webfont 12.0.0 → 12.1.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.
Files changed (57) hide show
  1. package/NOTICE.md +14 -2
  2. package/README.md +176 -15
  3. package/dist/browser.js +4 -0
  4. package/dist/cli.mjs +518 -253
  5. package/dist/index.js +1 -1
  6. package/dist/parseTemplateOption-5T7rSw5J.mjs +20 -0
  7. package/dist/parseTemplateOption-BmH_pcQh.js +1 -0
  8. package/dist/renderTemplates-DvRlS58E.mjs +93 -0
  9. package/dist/renderTemplates-zCYCzeOt.js +1 -0
  10. package/dist/src/browser.d.ts +2 -0
  11. package/dist/src/index.d.ts +2 -0
  12. package/dist/src/lib/applyOptimizeSvgToGlyphs.d.ts +3 -0
  13. package/dist/src/lib/evenoddFillRule.d.ts +2 -0
  14. package/dist/src/lib/inputSource.d.ts +1 -4
  15. package/dist/src/lib/inputSourceUtils.d.ts +4 -0
  16. package/dist/src/lib/largeFontLigatures.d.ts +4 -0
  17. package/dist/src/lib/optimizeSvgGlyphs.d.ts +4 -0
  18. package/dist/src/lib/parseFormats.d.ts +4 -0
  19. package/dist/src/lib/parseTemplateOption.d.ts +2 -0
  20. package/dist/src/lib/runtimeEnvironment.d.ts +4 -0
  21. package/dist/src/lib/svgDiagnostics/diagnoseSvgContents.d.ts +12 -0
  22. package/dist/src/lib/svgFontOutput/emptyGlyphPaths.d.ts +3 -0
  23. package/dist/src/lib/svgTools/applySvgDiagnostics.d.ts +13 -0
  24. package/dist/src/lib/svgTools/applySvgTools.d.ts +14 -0
  25. package/dist/src/lib/svgTools/normalizeSvgToolsOptions.d.ts +2 -0
  26. package/dist/src/lib/svgicons2svgfont/index.d.ts +5 -0
  27. package/dist/src/lib/svgicons2svgfont/metadataFromSrcPath.d.ts +11 -0
  28. package/dist/src/lib/templateUnicodeRange.d.ts +4 -0
  29. package/dist/src/lib/ttfEncode.d.ts +5 -0
  30. package/dist/src/standalone/convertTtfInput.d.ts +3 -0
  31. package/dist/src/standalone/defaultOptions.d.ts +3 -0
  32. package/dist/src/standalone/generateSvgFont.d.ts +2 -0
  33. package/dist/src/standalone/getGlyphsDataFromInputs.d.ts +3 -0
  34. package/dist/src/standalone/glyphsData.d.ts +1 -1
  35. package/dist/src/standalone/index.d.ts +5 -0
  36. package/dist/src/standalone/inputMode.d.ts +3 -1
  37. package/dist/src/standalone/optionsFromGlyphs.d.ts +3 -0
  38. package/dist/src/standalone/renderTemplates.d.ts +10 -0
  39. package/dist/src/standalone/runSvgPipeline.d.ts +3 -0
  40. package/dist/src/standalone/validateWebfontOptions.d.ts +6 -0
  41. package/dist/src/standalone/webfontFromGlyphs.d.ts +3 -0
  42. package/dist/src/types/GlyphContentTransformFn.d.ts +2 -0
  43. package/dist/src/types/GlyphInput.d.ts +6 -0
  44. package/dist/src/types/InitialOptions.d.ts +2 -0
  45. package/dist/src/types/OptionsBase.d.ts +9 -1
  46. package/dist/src/types/RenderedTemplate.d.ts +7 -0
  47. package/dist/src/types/Result.d.ts +8 -0
  48. package/dist/src/types/SvgToolsOptions.d.ts +13 -0
  49. package/dist/src/types/TranscodedFont.d.ts +7 -0
  50. package/dist/src/types/WebfontFromGlyphsOptions.d.ts +11 -0
  51. package/dist/src/types/WebfontOptions.d.ts +12 -2
  52. package/dist/src/types/index.d.ts +2 -1
  53. package/package.json +16 -3
  54. package/templates/template.css.njk +6 -3
  55. package/templates/template.html.njk +15 -4
  56. package/templates/template.scss.njk +6 -3
  57. package/templates/template.styl.njk +6 -3
package/dist/cli.mjs CHANGED
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { fileURLToPath as e } from "node:url";
3
- const t = e(import.meta.url), n = e(new URL(".", import.meta.url));
3
+ const t = e(import.meta.url);
4
+ e(new URL(".", import.meta.url));
5
+ import { t as n } from "./parseTemplateOption-5T7rSw5J.mjs";
4
6
  import { pathToFileURL as r } from "node:url";
5
7
  import i from "meow";
6
8
  import * as a from "fs";
@@ -10,32 +12,32 @@ import c from "path";
10
12
  import l from "resolve-from";
11
13
  import { globby as u } from "globby";
12
14
  import { cosmiconfig as d } from "cosmiconfig";
13
- import ee from "crypto";
14
15
  import f from "deepmerge";
15
- import p from "nunjucks";
16
- import { Readable as m } from "stream";
17
- import h from "ttf2woff";
18
- import g from "wawoff2";
19
- import { SVGIcons2SVGFontStream as te, fileSorter as _, getMetadataService as v } from "svgicons2svgfont";
20
- import y from "ttf2eot";
21
- import b from "fontverter";
22
- import * as ne from "fs/promises";
23
- import re from "xml2js";
24
- import ie from "p-limit";
25
- import ae from "svg2ttf";
16
+ import * as p from "fs/promises";
17
+ import ee from "ttf2woff";
18
+ import te from "wawoff2";
19
+ import ne from "ttf2eot";
20
+ import re from "fontverter";
21
+ import m from "xml2js";
22
+ import h from "p-limit";
23
+ import { SVGIcons2SVGFontStream as g, fileSorter as _, getMetadataService as ie } from "svgicons2svgfont";
24
+ import ae from "crypto";
25
+ import { optimize as oe } from "svgo";
26
+ import { Readable as se } from "stream";
27
+ import ce from "svg2ttf";
26
28
  //#region \0rolldown/runtime.js
27
- var oe = Object.create, x = Object.defineProperty, se = Object.getOwnPropertyDescriptor, ce = Object.getOwnPropertyNames, le = Object.getPrototypeOf, ue = Object.prototype.hasOwnProperty, S = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t.exports), C = (e, t, n, r) => {
28
- if (t && typeof t == "object" || typeof t == "function") for (var i = ce(t), a = 0, o = i.length, s; a < o; a++) s = i[a], !ue.call(e, s) && s !== n && x(e, s, {
29
+ var le = Object.create, v = Object.defineProperty, ue = Object.getOwnPropertyDescriptor, de = Object.getOwnPropertyNames, fe = Object.getPrototypeOf, pe = Object.prototype.hasOwnProperty, y = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t.exports), me = (e, t, n, r) => {
30
+ if (t && typeof t == "object" || typeof t == "function") for (var i = de(t), a = 0, o = i.length, s; a < o; a++) s = i[a], !pe.call(e, s) && s !== n && v(e, s, {
29
31
  get: ((e) => t[e]).bind(null, s),
30
- enumerable: !(r = se(t, s)) || r.enumerable
32
+ enumerable: !(r = ue(t, s)) || r.enumerable
31
33
  });
32
34
  return e;
33
- }, w = (e, t, n) => (n = e == null ? {} : oe(le(e)), C(t || !e || !e.__esModule ? x(n, "default", {
35
+ }, b = (e, t, n) => (n = e == null ? {} : le(fe(e)), me(t || !e || !e.__esModule ? v(n, "default", {
34
36
  value: e,
35
37
  enumerable: !0
36
- }) : n, e)), T = {
38
+ }) : n, e)), he = {
37
39
  name: "webfont",
38
- version: "12.0.0",
40
+ version: "12.1.0",
39
41
  description: "Generator of fonts from SVG icons; decompress WOFF/WOFF2 to embedded TTF/OTF (not TTF↔OTF transcoding)",
40
42
  directories: {
41
43
  lib: "dist",
@@ -51,12 +53,23 @@ var oe = Object.create, x = Object.defineProperty, se = Object.getOwnPropertyDes
51
53
  "NOTICE.md"
52
54
  ],
53
55
  main: "dist/index.js",
56
+ browser: "dist/browser.js",
54
57
  bin: "dist/cli.mjs",
55
58
  source: "src/index.ts",
56
59
  types: "dist/src/index.d.ts",
57
60
  typings: "dist/src/index.d.ts",
61
+ exports: {
62
+ ".": {
63
+ node: {
64
+ import: "./dist/index.js",
65
+ require: "./dist/index.js"
66
+ },
67
+ default: "./dist/browser.js"
68
+ },
69
+ "./package.json": "./package.json"
70
+ },
58
71
  scripts: {
59
- build: "vite build --mode library && vite build --mode cli",
72
+ build: "vite build --mode library && vite build --mode browser && vite build --mode cli",
60
73
  clean: "rm -rf dist/ temp/",
61
74
  demo: "node dist/cli.mjs './src/fixtures/svg-icons/*.svg' -d demo -t html --normalize --center-horizontally",
62
75
  lint: "biome check .",
@@ -70,7 +83,8 @@ var oe = Object.create, x = Object.defineProperty, se = Object.getOwnPropertyDes
70
83
  test: "vitest run src",
71
84
  testc: "vitest run src --coverage",
72
85
  "test-debug": "vitest run src --no-file-parallelism",
73
- testu: "vitest run src -u"
86
+ testu: "vitest run src -u",
87
+ "deprecate-pre-12": "npm deprecate 'webfont@>=10.0.0 <12.0.0' 'Deprecated: upgrade to webfont@12. v10–11 enabled ligatures by default (browser hangs on large fonts, #558). 12.x: ligatures off, Node 12+, named import, unicode-range off, template fixes. See MIGRATION.md'"
74
88
  },
75
89
  dependencies: {
76
90
  cosmiconfig: "9.0.2",
@@ -83,6 +97,7 @@ var oe = Object.create, x = Object.defineProperty, se = Object.getOwnPropertyDes
83
97
  "resolve-from": "^5.0.0",
84
98
  svg2ttf: "^6.1.0",
85
99
  svgicons2svgfont: "^16.0.0",
100
+ svgo: "4.0.1",
86
101
  ttf2eot: "3.1.0",
87
102
  ttf2woff: "^3.0.0",
88
103
  wawoff2: "2.0.0",
@@ -159,7 +174,7 @@ var oe = Object.create, x = Object.defineProperty, se = Object.getOwnPropertyDes
159
174
  "builder",
160
175
  "generator"
161
176
  ]
162
- }, E = "\n Usage: webfont [input] [options]\n\n Input: File(s) or glob(s).\n\n SVG icons: one or more `.svg` files (default pipeline).\n Webfont decompression: one or more `.woff` / `.woff2` paths, globs, or http(s) URLs.\n You must have rights to any font file you process (see NOTICE.md).\n\n If an input argument is wrapped in quotation marks, it will be passed to \"fast-glob\"\n for cross-platform glob support.\n\n Options:\n\n --config\n\n Path to a specific configuration file (JSON, YAML, or CommonJS)\n or the name of a module in `node_modules` that points to one.\n If no `--config` argument is provided, webfont will search for\n configuration files in the following places, in this order:\n - a `webfont` property in `package.json`\n - a `.webfontrc` file (with or without filename extension:\n `.json`, `.yaml`, and `.js` are available)\n - a `webfont.config.js` file exporting a JS object\n The search will begin in the working directory and move up the\n directory tree until a configuration file is found.\n\n -u, --fontName\n\n The font family name you want, default: \"webfont\".\n\n -h, --help\n\n Output usage information.\n\n -v, --version\n\n Output the version number.\n\n -f, --formats\n\n Font formats to generate. Pass a JSON array (e.g. '[\"woff2\"]') or a\n comma-separated list (e.g. woff2 or svg, ttf, woff2).\n SVG input: svg, ttf, eot, woff, woff2 (not otf).\n WOFF/WOFF2 input: ttf and/or otf matching the embedded SFNT flavor.\n\n -d, --dest\n\n Destination for generated fonts.\n\n -m, --dest-create\n\n Create destination directory if it does not exist.\n\n -t, --template\n\n Type of template ('css', 'scss', 'styl') or path to custom template.\n\n -s, --destTemplate\n\n Destination for generated template. If not passed used `dest` argument value.\n\n -c, --templateClassName\n\n Class name in css template.\n\n -p, --templateFontPath\n\n Font path in css template.\n\n -n, --templateFontName\n\n Font name in css template.\n\n --templateCacheString\n\n Specify cache string in scss/css template.\n\n --no-sort\n\n Keeps the files in the same order of entry\n\n --no-ligatures\n\n Prevents adding ligature unicode\n\n --verbose\n\n Tell me everything!.\n\n For \"svgicons2svgfont\":\n\n --fontId\n\n The font id you want, default as \"--fontName\".\n\n --fontStyle\n\n The font style you want.\n\n --fontWeight\n\n The font weight you want.\n\n --fixedWidth\n\n Creates a monospace font of the width of the largest input icon.\n\n --centerHorizontally\n\n Calculate the bounds of a glyph and center it horizontally.\n\n --normalize\n\n Normalize icons by scaling them to the height of the highest icon.\n\n --fontHeight\n\n The outputted font height [MAX(icons.height)].\n\n --round\n\n Setup the SVG path rounding [10e12].\n\n --descent\n\n The font descent [0].\n\n --ascent\n\n The font ascent [height - descent].\n\n --startUnicode\n\n The start unicode codepoint for files without prefix [0xEA01].\n\n --prependUnicode\n\n Prefix files with their automatically allocated unicode codepoint.\n\n --metadata\n\n Content of the metadata tag.\n\n --addHashInFontUrl\n\n Generated font url will be : [webfont].[ext]?v=[hash]\n", D = {
177
+ }, ge = "\n Usage: webfont [input] [options]\n\n Input: File(s) or glob(s).\n\n SVG icons: one or more `.svg` files (default pipeline).\n Webfont decompression: one or more `.woff` / `.woff2` paths, globs, or http(s) URLs.\n You must have rights to any font file you process (see NOTICE.md).\n\n If an input argument is wrapped in quotation marks, it will be passed to \"fast-glob\"\n for cross-platform glob support.\n\n Options:\n\n --config\n\n Path to a specific configuration file (JSON, YAML, or CommonJS)\n or the name of a module in `node_modules` that points to one.\n If no `--config` argument is provided, webfont will search for\n configuration files in the following places, in this order:\n - a `webfont` property in `package.json`\n - a `.webfontrc` file (with or without filename extension:\n `.json`, `.yaml`, and `.js` are available)\n - a `webfont.config.js` file exporting a JS object\n The search will begin in the working directory and move up the\n directory tree until a configuration file is found.\n\n -u, --fontName\n\n The font family name you want, default: \"webfont\".\n\n -h, --help\n\n Output usage information.\n\n -v, --version\n\n Output the version number.\n\n -f, --formats\n\n Font formats to generate. Pass a JSON array (e.g. '[\"woff2\"]') or a\n comma-separated list (e.g. woff2 or svg, ttf, woff2).\n SVG input: svg, ttf, eot, woff, woff2 (not otf).\n WOFF/WOFF2 input: ttf and/or otf matching the embedded SFNT flavor.\n\n -d, --dest\n\n Destination for generated fonts.\n\n -m, --dest-create\n\n Create destination directory if it does not exist.\n\n -t, --template\n\n Built-in template name(s) ('css', 'scss', 'styl', 'html', 'json') or path to a custom template.\n Pass a JSON array (e.g. '[\"html\",\"scss\"]') or comma-separated list for multiple outputs.\n\n -s, --destTemplate\n\n Destination for generated template. If not passed used `dest` argument value.\n\n -c, --templateClassName\n\n Class name in css template.\n\n -p, --templateFontPath\n\n Font path in css template.\n\n -n, --templateFontName\n\n Font name in css template.\n\n --templateCacheString\n\n Specify cache string in scss/css template.\n\n --no-sort\n\n Keeps the files in the same order of entry\n\n --ligatures\n\n Add OpenType ligature glyphs (icon names as text). Off by default — large\n icon sets can hang Firefox on Windows (#558). Prefer class + codepoint CSS.\n\n --unicode-range\n\n Emit unicode-range in built-in @font-face rules (computed from glyph code points).\n Off by default — enabling may prevent ligature names from rendering; see README.\n\n --no-template-font-ligatures\n\n Omit font-feature-settings: \"liga\" from the built-in HTML preview template\n\n --optimize-svg\n\n Run a conservative SVGO pass on each SVG before font generation\n (does not convert strokes to fills; use glyphContentTransformFn for that)\n\n --verbose\n\n Tell me everything!.\n\n --svg-diagnose\n\n (Alpha) Scan SVG icons for icon-font incompatibilities (stroke-only paths,\n fill-rule: evenodd, unsupported elements) and log warnings.\n\n For \"svgicons2svgfont\":\n\n --fontId\n\n The font id you want, default as \"--fontName\".\n\n --fontStyle\n\n The font style you want.\n\n --fontWeight\n\n The font weight you want.\n\n --fixedWidth\n\n Creates a monospace font of the width of the largest input icon.\n\n --centerHorizontally\n\n Calculate the bounds of a glyph and center it horizontally.\n\n --normalize\n\n Normalize icons by scaling them to the height of the highest icon.\n\n --fontHeight\n\n The outputted font height [MAX(icons.height)].\n\n --round\n\n Setup the SVG path rounding [10e12].\n\n --descent\n\n The font descent [0].\n\n --ascent\n\n The font ascent [height - descent].\n\n --startUnicode\n\n The start unicode codepoint for files without prefix [0xEA01].\n\n --prependUnicode\n\n Prefix files with their automatically allocated unicode codepoint.\n\n --metadata\n\n Content of the metadata tag.\n\n --addHashInFontUrl\n\n Append an MD5 content hash to font URLs in built-in templates\n (?v=[hash]) while keeping output filenames stable (fontName.woff2, etc.).\n Use with a fixed fontName — do not randomize fontName for cache busting.\n", _e = {
163
178
  ascent: { type: "string" },
164
179
  centerHorizontally: { type: "boolean" },
165
180
  config: { type: "string" },
@@ -196,7 +211,7 @@ var oe = Object.create, x = Object.defineProperty, se = Object.getOwnPropertyDes
196
211
  type: "boolean"
197
212
  },
198
213
  ligatures: {
199
- default: !0,
214
+ default: !1,
200
215
  type: "boolean"
201
216
  },
202
217
  metadata: { type: "string" },
@@ -224,6 +239,10 @@ var oe = Object.create, x = Object.defineProperty, se = Object.getOwnPropertyDes
224
239
  default: !1,
225
240
  type: "boolean"
226
241
  },
242
+ optimizeSvg: {
243
+ default: !1,
244
+ type: "boolean"
245
+ },
227
246
  templateFontPath: {
228
247
  shortFlag: "p",
229
248
  type: "string"
@@ -232,88 +251,155 @@ var oe = Object.create, x = Object.defineProperty, se = Object.getOwnPropertyDes
232
251
  default: "",
233
252
  type: "string"
234
253
  },
254
+ unicodeRange: {
255
+ default: !1,
256
+ type: "boolean"
257
+ },
258
+ templateFontLigatures: {
259
+ default: !0,
260
+ type: "boolean"
261
+ },
235
262
  verbose: {
236
263
  default: !1,
237
264
  type: "boolean"
238
265
  },
266
+ svgDiagnose: {
267
+ default: !1,
268
+ type: "boolean"
269
+ },
239
270
  version: {
240
271
  shortFlag: "v",
241
272
  type: "boolean"
242
273
  }
243
- }, O = { url: r(t).href }, k = ((e = process.argv.slice(2)) => i(E, {
274
+ }, ve = { url: r(t).href }, ye = ((e = process.argv.slice(2)) => i(ge, {
244
275
  argv: [...e],
245
276
  autoHelp: !1,
246
277
  autoVersion: !1,
247
- flags: D,
248
- importMeta: O,
249
- pkg: T
250
- }))(), A = /^https?:\/\//iu, j = (e) => A.test(e), M = (e) => {
251
- if (j(e)) try {
278
+ flags: _e,
279
+ importMeta: ve,
280
+ pkg: he
281
+ }))(), be = /^https?:\/\//iu, x = (e) => be.test(e), S = (e) => {
282
+ if (x(e)) try {
252
283
  return c.extname(new URL(e).pathname).toLowerCase();
253
284
  } catch {
254
285
  return "";
255
286
  }
256
287
  return c.extname(e).toLowerCase();
257
- }, N = async (e) => (await Promise.all(e.map((e) => j(e) ? Promise.resolve([e]) : u(e)))).flat(), P = (e) => {
288
+ }, C = (e) => {
258
289
  let t = e;
259
- j(e) && (t = new URL(e).pathname);
260
- let n = c.basename(t), r = M(e);
290
+ x(e) && (t = new URL(e).pathname);
291
+ let n = c.basename(t), r = S(e);
261
292
  return r === ".woff2" ? n.slice(0, -6) : r === ".woff" ? n.slice(0, -5) : n.replace(/\.[^.]+$/u, "");
262
- }, F = {
293
+ }, w = {
263
294
  ".woff": "-woff",
264
295
  ".woff2": "-woff2"
265
- }, I = (e) => {
266
- let t = e.map((e) => P(e)), n = /* @__PURE__ */ new Map();
296
+ }, T = (e) => {
297
+ let t = e.map((e) => C(e)), n = /* @__PURE__ */ new Map();
267
298
  for (let e of t) n.set(e, (n.get(e) ?? 0) + 1);
268
299
  return e.map((e, r) => {
269
- let i = t[r], a = (n.get(i) ?? 0) > 1, o = M(e);
270
- return a ? `${i}${F[o] ?? `-${r + 1}`}` : i;
300
+ let i = t[r], a = (n.get(i) ?? 0) > 1, o = S(e);
301
+ return a ? `${i}${w[o] ?? `-${r + 1}`}` : i;
271
302
  });
272
- }, L = () => c.resolve(n, "../templates"), R = (e) => `${L()}/template.${e}.njk`, z = () => {
273
- let e = L();
274
- return {
275
- css: { path: c.join(e, "template.css.njk") },
276
- html: { path: c.join(e, "template.html.njk") },
277
- json: { path: c.join(e, "template.json.njk") },
278
- scss: { path: c.join(e, "template.scss.njk") },
279
- styl: { path: c.join(e, "template.styl.njk") }
280
- };
281
- }, B = (e) => ({
282
- prependUnicode: !!e.prependUnicode,
283
- startUnicode: Number(e.startUnicode)
284
- }), V = (e) => ({
285
- ascent: e.ascent,
286
- centerHorizontally: e.centerHorizontally,
287
- descent: e.descent,
288
- fixedWidth: e.fixedWidth,
289
- fontHeight: e.fontHeight,
290
- fontId: e.fontId,
291
- fontName: e.fontName,
292
- fontStyle: e.fontStyle,
293
- fontWeight: e.fontWeight,
294
- metadata: e.metadata,
295
- normalize: e.normalize,
296
- round: e.round
297
- }), H = (e) => Buffer.from(y(e)), U = 1330926671, de = 1953658213, fe = 65536, pe = (e) => {
303
+ }, E = async (e) => (await Promise.all(e.map((e) => x(e) ? Promise.resolve([e]) : u(e)))).flat(), D = 1330926671, O = 1953658213, k = 65536, A = (e) => {
298
304
  if (e.length < 4) throw Error("SFNT buffer is too short to read flavor");
299
305
  let t = e.readUInt32BE(0);
300
- if (t === U) return "otf";
301
- if (t === de || t === fe) return "ttf";
306
+ if (t === D) return "otf";
307
+ if (t === O || t === k) return "ttf";
302
308
  throw Error(`Unsupported SFNT flavor 0x${t.toString(16)}`);
303
- }, me = /* @__PURE__ */ S(((e, t) => {
309
+ }, j = (e) => Buffer.from(ne(e)), M = (e) => j(e), N = (e, t = {}) => Buffer.from(ee(e, t).buffer), P = async (e) => Buffer.from(await te.compress(e)), F = /* @__PURE__ */ new Set([".woff", ".woff2"]), I = ".svg", L = ".ttf", R = [
310
+ "svg",
311
+ "ttf",
312
+ "eot",
313
+ "woff",
314
+ "woff2"
315
+ ], z = (e) => e === I, B = (e) => e === L, V = (e) => F.has(e), xe = (e) => z(e) || V(e) || B(e), Se = (e) => {
316
+ if (e.length === 0) return "empty";
317
+ let t = e.map((e) => S(e));
318
+ if (!t.every(xe)) return "empty";
319
+ let n = t.some(z), r = t.some(V), i = t.some(B);
320
+ return [
321
+ n,
322
+ r,
323
+ i
324
+ ].filter(Boolean).length > 1 ? "mixed" : r ? "webfont" : i ? "ttf" : n ? "svg" : "empty";
325
+ }, Ce = (e) => {
326
+ if (e.includes("otf")) throw Error("OTF output is only supported when converting WOFF/WOFF2 input. Request \"ttf\" for SVG icons, or pass a .woff/.woff2 file.");
327
+ }, H = (e, t) => t === "svg" ? e.filter((e) => S(e) === I) : t === "webfont" ? e.filter((e) => F.has(S(e))) : t === "ttf" ? e.filter((e) => S(e) === L) : [], we = /* @__PURE__ */ new Set([
328
+ "ttf",
329
+ "eot",
330
+ "woff",
331
+ "woff2"
332
+ ]), Te = (e) => {
333
+ let t = e.filter((e) => we.has(e));
334
+ if (e.length === R.length && R.every((t) => e.includes(t))) return ["woff", "woff2"];
335
+ if (t.length === 0) throw Error("formats must include at least one of \"ttf\", \"eot\", \"woff\", or \"woff2\" when converting TTF input");
336
+ return [...new Set(t)];
337
+ }, Ee = (e) => {
338
+ let t = e.filter((e) => e === "ttf" || e === "otf");
339
+ if (e.length === R.length && R.every((t) => e.includes(t))) return ["ttf"];
340
+ if (t.length === 0) throw Error("formats must include \"ttf\" and/or \"otf\" when converting WOFF/WOFF2 input");
341
+ return [...new Set(t)];
342
+ }, De = (e) => {
343
+ if (e.length === 0) throw Error("No TTF files matched");
344
+ }, Oe = (e) => {
345
+ if (e.template) throw Error("Templates are not supported when converting TTF input");
346
+ if (e.glyphTransformFn) throw Error("glyphTransformFn is not supported when converting TTF input");
347
+ if (e.glyphContentTransformFn) throw Error("glyphContentTransformFn is not supported when converting TTF input");
348
+ }, ke = (e, t) => {
349
+ let n;
350
+ try {
351
+ n = A(e);
352
+ } catch {
353
+ throw Error(`Input is not a valid TrueType font: ${t}`);
354
+ }
355
+ if (n !== "ttf") throw Error(`OpenType (OTF) input is not supported for webfont encoding. Use a .ttf file for ${t}.`);
356
+ }, Ae = async (e, t, n, r) => {
357
+ if (n === "ttf") {
358
+ e.ttf = t;
359
+ return;
360
+ }
361
+ if (n === "eot") {
362
+ e.eot = M(t);
363
+ return;
364
+ }
365
+ if (n === "woff") {
366
+ let n;
367
+ typeof r.metadata == "string" && (n = r.metadata), e.woff = N(t, { metadata: n });
368
+ return;
369
+ }
370
+ e.woff2 = await P(t);
371
+ }, je = async (e, t, n, r) => {
372
+ if (x(e)) throw Error(`Remote TTF URLs are not supported. Download the file first: ${e}`);
373
+ r && console.log(`Encoding ${e}...`);
374
+ let i = await p.readFile(e);
375
+ ke(i, e);
376
+ let a = { source: e };
377
+ return await Promise.all(t.map((e) => Ae(a, i, e, n))), a;
378
+ }, Me = async (e, t) => {
379
+ Oe(t), De(e);
380
+ let n = Te(t.formats), r = await Promise.all(e.map((e) => je(e, n, t, t.verbose))), i = {
381
+ config: { ...t },
382
+ transcodedFonts: r
383
+ };
384
+ if (r.length === 1) {
385
+ let [e] = r;
386
+ i.ttf = e.ttf, i.eot = e.eot, i.woff = e.woff, i.woff2 = e.woff2;
387
+ }
388
+ return i;
389
+ }, Ne = /* @__PURE__ */ y(((e, t) => {
304
390
  t.exports = function(e) {
305
391
  return !e || e.length < 8 ? !1 : e[0] === 119 && e[1] === 79 && e[2] === 70 && e[3] === 70 && e[4] === 0 && e[5] === 1 && e[6] === 0 && e[7] === 0 || e[4] === 79 && e[5] === 84 && e[6] === 84 && e[7] === 79;
306
392
  };
307
- })), he = /* @__PURE__ */ S(((e, t) => {
393
+ })), Pe = /* @__PURE__ */ y(((e, t) => {
308
394
  t.exports = function(e) {
309
395
  return !e || e.length < 8 ? !1 : e[0] === 119 && e[1] === 79 && e[2] === 70 && e[3] === 50 && e[4] === 0 && e[5] === 1 && e[6] === 0 && e[7] === 0;
310
396
  };
311
- })), ge = /* @__PURE__ */ w(me()), _e = /* @__PURE__ */ w(he()), ve = (e, t) => {
312
- let n = M(t);
313
- if (n === ".woff2" && !(0, _e.default)(e)) throw Error(`URL did not return a valid WOFF2 font: ${t}`);
314
- if (n === ".woff" && !(0, ge.default)(e)) throw Error(`URL did not return a valid WOFF font: ${t}`);
397
+ })), Fe = /* @__PURE__ */ b(Ne()), Ie = /* @__PURE__ */ b(Pe()), Le = (e, t) => {
398
+ let n = S(t);
399
+ if (n === ".woff2" && !(0, Ie.default)(e)) throw Error(`URL did not return a valid WOFF2 font: ${t}`);
400
+ if (n === ".woff" && !(0, Fe.default)(e)) throw Error(`URL did not return a valid WOFF font: ${t}`);
315
401
  if (e.length === 0) throw Error(`URL returned an empty response: ${t}`);
316
- }, ye = async (e) => {
402
+ }, Re = async (e) => {
317
403
  let t;
318
404
  try {
319
405
  t = await fetch(e);
@@ -323,32 +409,14 @@ var oe = Object.create, x = Object.defineProperty, se = Object.getOwnPropertyDes
323
409
  }
324
410
  if (!t.ok) throw Error(`Failed to fetch font URL ${e}: HTTP ${t.status} ${t.statusText}`);
325
411
  let n = await t.arrayBuffer(), r = Buffer.from(n);
326
- return ve(r, e), r;
327
- }, W = /* @__PURE__ */ new Set([".woff", ".woff2"]), G = ".svg", K = [
328
- "svg",
329
- "ttf",
330
- "eot",
331
- "woff",
332
- "woff2"
333
- ], q = (e) => e === G, J = (e) => W.has(e), be = (e) => q(e) || J(e), xe = (e) => {
334
- if (e.length === 0) return "empty";
335
- let t = e.map((e) => M(e));
336
- if (!t.every(be)) return "empty";
337
- let n = t.some(q), r = t.some(J);
338
- return n && r ? "mixed" : r ? "webfont" : n ? "svg" : "empty";
339
- }, Se = (e) => {
340
- if (e.includes("otf")) throw Error("OTF output is only supported when converting WOFF/WOFF2 input. Request \"ttf\" for SVG icons, or pass a .woff/.woff2 file.");
341
- }, Y = (e, t) => t === "svg" ? e.filter((e) => M(e) === G) : t === "webfont" ? e.filter((e) => W.has(M(e))) : [], Ce = (e) => {
342
- let t = e.filter((e) => e === "ttf" || e === "otf");
343
- if (e.length === K.length && K.every((t) => e.includes(t))) return ["ttf"];
344
- if (t.length === 0) throw Error("formats must include \"ttf\" and/or \"otf\" when converting WOFF/WOFF2 input");
345
- return [...new Set(t)];
346
- }, we = (e) => {
412
+ return Le(r, e), r;
413
+ }, ze = (e) => {
347
414
  if (e.length === 0) throw Error("No WOFF or WOFF2 files matched");
348
- }, Te = (e) => {
415
+ }, Be = (e) => {
349
416
  if (e.template) throw Error("Templates are not supported when converting WOFF/WOFF2 input");
350
417
  if (e.glyphTransformFn) throw Error("glyphTransformFn is not supported when converting WOFF/WOFF2 input");
351
- }, Ee = (e) => {
418
+ if (e.glyphContentTransformFn) throw Error("glyphContentTransformFn is not supported when converting WOFF/WOFF2 input");
419
+ }, Ve = (e) => {
352
420
  let { decompressed: t, sfnt: n, format: r, flavor: i, source: a } = e;
353
421
  if (r === "ttf" && i !== "ttf") throw Error(`Input decompresses to OpenType (OTF). Request "otf" format instead of "ttf" for ${a}.`);
354
422
  if (r === "otf" && i !== "otf") throw Error(`Input decompresses to TrueType (TTF). Request "ttf" format instead of "otf" for ${a}.`);
@@ -357,10 +425,10 @@ var oe = Object.create, x = Object.defineProperty, se = Object.getOwnPropertyDes
357
425
  return;
358
426
  }
359
427
  t.otf = n;
360
- }, De = (e) => j(e) ? ye(e) : ne.readFile(e), Oe = async (e, t, n) => {
428
+ }, He = (e) => x(e) ? Re(e) : p.readFile(e), Ue = async (e, t, n) => {
361
429
  n && console.log(`Decompressing ${e}...`);
362
- let r = await De(e), i = Buffer.from(await b.convert(r, "sfnt")), a = pe(i), o = { source: e };
363
- for (let n of t) Ee({
430
+ let r = await He(e), i = Buffer.from(await re.convert(r, "sfnt")), a = A(i), o = { source: e };
431
+ for (let n of t) Ve({
364
432
  decompressed: o,
365
433
  sfnt: i,
366
434
  format: n,
@@ -368,18 +436,41 @@ var oe = Object.create, x = Object.defineProperty, se = Object.getOwnPropertyDes
368
436
  source: e
369
437
  });
370
438
  return o;
371
- }, ke = async (e, t) => {
372
- Te(t), we(e);
373
- let n = Ce(t.formats), r = await Promise.all(e.map((e) => Oe(e, n, t.verbose))), i = {
439
+ }, We = async (e, t) => {
440
+ Be(t), ze(e);
441
+ let n = Ee(t.formats), r = await Promise.all(e.map((e) => Ue(e, n, t.verbose))), i = {
374
442
  config: { ...t },
375
443
  decompressedFonts: r
376
444
  };
377
445
  return r.length === 1 && (i.ttf = r[0].ttf, i.otf = r[0].otf), i;
378
- }, Ae = ie, je = (e) => e === void 0 ? [] : Array.isArray(e) ? e : [e], Me = (e) => ({
446
+ }, Ge = h, Ke = (e) => ({
447
+ prependUnicode: !!e.prependUnicode,
448
+ startUnicode: Number(e.startUnicode)
449
+ }), qe = (e) => {
450
+ if (e == null) return;
451
+ if (typeof e == "number") return Number.isFinite(e) ? e : void 0;
452
+ let t = e.trim();
453
+ if (t.length === 0) return;
454
+ let n = Number(t);
455
+ if (Number.isFinite(n)) return n;
456
+ }, Je = (e) => ({
457
+ ascent: e.ascent,
458
+ centerHorizontally: e.centerHorizontally,
459
+ descent: e.descent,
460
+ fixedWidth: e.fixedWidth,
461
+ fontHeight: e.fontHeight,
462
+ fontId: e.fontId,
463
+ fontName: e.fontName,
464
+ fontStyle: e.fontStyle,
465
+ fontWeight: e.fontWeight,
466
+ metadata: e.metadata,
467
+ normalize: e.normalize,
468
+ round: qe(e.round)
469
+ }), Ye = (e) => e === void 0 ? [] : Array.isArray(e) ? e : [e], Xe = (e) => ({
379
470
  name: e.name,
380
- unicode: je(e.unicode)
381
- }), Ne = (e, t) => {
382
- let n = t.metadataProvider || v(B(t)), r = new re.Parser(), i = Ae(t.maxConcurrency);
471
+ unicode: Ye(e.unicode)
472
+ }), Ze = (e, t) => {
473
+ let n = t.metadataProvider || ie(Ke(t)), r = new m.Parser(), i = Ge(t.maxConcurrency);
383
474
  return Promise.all(e.map((e) => i(() => new Promise((t, n) => {
384
475
  let i = o(e), a = "";
385
476
  i.on("error", (e) => n(e)).on("data", (e) => {
@@ -396,97 +487,182 @@ var oe = Object.create, x = Object.defineProperty, se = Object.getOwnPropertyDes
396
487
  n(e.srcPath, (n, a) => {
397
488
  if (n) return r(n);
398
489
  if (!a) return r(/* @__PURE__ */ Error(`Missing metadata for ${e.srcPath}`));
399
- let o = Me(a);
490
+ let o = Xe(a);
400
491
  return i && o.unicode.push(a.name.replace(/-/gu, "_")), e.metadata = o, t(e);
401
492
  });
402
493
  })));
403
494
  });
404
- }, Pe = (e) => {
495
+ }, Qe = () => ({
496
+ centerHorizontally: !1,
497
+ descent: 0,
498
+ fixedWidth: !1,
499
+ fontHeight: void 0,
500
+ fontId: void 0,
501
+ fontName: "webfont",
502
+ fontStyle: "",
503
+ fontWeight: "",
504
+ formats: [
505
+ "svg",
506
+ "ttf",
507
+ "eot",
508
+ "woff",
509
+ "woff2"
510
+ ],
511
+ formatsOptions: { ttf: {
512
+ copyright: null,
513
+ ts: null,
514
+ version: null
515
+ } },
516
+ ligatures: !1,
517
+ maxConcurrency: 100,
518
+ metadata: void 0,
519
+ normalize: !1,
520
+ prependUnicode: !1,
521
+ round: 0x9184e72a000,
522
+ sort: !0,
523
+ startUnicode: 59905,
524
+ templateFontPath: "./",
525
+ unicodeRange: !1,
526
+ verbose: !1
527
+ }), $e = (e) => {
405
528
  if (!e?.files) throw Error("You must pass webfont a `files` glob");
406
529
  return {
407
- centerHorizontally: !1,
408
- descent: 0,
409
- fixedWidth: !1,
410
- fontHeight: void 0,
411
- fontId: void 0,
412
- fontName: "webfont",
413
- fontStyle: "",
414
- fontWeight: "",
415
- formats: [
416
- "svg",
417
- "ttf",
418
- "eot",
419
- "woff",
420
- "woff2"
421
- ],
422
- formatsOptions: { ttf: {
423
- copyright: null,
424
- ts: null,
425
- version: null
426
- } },
427
- ligatures: !0,
428
- maxConcurrency: 100,
429
- metadata: void 0,
430
- normalize: !1,
431
- prependUnicode: !1,
432
- round: 0x9184e72a000,
433
- sort: !0,
434
- startUnicode: 59905,
435
- templateFontPath: "./",
436
- verbose: !1,
530
+ ...Qe(),
437
531
  ...e
438
532
  };
439
- }, Fe = (e, t) => {
440
- if (e === "woff2") {
441
- if (!t.woff2) throw Error("Missing woff2 buffer for template rendering");
442
- return Buffer.from(t.woff2).toString("base64");
533
+ }, et = () => ({
534
+ multipass: !1,
535
+ plugins: [
536
+ "removeDoctype",
537
+ "removeXMLProcInst",
538
+ "removeComments",
539
+ "removeMetadata",
540
+ "removeEditorsNSData",
541
+ "removeDesc",
542
+ "cleanupAttrs",
543
+ "removeUnusedNS"
544
+ ]
545
+ }), tt = (e) => {
546
+ let t = et();
547
+ return e ? {
548
+ ...t,
549
+ ...e,
550
+ plugins: e.plugins ?? t.plugins
551
+ } : t;
552
+ }, nt = (e, t, n) => oe(e, {
553
+ ...tt(n),
554
+ path: t
555
+ }).data, rt = (e, t) => e.map((e) => ({
556
+ ...e,
557
+ contents: nt(e.contents, e.srcPath, t)
558
+ })), it = (e, t) => t && e > 2e3, at = (e) => `Warning: ${e} glyphs with ligatures enabled may cause severe browser slowdown or hangs (especially Firefox on Windows). Ligatures are off by default; enable only if needed: --ligatures or ligatures: true. See TROUBLESHOOTING.md and https://github.com/itgalaxy/webfont/issues/558`, ot = /<glyph\b([^>/]*)(?:\/>|>)/giu, st = /\bglyph-name=["']([^"']+)["']/iu, ct = /\bd=["']([^"']*)["']/iu, lt = (e) => {
559
+ let t = [];
560
+ for (let n of e.matchAll(ot)) {
561
+ let e = n[1] ?? "", r = st.exec(e);
562
+ r && (ct.exec(e)?.[1] ?? "").trim().length === 0 && t.push(r[1]);
443
563
  }
444
- let n = t[e];
445
- if (!n) throw Error(`Missing ${e} buffer for template rendering`);
446
- return n.toString("base64");
447
- }, Ie = (e, t = {}) => Buffer.from(ae(e, t).buffer), Le = (e) => "filepath" in e, Re = async (e) => {
448
- let t = d("webfont", { searchStrategy: "global" });
449
- if (e.configFile) {
450
- let n = c.resolve(process.cwd(), e.configFile);
451
- return await t.load(n) ?? {};
564
+ return t;
565
+ }, ut = (e, t) => {
566
+ for (let n of t) {
567
+ let t = n.metadata?.name;
568
+ if (t && (e === t || e.startsWith(`${t}-`))) return n.srcPath;
452
569
  }
453
- return await t.search(process.cwd()) ?? {};
454
- }, ze = (e, t) => {
570
+ }, dt = (e, t) => {
571
+ let n = /* @__PURE__ */ new Set(), r = [];
572
+ for (let i of e) {
573
+ let e = ut(i, t), a = e ?? i;
574
+ n.has(a) || (n.add(a), e ? r.push(`${i} (${e})`) : r.push(i));
575
+ }
576
+ return r.join("; ");
577
+ }, ft = (e, t) => {
578
+ let n = lt(e);
579
+ if (n.length === 0) return;
580
+ let r = dt(n, t);
581
+ throw Error(`Empty glyph path(s) in SVG font output for: ${r}. Stroke-only SVGs (fill="none" with stroke) often produce empty glyphs because svgicons2svgfont does not convert strokes. Convert strokes to filled paths in your design tool, preprocess with glyphContentTransformFn (for example svg-outline-stroke), or run with --svg-diagnose for compatibility warnings. See TROUBLESHOOTING.md ("Stroke-only SVGs produce blank icons").`);
582
+ }, pt = /fill-rule\s*:\s*evenodd|fill-rule\s*=\s*["']evenodd["']/iu, mt = (e) => pt.test(e), ht = /\bstroke\s*=|\bstroke\s*:/iu, gt = /fill\s*=\s*["']none["']|fill\s*:\s*none/iu, _t = /<(line|polyline|clipPath)\b/iu, vt = (e) => ht.test(e) ? gt.test(e) : !1, yt = (e) => _t.test(e), U = (e, t) => {
583
+ switch (e) {
584
+ case "evenodd-fill-rule": return `[webfont:diagnose] ${t} uses fill-rule: evenodd. Icon fonts render glyphs with the nonzero fill rule, so holes and counter-shapes can disappear. See TROUBLESHOOTING.md ("Icon details missing after export").`;
585
+ case "stroke-only": return `[webfont:diagnose] ${t} uses stroke-based paths (fill="none"). svgicons2svgfont ignores stroke; outlines may render as solid shapes or lose detail. Preprocess with glyphContentTransformFn (for example svg-outline-stroke) before conversion. See TROUBLESHOOTING.md ("Icon details missing after export").`;
586
+ case "unsupported-element": return `[webfont:diagnose] ${t} contains <line>, <polyline>, or <clipPath>. These elements are poorly supported in icon fonts; results may differ from the browser preview. Convert to filled paths or preprocess with glyphContentTransformFn.`;
587
+ default: return e;
588
+ }
589
+ }, bt = (e, t) => {
590
+ let n = [];
591
+ return mt(t) && n.push({
592
+ code: "evenodd-fill-rule",
593
+ message: U("evenodd-fill-rule", e),
594
+ srcPath: e
595
+ }), vt(t) && n.push({
596
+ code: "stroke-only",
597
+ message: U("stroke-only", e),
598
+ srcPath: e
599
+ }), yt(t) && n.push({
600
+ code: "unsupported-element",
601
+ message: U("unsupported-element", e),
602
+ srcPath: e
603
+ }), n;
604
+ }, xt = (e) => e.flatMap((e) => bt(e.srcPath, e.contents)), St = (e, t) => t.diagnose ? !0 : !!(t.verbose && e.code === "evenodd-fill-rule"), Ct = (e) => {
605
+ if (!e || !e.diagnose) return;
606
+ let t = { diagnose: !0 };
607
+ return e.onMessage && (t.onMessage = e.onMessage), t;
608
+ }, wt = (e, t, n = {}) => {
609
+ let r = Ct(t), i = xt(e), { reporter: a, verbose: o = !1 } = n;
610
+ for (let e of i) St(e, {
611
+ diagnose: r?.diagnose,
612
+ verbose: o
613
+ }) && a?.(e.message);
614
+ let s = [];
615
+ return r?.diagnose && (s = i), {
616
+ diagnostics: s,
617
+ glyphs: e
618
+ };
619
+ }, Tt = (e, t, n = {}) => {
620
+ let { diagnostics: r, glyphs: i } = wt(e, t, n);
621
+ return {
622
+ diagnostics: r,
623
+ glyphs: i
624
+ };
625
+ }, Et = (e, t) => {
455
626
  let n = "";
456
627
  return new Promise((r, i) => {
457
628
  t.verbose && console.log("Generating SVG font...");
458
- let a = new te(V(t)).on("finish", () => r(n)).on("data", (e) => {
629
+ let a = new g(Je(t)).on("finish", () => r(n)).on("data", (e) => {
459
630
  n += e;
460
631
  }).on("error", (e) => i(e));
461
632
  e.forEach((e) => {
462
- let t = new m();
633
+ let t = new se();
463
634
  t.push(e.contents), t.push(null), t.metadata = e.metadata ?? {
464
635
  name: "",
465
636
  unicode: []
466
637
  }, a.write(t);
467
638
  }), a.end();
468
639
  });
469
- }, Be = (e) => H(e), Ve = (e, t) => Buffer.from(h(e, t).buffer), He = (e) => g.compress(e), Ue = async (e) => {
470
- let t = Pe(e);
471
- delete t.filePath;
472
- let r = await Re({ configFile: t.configFile }), i;
473
- Le(r) && (t = f(t, r.config, { arrayMerge: (e, t) => t }), i = r.filepath);
474
- let a;
475
- a = Array.isArray(t.files) ? t.files : [t.files];
476
- let o = await N(a), s = xe(o);
477
- if (s === "mixed") throw Error("Cannot mix SVG icons with WOFF/WOFF2 font files in the same run");
478
- if (s === "empty") throw Error("Files glob patterns specified did not match any supported files");
479
- if (s === "webfont") {
480
- let e = await ke(Y(o, s), t);
481
- return i && (e.config = {
482
- ...t,
483
- filePath: i
484
- }), e;
640
+ }, Dt = (e, t = {}) => Buffer.from(ce(e, t).buffer), Ot = (e) => M(e), kt = (e, t) => N(e, t), At = (e) => P(e), jt = async (e, t) => {
641
+ let n = (e) => {
642
+ if (t.svgTools?.onMessage) {
643
+ t.svgTools.onMessage(e);
644
+ return;
645
+ }
646
+ (t.svgTools?.diagnose || t.verbose) && console.log(e);
647
+ }, r = !!(t.svgTools?.onMessage || t.svgTools?.diagnose || t.verbose), i;
648
+ r && (i = n);
649
+ let { diagnostics: a, glyphs: o } = Tt(e, t.svgTools, {
650
+ reporter: i,
651
+ verbose: t.verbose
652
+ }), s = o;
653
+ if (t.optimizeSvg && (s = rt(s, t.svgoConfig)), t.glyphContentTransformFn) {
654
+ let e = t.glyphContentTransformFn;
655
+ s = await Promise.all(s.map(async (t) => {
656
+ let n = await e(t);
657
+ return {
658
+ ...t,
659
+ contents: n
660
+ };
661
+ }));
485
662
  }
486
- Se(t.formats);
487
- let l = await Ne(Y(o, "svg"), t);
488
663
  if (t.glyphTransformFn) {
489
- let e = t.glyphTransformFn, n = l.map(async (t) => {
664
+ let e = t.glyphTransformFn;
665
+ s = await Promise.all(s.map(async (t) => {
490
666
  let n = await e(t.metadata ?? {
491
667
  name: "",
492
668
  unicode: []
@@ -495,71 +671,142 @@ var oe = Object.create, x = Object.defineProperty, se = Object.getOwnPropertyDes
495
671
  ...t,
496
672
  metadata: n
497
673
  };
498
- });
499
- l = await Promise.all(n);
674
+ }));
500
675
  }
501
- let u = {};
502
- t.formatsOptions?.ttf && (u = t.formatsOptions.ttf);
503
- let d = await ze(l, t), m = Ie(d, u), h = {
504
- glyphsData: l,
505
- hash: ee.createHash("md5").update(d).digest("hex"),
506
- svg: d,
507
- ttf: m
508
- }, { formats: g } = t;
509
- if (g.includes("eot") && (h.eot = Be(m)), g.includes("woff")) {
676
+ it(s.length, t.ligatures) && console.log(at(s.length));
677
+ let c = {};
678
+ t.formatsOptions?.ttf && (c = t.formatsOptions.ttf);
679
+ let l = await Et(s, t);
680
+ ft(l, s);
681
+ let u = Dt(l, c), d = {
682
+ config: t,
683
+ glyphsData: s,
684
+ hash: ae.createHash("md5").update(l).digest("hex"),
685
+ svg: l,
686
+ ttf: u
687
+ };
688
+ a.length > 0 && (d.svgDiagnostics = a);
689
+ let { formats: f } = t;
690
+ if (f.includes("eot") && (d.eot = Ot(u)), f.includes("woff")) {
510
691
  let e;
511
- typeof t.metadata == "string" && (e = t.metadata), h.woff = Ve(m, { metadata: e });
692
+ typeof t.metadata == "string" && (e = t.metadata), d.woff = kt(u, { metadata: e });
512
693
  }
513
- if (g.includes("woff2") && (h.woff2 = Buffer.from(await He(m))), t.template) {
514
- let e = z(), r;
515
- if (Object.keys(e).includes(t.template)) {
516
- h.usedBuildInTemplate = !0;
517
- let e = c.resolve(n, "../..");
518
- p.configure(e), r = R(t.template);
519
- } else {
520
- let e = c.resolve(t.template);
521
- p.configure(c.dirname(e)), r = c.resolve(e);
522
- }
523
- let i = {};
524
- t.addHashInFontUrl && (i = { hash: h.hash });
525
- let a = f.all([
526
- { glyphs: h.glyphsData?.map((e) => e.metadata) ?? [] },
527
- t,
528
- {
529
- cacheString: t.templateCacheString || Date.now(),
530
- className: t.templateClassName || t.fontName,
531
- fontName: t.templateFontName || t.fontName,
532
- fontPath: t.templateFontPath.replace(/\/?$/u, "/")
533
- },
534
- i,
535
- { fonts: Object.fromEntries(new Map(g.map((e) => [e, () => Fe(e, h)]))) }
536
- ]);
537
- h.template = p.render(r, a);
694
+ if (f.includes("woff2") && (d.woff2 = Buffer.from(await At(u))), t.template) {
695
+ let { renderTemplates: e } = await import("./renderTemplates-DvRlS58E.mjs"), { templates: n, usedBuildInTemplate: r } = e(t, d, f);
696
+ n.length > 0 && (d.templates = n, d.template = n[0]?.content, d.usedBuildInTemplate = r);
538
697
  }
539
- return g.includes("svg") || delete h.svg, g.includes("ttf") || delete h.ttf, g.includes("otf") || delete h.otf, i ? h.config = {
540
- ...t,
541
- filePath: i
542
- } : h.config = t, h;
543
- }, X = /* @__PURE__ */ new Set([
698
+ return f.includes("svg") || delete d.svg, f.includes("ttf") || delete d.ttf, f.includes("otf") || delete d.otf, d;
699
+ }, W = /* @__PURE__ */ new Set([
544
700
  "eot",
545
701
  "otf",
546
702
  "svg",
547
703
  "ttf",
548
704
  "woff",
549
705
  "woff2"
550
- ]), Z = (e) => {
551
- if (typeof e != "string" || !X.has(e)) throw Error(`Invalid format "${String(e)}". Expected one of: ${[...X].join(", ")}`);
706
+ ]), Mt = [...W].join(", "), G = (e) => {
707
+ if (typeof e != "string" || !W.has(e)) throw Error(`Invalid format "${String(e)}". Expected one of: ${Mt}`);
552
708
  return e;
553
- }, We = (e) => {
554
- let t = e.trim();
555
- if (t.startsWith("{") || t.startsWith("[")) {
556
- let e = JSON.parse(t);
557
- if (!Array.isArray(e)) throw Error("formats must be a JSON array");
558
- return e.map(Z);
709
+ }, K = (e) => {
710
+ if (e.length === 0) throw Error("formats must not be empty");
711
+ return e.map(G);
712
+ }, Nt = (e) => {
713
+ if (!Array.isArray(e)) throw Error("formats must be an array of format names (e.g. [\"woff2\", \"svg\"])");
714
+ return K(e);
715
+ }, q = (e, t) => {
716
+ if (t !== void 0 && typeof t != "string") throw Error(`${e} must be a string`);
717
+ }, Pt = (e, t) => {
718
+ if (t !== void 0 && typeof t != "boolean" && typeof t != "string") throw Error(`${e} must be a boolean or string`);
719
+ }, J = (e, t) => {
720
+ if (t !== void 0 && typeof t != "boolean") throw Error(`${e} must be a boolean`);
721
+ }, Ft = (e, t) => {
722
+ if (t !== void 0 && (typeof t != "object" || !t || Array.isArray(t))) throw Error(`${e} must be an object`);
723
+ }, It = (e) => {
724
+ if (typeof e == "string") {
725
+ if (e.length === 0) throw Error("files must not be empty");
726
+ return;
727
+ }
728
+ if (Array.isArray(e)) {
729
+ if (e.length === 0) throw Error("files must not be empty");
730
+ if (!e.every((e) => typeof e == "string")) throw Error("files must be a string or an array of strings");
731
+ return;
732
+ }
733
+ throw Error("files must be a string or an array of strings");
734
+ }, Lt = (e) => (It(e.files), e.formats = Nt(e.formats), q("fontName", e.fontName), Pt("unicodeRange", e.unicodeRange), J("optimizeSvg", e.optimizeSvg), Ft("svgoConfig", e.svgoConfig), J("templateFontLigatures", e.templateFontLigatures), e.template !== void 0 && n(e.template), q("templateFontPath", e.templateFontPath), e), Rt = (e) => "filepath" in e, Y = async (e) => {
735
+ let t = d("webfont", { searchStrategy: "global" });
736
+ if (e.configFile) {
737
+ let n = c.resolve(process.cwd(), e.configFile);
738
+ return await t.load(n) ?? {};
739
+ }
740
+ return await t.search(process.cwd()) ?? {};
741
+ }, zt = Y, Bt = async (e) => {
742
+ let t = $e(e);
743
+ delete t.filePath;
744
+ let n = await Y({ configFile: t.configFile }), r;
745
+ Rt(n) && (t = f(t, n.config, { arrayMerge: (e, t) => t }), r = n.filepath), t = Lt(t);
746
+ let i;
747
+ i = Array.isArray(t.files) ? t.files : [t.files];
748
+ let a = await E(i), o = Se(a);
749
+ if (o === "mixed") throw Error("Cannot mix SVG icons, TTF fonts, and WOFF/WOFF2 files in the same run");
750
+ if (o === "empty") throw Error("Files glob patterns specified did not match any supported files");
751
+ if (o === "webfont") {
752
+ let e = await We(H(a, o), t);
753
+ return r && (e.config = {
754
+ ...t,
755
+ filePath: r
756
+ }), e;
559
757
  }
758
+ if (o === "ttf") {
759
+ let e = await Me(H(a, o), t);
760
+ return r && (e.config = {
761
+ ...t,
762
+ filePath: r
763
+ }), e;
764
+ }
765
+ Ce(t.formats);
766
+ let s = await jt(await Ze(H(a, "svg"), t), t);
767
+ return r ? s.config = {
768
+ ...t,
769
+ filePath: r
770
+ } : s.config = t, s;
771
+ }, Vt = (e) => {
772
+ if (e.svgDiagnose) return { diagnose: !0 };
773
+ }, Ht = (e) => {
774
+ if (e === void 0) return;
775
+ let t = e.trim();
560
776
  if (t.length === 0) throw Error("formats must not be empty");
561
- return t.split(",").map((e) => Z(e.trim()));
562
- }, Ge = [
777
+ if (t.startsWith("[") || t.startsWith("{")) {
778
+ let e;
779
+ try {
780
+ e = JSON.parse(t);
781
+ } catch {
782
+ throw Error("formats must be a JSON array (e.g. [\"woff2\",\"svg\"]) or comma-separated list");
783
+ }
784
+ if (!Array.isArray(e)) throw Error("formats must be a JSON array (e.g. [\"woff2\",\"svg\"]) or comma-separated list");
785
+ return K(e);
786
+ }
787
+ return t.split(",").map((e) => e.trim()).filter((e) => e.length > 0).map(G);
788
+ }, Ut = (e) => {
789
+ if (e === void 0) return;
790
+ let t = e.trim();
791
+ if (t.length === 0) throw Error("template must not be empty");
792
+ if (t.startsWith("[") || t.startsWith("{")) {
793
+ let e;
794
+ try {
795
+ e = JSON.parse(t);
796
+ } catch {
797
+ throw Error("template must be a JSON array (e.g. [\"html\",\"scss\"]) or a template name");
798
+ }
799
+ if (!Array.isArray(e)) throw Error("template must be a JSON array (e.g. [\"html\",\"scss\"]) or a template name");
800
+ return n(e);
801
+ }
802
+ return t.includes(",") ? n(t.split(",").map((e) => e.trim()).filter((e) => e.length > 0)) : t;
803
+ }, Wt = (e) => {
804
+ if (!(!("config" in e) || e.config?.files === void 0)) return Array.isArray(e.config.files) ? e.config.files : [e.config.files];
805
+ }, Gt = async (e, t) => {
806
+ let n = Wt(await zt({ configFile: t.configFile }));
807
+ if (e.input.length > 0 && n !== void 0) throw Error("Cannot specify input files on the command line when `files` is set in the config file");
808
+ return e.input.length > 0 ? e.input : n === void 0 ? [] : n;
809
+ }, Kt = [
563
810
  "svg",
564
811
  "ttf",
565
812
  "otf",
@@ -568,24 +815,37 @@ var oe = Object.create, x = Object.defineProperty, se = Object.getOwnPropertyDes
568
815
  "woff2",
569
816
  "hash",
570
817
  "template"
571
- ], Q = (e) => {
818
+ ], qt = (e) => {
572
819
  let t = {};
573
- return typeof e.flags.config == "string" && (t.configFile = l.silent(process.cwd(), e.flags.config) || s.join(process.cwd(), e.flags.config)), e.flags.fontName && (t.fontName = e.flags.fontName), e.flags.formats && (t.formats = We(e.flags.formats)), e.flags.dest && (t.dest = e.flags.dest), e.flags.destCreate && (t.destCreate = e.flags.destCreate), e.flags.template && (t.template = e.flags.template), e.flags.templateClassName && (t.templateClassName = e.flags.templateClassName), e.flags.templateFontPath && (t.templateFontPath = e.flags.templateFontPath), e.flags.templateFontName && (t.templateFontName = e.flags.templateFontName), e.flags.templateCacheString && (t.templateCacheString = e.flags.templateCacheString), e.flags.destTemplate && (t.destTemplate = e.flags.destTemplate), e.flags.verbose && (t.verbose = e.flags.verbose), e.flags.fontId && (t.fontId = e.flags.fontId), e.flags.fontStyle && (t.fontStyle = e.flags.fontStyle), e.flags.fontWeight && (t.fontWeight = e.flags.fontWeight), e.flags.fixedWidth && (t.fixedWidth = e.flags.fixedWidth), e.flags.centerHorizontally && (t.centerHorizontally = e.flags.centerHorizontally), e.flags.normalize && (t.normalize = e.flags.normalize), e.flags.fontHeight && (t.fontHeight = e.flags.fontHeight), e.flags.round && (t.round = e.flags.round), e.flags.descent && (t.descent = e.flags.descent), e.flags.ascent && (t.ascent = e.flags.ascent), e.flags.startUnicode && (t.startUnicode = e.flags.startUnicode), e.flags.prependUnicode && (t.prependUnicode = e.flags.prependUnicode), e.flags.metadata && (t.metadata = e.flags.metadata), e.flags.sort === !1 && (t.sort = e.flags.sort), e.flags.ligatures === !1 && (t.ligatures = e.flags.ligatures), e.flags.addHashInFontUrl && (t.addHashInFontUrl = e.flags.addHashInFontUrl), t;
574
- }, $ = (e) => {
820
+ typeof e.flags.config == "string" && (t.configFile = l.silent(process.cwd(), e.flags.config) || s.join(process.cwd(), e.flags.config)), e.flags.fontName && (t.fontName = e.flags.fontName), e.flags.formats && (t.formats = Ht(e.flags.formats)), e.flags.dest && (t.dest = e.flags.dest), e.flags.destCreate && (t.destCreate = e.flags.destCreate), e.flags.template && (t.template = Ut(e.flags.template)), e.flags.templateClassName && (t.templateClassName = e.flags.templateClassName), e.flags.templateFontPath && (t.templateFontPath = e.flags.templateFontPath), e.flags.templateFontName && (t.templateFontName = e.flags.templateFontName), e.flags.templateCacheString && (t.templateCacheString = e.flags.templateCacheString), e.flags.destTemplate && (t.destTemplate = e.flags.destTemplate), e.flags.verbose && (t.verbose = e.flags.verbose), e.flags.fontId && (t.fontId = e.flags.fontId), e.flags.fontStyle && (t.fontStyle = e.flags.fontStyle), e.flags.fontWeight && (t.fontWeight = e.flags.fontWeight), e.flags.fixedWidth && (t.fixedWidth = e.flags.fixedWidth), e.flags.centerHorizontally && (t.centerHorizontally = e.flags.centerHorizontally), e.flags.normalize && (t.normalize = e.flags.normalize), e.flags.optimizeSvg && (t.optimizeSvg = e.flags.optimizeSvg), e.flags.fontHeight && (t.fontHeight = e.flags.fontHeight), e.flags.round && (t.round = e.flags.round), e.flags.descent && (t.descent = e.flags.descent), e.flags.ascent && (t.ascent = e.flags.ascent), e.flags.startUnicode && (t.startUnicode = e.flags.startUnicode), e.flags.prependUnicode && (t.prependUnicode = e.flags.prependUnicode), e.flags.metadata && (t.metadata = e.flags.metadata), e.flags.sort === !1 && (t.sort = e.flags.sort), e.flags.ligatures && (t.ligatures = e.flags.ligatures), e.flags.unicodeRange && (t.unicodeRange = e.flags.unicodeRange), e.flags.templateFontLigatures === !1 && (t.templateFontLigatures = e.flags.templateFontLigatures), e.flags.addHashInFontUrl && (t.addHashInFontUrl = e.flags.addHashInFontUrl);
821
+ let n = Vt(e.flags);
822
+ return n && (t.svgTools = n), t;
823
+ }, X = (e) => {
575
824
  if (!e.config) throw Error("Missing config in webfont result");
576
825
  return e.config;
577
- }, Ke = (e, t) => (e.config = {
578
- ...$(e),
826
+ }, Jt = (e, t) => (e.config = {
827
+ ...X(e),
579
828
  dest: t.dest,
580
829
  destTemplate: t.destTemplate
581
- }, e), qe = (e, t) => {
830
+ }, e), Z = (e, t, n) => {
831
+ let r = t.dest ?? process.cwd();
832
+ return typeof t.destTemplate == "string" && (r = t.destTemplate), n ? s.join(r, `${t.fontName}.${e}`) : s.join(r, s.basename(e).replace(".njk", ""));
833
+ }, Q = (e) => Array.isArray(e) ? e[0] : e, Yt = (e, t) => {
582
834
  if (!e.template) return;
583
- let n = t.dest ?? process.cwd(), r;
584
- return r = typeof t.destTemplate == "string" ? t.destTemplate : n, e.usedBuildInTemplate && typeof t.template == "string" ? s.join(r, `${t.fontName}.${t.template}`) : typeof t.template == "string" ? s.join(r, s.basename(t.template).replace(".njk", "")) : r;
585
- }, Je = (e, t, n, r) => {
835
+ let n = Q(t.template);
836
+ if (e.usedBuildInTemplate && n) return Z(n, t, !0);
837
+ if (n) return Z(n, t, !1);
838
+ let r = t.dest ?? process.cwd();
839
+ return typeof t.destTemplate == "string" ? t.destTemplate : r;
840
+ }, Xt = async (e, t) => {
841
+ await Promise.all(e.map(async (e) => {
842
+ let n = s.resolve(Z(e.template, t, !!e.builtIn));
843
+ await a.promises.mkdir(s.dirname(n), { recursive: !0 }), await a.promises.writeFile(n, e.content);
844
+ }));
845
+ }, Zt = (e, t, n, r) => {
586
846
  let i = n.fontName, a = n.dest ?? process.cwd();
587
847
  return e === "template" ? s.resolve(r ?? a) : e === "hash" ? s.resolve(s.join(a, `${i}.hash`)) : s.resolve(s.join(a, `${i}.${e}`));
588
- }, Ye = (e) => /* @__PURE__ */ Error(`Destination directory "${e}" does not exist. Use --dest-create (-m) to create it.`), Xe = async (e, t) => {
848
+ }, Qt = (e) => /* @__PURE__ */ Error(`Destination directory "${e}" does not exist. Use --dest-create (-m) to create it.`), $t = async (e, t) => {
589
849
  try {
590
850
  await a.promises.access(e, a.constants.F_OK);
591
851
  } catch {
@@ -593,36 +853,41 @@ var oe = Object.create, x = Object.defineProperty, se = Object.getOwnPropertyDes
593
853
  await a.promises.mkdir(e, { recursive: !0 });
594
854
  return;
595
855
  }
596
- throw Ye(e);
856
+ throw Qt(e);
597
857
  }
598
- }, Ze = (e, t, n) => e.length === 1 && n.fontName ? n.fontName : I(e.map((e) => e.source))[e.indexOf(t)] ?? n.fontName, Qe = async (e, t, n) => {
858
+ }, $ = (e, t, n) => e.length === 1 && n.fontName ? n.fontName : T(e.map((e) => e.source))[e.indexOf(t)] ?? n.fontName, en = async (e, t, n) => {
599
859
  await Promise.all(e.flatMap((r) => {
600
- let i = Ze(e, r, t), o = [];
860
+ let i = $(e, r, t), o = [];
601
861
  return r.ttf && o.push(a.promises.writeFile(s.resolve(s.join(n, `${i}.ttf`)), r.ttf)), r.otf && o.push(a.promises.writeFile(s.resolve(s.join(n, `${i}.otf`)), r.otf)), o;
602
862
  }));
603
- }, $e = async (e) => {
604
- let t = $(e), n = t.dest ?? process.cwd(), r = qe(e, t);
605
- return e.template && delete e.hash, await Xe(n, t.destCreate), e.decompressedFonts && e.decompressedFonts.length > 1 ? (await Qe(e.decompressedFonts, t, n), e) : (await Promise.all(Ge.filter((t) => e[t] !== void 0).map(async (n) => {
863
+ }, tn = (e, t, n) => $(e, t, n), nn = async (e, t, n) => {
864
+ await Promise.all(e.flatMap((r) => {
865
+ let i = tn(e, r, t), o = [];
866
+ return r.ttf && o.push(a.promises.writeFile(s.resolve(s.join(n, `${i}.ttf`)), r.ttf)), r.eot && o.push(a.promises.writeFile(s.resolve(s.join(n, `${i}.eot`)), r.eot)), r.woff && o.push(a.promises.writeFile(s.resolve(s.join(n, `${i}.woff`)), r.woff)), r.woff2 && o.push(a.promises.writeFile(s.resolve(s.join(n, `${i}.woff2`)), r.woff2)), o;
867
+ }));
868
+ }, rn = async (e) => {
869
+ let t = X(e), n = t.dest ?? process.cwd(), r = Yt(e, t);
870
+ return e.template && delete e.hash, await $t(n, t.destCreate), e.templates && e.templates.length > 0 && await Xt(e.templates, t), e.transcodedFonts && e.transcodedFonts.length > 1 ? (await nn(e.transcodedFonts, t, n), e) : e.decompressedFonts && e.decompressedFonts.length > 1 ? (await en(e.decompressedFonts, t, n), e) : (await Promise.all(Kt.filter((t) => t === "template" && e.templates && e.templates.length > 0 ? !1 : e[t] !== void 0).map(async (n) => {
606
871
  let i = e[n];
607
872
  if (i === void 0) return;
608
- let o = Je(n, e, t, r);
873
+ let o = Zt(n, e, t, r);
609
874
  await a.promises.writeFile(o, i);
610
875
  })), e);
611
- }, et = (e) => typeof e == "object" && e && "code" in e && typeof e.code == "number" ? e.code : 1, tt = (e) => {
612
- nt(e).catch((e) => {
613
- console.log(e.stack), process.exit(et(e));
876
+ }, an = (e) => typeof e == "object" && e && "code" in e && typeof e.code == "number" ? e.code : 1, on = (e) => {
877
+ sn(e).catch((e) => {
878
+ console.log(e.stack), process.exit(an(e));
614
879
  });
615
- }, nt = async (e) => {
880
+ }, sn = async (e) => {
616
881
  e.flags.help && e.showHelp(), e.flags.version && e.showVersion();
617
- let t = {
618
- ...Q(e),
619
- files: e.input
620
- };
621
- t.files.length === 0 && e.showHelp();
622
- let n = await Ue(t);
623
- return Ke(n, t), $e(n);
882
+ let t = qt(e), n = await Gt(e, t);
883
+ n.length === 0 && e.showHelp();
884
+ let r = {
885
+ ...t,
886
+ files: n
887
+ }, i = await Bt(r);
888
+ return Jt(i, r), rn(i);
624
889
  };
625
890
  //#endregion
626
891
  //#region src/cli/index.ts
627
- tt(k);
892
+ on(ye);
628
893
  //#endregion