@getvitops/utils 1.0.0 → 2.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.
- package/CHANGELOG.md +228 -0
- package/README.md +33 -0
- package/dist/color/index.d.mts +17 -3
- package/dist/color/index.d.mts.map +1 -1
- package/dist/color/index.mjs +19 -5
- package/dist/color/index.mjs.map +1 -1
- package/dist/favicon.d.mts +13 -0
- package/dist/favicon.d.mts.map +1 -1
- package/dist/favicon.mjs +40 -28
- package/dist/favicon.mjs.map +1 -1
- package/dist/index.d.mts +216 -21
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +369 -29
- package/dist/index.mjs.map +1 -1
- package/dist/indexing/index.d.mts +277 -0
- package/dist/indexing/index.d.mts.map +1 -0
- package/dist/indexing/index.mjs +547 -0
- package/dist/indexing/index.mjs.map +1 -0
- package/dist/media/index.d.mts +277 -0
- package/dist/media/index.d.mts.map +1 -0
- package/dist/media/index.mjs +533 -0
- package/dist/media/index.mjs.map +1 -0
- package/package.json +9 -1
package/dist/favicon.mjs
CHANGED
|
@@ -15,6 +15,19 @@ import { join } from "node:path";
|
|
|
15
15
|
* crush) is used when present on PATH and skipped otherwise — it is optional.
|
|
16
16
|
*/
|
|
17
17
|
const exec = promisify(cp.exec);
|
|
18
|
+
/** `#rgb` / `#rrggbb` → a sharp background. Anything else is rejected loudly. */
|
|
19
|
+
function parseBackground(color) {
|
|
20
|
+
const hex = color.trim().replace(/^#/, "");
|
|
21
|
+
const full = hex.length === 3 ? [...hex].map((c) => c + c).join("") : hex.length === 6 ? hex : null;
|
|
22
|
+
if (full == null || !/^[0-9a-f]{6}$/i.test(full)) throw new Error(`favicon: backgroundColor must be a hex colour like "#ffffff" or "#fff" (got ${JSON.stringify(color)}).`);
|
|
23
|
+
const n = Number.parseInt(full, 16);
|
|
24
|
+
return {
|
|
25
|
+
r: n >> 16 & 255,
|
|
26
|
+
g: n >> 8 & 255,
|
|
27
|
+
b: n & 255,
|
|
28
|
+
alpha: 1
|
|
29
|
+
};
|
|
30
|
+
}
|
|
18
31
|
let warnedNoOxipng = false;
|
|
19
32
|
async function optimizePng(file, enabled) {
|
|
20
33
|
if (!enabled) return;
|
|
@@ -28,6 +41,21 @@ async function optimizePng(file, enabled) {
|
|
|
28
41
|
}
|
|
29
42
|
}
|
|
30
43
|
/**
|
|
44
|
+
* Does the source carry any transparency at all?
|
|
45
|
+
*
|
|
46
|
+
* Best-effort and deliberately quiet on failure — this only decides whether to
|
|
47
|
+
* print a warning, so a probe that throws must not take the build down with it.
|
|
48
|
+
* `stats().isOpaque` is sharp's own answer and covers the SVG case too, since it
|
|
49
|
+
* rasterises first.
|
|
50
|
+
*/
|
|
51
|
+
async function hasTransparency(sharp, source) {
|
|
52
|
+
try {
|
|
53
|
+
return !(await sharp(source, { density: 384 }).stats()).isOpaque;
|
|
54
|
+
} catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
31
59
|
* Generate the standard favicon set from an SVG/PNG source into `outputDir`:
|
|
32
60
|
* `favicon.ico`, `icon-{16?,32,192,512}.png`, `apple-touch-icon.png`, `icon-mask.png`.
|
|
33
61
|
* Returns the list of written file paths.
|
|
@@ -38,6 +66,7 @@ async function generateFavicons(opts) {
|
|
|
38
66
|
if (!source.endsWith(".svg") && !source.endsWith(".png")) throw new Error("favicon: source must be an SVG or PNG file");
|
|
39
67
|
const dir = (opts.outputDir ?? ".").replace(/\/+$/, "");
|
|
40
68
|
const optimize = opts.optimize ?? true;
|
|
69
|
+
const maskBg = parseBackground(opts.backgroundColor ?? "#ffffff");
|
|
41
70
|
mkdirSync(dir, { recursive: true });
|
|
42
71
|
const out = (name) => join(dir, name);
|
|
43
72
|
const written = [];
|
|
@@ -75,47 +104,28 @@ async function generateFavicons(opts) {
|
|
|
75
104
|
if (lowResSource) icoSources.unshift(out("icon-16.png"));
|
|
76
105
|
await writeFile(out("favicon.ico"), await pngToIco(icoSources));
|
|
77
106
|
written.push(out("favicon.ico"));
|
|
107
|
+
if (opts.backgroundColor == null && await hasTransparency(sharp, source)) console.warn(`favicon: ${source} has transparency, and the maskable outputs (icon-mask.png, apple-touch-icon.png) must be opaque — the OS crops them to its own shape. Defaulting their background to #ffffff; set backgroundColor to choose.`);
|
|
78
108
|
await sharp(out("icon-512.png")).resize(140, 140, {
|
|
79
109
|
fit: "contain",
|
|
80
|
-
background:
|
|
81
|
-
r: 0,
|
|
82
|
-
g: 0,
|
|
83
|
-
b: 0,
|
|
84
|
-
alpha: 0
|
|
85
|
-
}
|
|
110
|
+
background: maskBg
|
|
86
111
|
}).extend({
|
|
87
112
|
top: 20,
|
|
88
113
|
bottom: 20,
|
|
89
114
|
left: 20,
|
|
90
115
|
right: 20,
|
|
91
|
-
background:
|
|
92
|
-
|
|
93
|
-
g: 0,
|
|
94
|
-
b: 0,
|
|
95
|
-
alpha: 0
|
|
96
|
-
}
|
|
97
|
-
}).png().toFile(out("apple-touch-icon.png"));
|
|
116
|
+
background: maskBg
|
|
117
|
+
}).flatten({ background: maskBg }).png().toFile(out("apple-touch-icon.png"));
|
|
98
118
|
written.push(out("apple-touch-icon.png"));
|
|
99
119
|
await sharp(out("icon-512.png")).resize(409, 409, {
|
|
100
120
|
fit: "contain",
|
|
101
|
-
background:
|
|
102
|
-
r: 0,
|
|
103
|
-
g: 0,
|
|
104
|
-
b: 0,
|
|
105
|
-
alpha: 0
|
|
106
|
-
}
|
|
121
|
+
background: maskBg
|
|
107
122
|
}).extend({
|
|
108
123
|
top: 52,
|
|
109
124
|
bottom: 51,
|
|
110
125
|
left: 52,
|
|
111
126
|
right: 51,
|
|
112
|
-
background:
|
|
113
|
-
|
|
114
|
-
g: 0,
|
|
115
|
-
b: 0,
|
|
116
|
-
alpha: 0
|
|
117
|
-
}
|
|
118
|
-
}).png().toFile(out("icon-mask.png"));
|
|
127
|
+
background: maskBg
|
|
128
|
+
}).flatten({ background: maskBg }).png().toFile(out("icon-mask.png"));
|
|
119
129
|
written.push(out("icon-mask.png"));
|
|
120
130
|
await Promise.all([
|
|
121
131
|
"icon-192.png",
|
|
@@ -169,12 +179,14 @@ function faviconManifest(opts) {
|
|
|
169
179
|
{
|
|
170
180
|
src: src("icon-192.png"),
|
|
171
181
|
sizes: "192x192",
|
|
172
|
-
type: "image/png"
|
|
182
|
+
type: "image/png",
|
|
183
|
+
purpose: "any"
|
|
173
184
|
},
|
|
174
185
|
{
|
|
175
186
|
src: src("icon-512.png"),
|
|
176
187
|
sizes: "512x512",
|
|
177
|
-
type: "image/png"
|
|
188
|
+
type: "image/png",
|
|
189
|
+
purpose: "any"
|
|
178
190
|
},
|
|
179
191
|
{
|
|
180
192
|
src: src("icon-mask.png"),
|
package/dist/favicon.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"favicon.mjs","names":[],"sources":["../src/favicon.ts"],"sourcesContent":["/**\n * Favicon generation — rasterize a source SVG/PNG into the standard favicon set.\n *\n * Ported from the repo's `lib/favicon.ts` so the logic lives in one place instead\n * of being copied per client. `sharp` + `png-to-ico` are loaded lazily (dynamic\n * import) so merely importing this module is cheap; the native `sharp` binary is\n * only touched when `generateFavicons` actually runs. `oxipng` (lossless PNG\n * crush) is used when present on PATH and skipped otherwise — it is optional.\n */\nimport { mkdirSync } from 'node:fs';\nimport { copyFile, writeFile } from 'node:fs/promises';\nimport { promisify } from 'node:util';\nimport cp from 'node:child_process';\nimport { join } from 'node:path';\n\nconst exec = promisify(cp.exec);\n\nexport interface FaviconOptions {\n /** Source image — an SVG or PNG. */\n source: string;\n /** Optional simplified source for the 16px icon. */\n lowResSource?: string;\n /** Directory to write into (default: current directory). */\n outputDir?: string;\n /** Run `oxipng` on the larger PNGs when available (default: true). */\n optimize?: boolean;\n}\n\nlet warnedNoOxipng = false;\nasync function optimizePng(file: string, enabled: boolean): Promise<void> {\n if (!enabled) return;\n try {\n await exec(`oxipng -o 3 \"${file}\"`);\n } catch {\n // oxipng missing or failed — lossless crush is best-effort, so skip quietly.\n if (!warnedNoOxipng) {\n warnedNoOxipng = true;\n console.warn('favicon: oxipng not available — skipping lossless PNG optimization.');\n }\n }\n}\n\n/**\n * Generate the standard favicon set from an SVG/PNG source into `outputDir`:\n * `favicon.ico`, `icon-{16?,32,192,512}.png`, `apple-touch-icon.png`, `icon-mask.png`.\n * Returns the list of written file paths.\n */\nexport async function generateFavicons(opts: FaviconOptions): Promise<string[]> {\n const { source, lowResSource } = opts;\n if (!source) throw new Error('favicon: no source path provided');\n if (!source.endsWith('.svg') && !source.endsWith('.png'))\n throw new Error('favicon: source must be an SVG or PNG file');\n\n const dir = (opts.outputDir ?? '.').replace(/\\/+$/, '');\n const optimize = opts.optimize ?? true;\n mkdirSync(dir, { recursive: true });\n const out = (name: string) => join(dir, name);\n\n const written: string[] = [];\n\n // Modern browsers prefer a scalable SVG favicon (and it supports dark-mode via\n // CSS media queries) — ship the source verbatim as favicon.svg when it is one.\n if (source.endsWith('.svg')) {\n await copyFile(source, out('favicon.svg'));\n written.push(out('favicon.svg'));\n }\n\n // Lazy-load the native/heavy deps only when actually generating.\n const [{ default: sharp }, { default: pngToIco }] = await Promise.all([\n import('sharp'),\n import('png-to-ico'),\n ]);\n\n // Rasterize the main source at each size. sharp reads SVG natively via libvips;\n // rendering at high density first keeps small-size edges crisp (ignored for PNG).\n await Promise.all(\n [32, 192, 512].map((size) =>\n sharp(source, { density: 384 })\n .resize(size, size, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } })\n .png()\n .toFile(out(`icon-${size}.png`))\n .then(() => written.push(out(`icon-${size}.png`))),\n ),\n );\n\n // Optional low-res 16px variant.\n if (lowResSource) {\n await sharp(lowResSource, { density: 384 })\n .resize(16, 16, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } })\n .png()\n .toFile(out('icon-16.png'));\n written.push(out('icon-16.png'));\n }\n\n // favicon.ico — sharp can't encode .ico, so png-to-ico packs the PNGs into the\n // multi-resolution container. Browsers pick the best size inside the file.\n const icoSources = [out('icon-32.png')];\n if (lowResSource) icoSources.unshift(out('icon-16.png'));\n await writeFile(out('favicon.ico'), await pngToIco(icoSources));\n written.push(out('favicon.ico'));\n\n // apple-touch-icon: 140x140 logo centered on a 180x180 transparent canvas.\n await sharp(out('icon-512.png'))\n .resize(140, 140, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } })\n .extend({\n top: 20,\n bottom: 20,\n left: 20,\n right: 20,\n background: { r: 0, g: 0, b: 0, alpha: 0 },\n })\n .png()\n .toFile(out('apple-touch-icon.png'));\n written.push(out('apple-touch-icon.png'));\n\n // icon-mask (maskable): 409x409 logo centered on a 512x512 canvas.\n await sharp(out('icon-512.png'))\n .resize(409, 409, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } })\n .extend({\n top: 52,\n bottom: 51,\n left: 52,\n right: 51,\n background: { r: 0, g: 0, b: 0, alpha: 0 },\n })\n .png()\n .toFile(out('icon-mask.png'));\n written.push(out('icon-mask.png'));\n\n // Lossless crush of the larger PNGs (best-effort; needs oxipng on PATH).\n await Promise.all(\n ['icon-192.png', 'icon-512.png', 'apple-touch-icon.png', 'icon-mask.png'].map((image) =>\n optimizePng(out(image), optimize),\n ),\n );\n\n return written;\n}\n\n// ── Head tags + web manifest (the \"tag layer\" over the generated image files) ──\n\nexport interface FaviconLink {\n rel: string;\n href: string;\n type?: string;\n sizes?: string;\n}\n\nexport interface FaviconTagOptions {\n /** Whether a favicon.svg was emitted (source was an SVG). */\n hasSvg?: boolean;\n /** Include the `<link rel=\"manifest\">` (default true). */\n manifest?: boolean;\n /** URL base the favicon files are served from (default '' → site root). */\n base?: string;\n}\n\n/**\n * The ordered `<link>` data matching what `generateFavicons` writes. Pure — no\n * I/O — so it can drive an Astro `<Head />`, the CLI, or plain HTML.\n */\nexport function faviconLinks(opts: FaviconTagOptions = {}): FaviconLink[] {\n const base = (opts.base ?? '').replace(/\\/+$/, '');\n const href = (f: string) => `${base}/${f}`;\n const links: FaviconLink[] = [{ rel: 'icon', href: href('favicon.ico'), sizes: '32x32' }];\n if (opts.hasSvg) links.push({ rel: 'icon', type: 'image/svg+xml', href: href('favicon.svg') });\n links.push({ rel: 'icon', type: 'image/png', sizes: '32x32', href: href('icon-32.png') });\n links.push({ rel: 'apple-touch-icon', href: href('apple-touch-icon.png') });\n if (opts.manifest !== false) links.push({ rel: 'manifest', href: href('site.webmanifest') });\n return links;\n}\n\nexport interface WebManifestOptions {\n name: string;\n shortName?: string;\n themeColor?: string;\n backgroundColor?: string;\n /** URL base the icon files are served from (default '' → site root). */\n base?: string;\n}\n\n/** Build the web-app-manifest object (icons match `generateFavicons` output). */\nexport function faviconManifest(opts: WebManifestOptions): Record<string, unknown> {\n const base = (opts.base ?? '').replace(/\\/+$/, '');\n const src = (f: string) => `${base}/${f}`;\n return {\n name: opts.name,\n short_name: opts.shortName ?? opts.name,\n icons: [\n { src: src('icon-192.png'), sizes: '192x192', type: 'image/png' },\n { src: src('icon-512.png'), sizes: '512x512', type: 'image/png' },\n { src: src('icon-mask.png'), sizes: '512x512', type: 'image/png', purpose: 'maskable' },\n ],\n theme_color: opts.themeColor ?? '#ffffff',\n background_color: opts.backgroundColor ?? '#ffffff',\n display: 'standalone',\n start_url: '/',\n };\n}\n\n/** Write `site.webmanifest` into `dir`. Returns the written path. */\nexport async function writeFaviconManifest(dir: string, opts: WebManifestOptions): Promise<string> {\n const path = join(dir.replace(/\\/+$/, ''), 'site.webmanifest');\n await writeFile(path, `${JSON.stringify(faviconManifest(opts), null, 2)}\\n`);\n return path;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"favicon.mjs","names":[],"sources":["../src/favicon.ts"],"sourcesContent":["/**\n * Favicon generation — rasterize a source SVG/PNG into the standard favicon set.\n *\n * Ported from the repo's `lib/favicon.ts` so the logic lives in one place instead\n * of being copied per client. `sharp` + `png-to-ico` are loaded lazily (dynamic\n * import) so merely importing this module is cheap; the native `sharp` binary is\n * only touched when `generateFavicons` actually runs. `oxipng` (lossless PNG\n * crush) is used when present on PATH and skipped otherwise — it is optional.\n */\nimport { mkdirSync } from 'node:fs';\nimport { copyFile, writeFile } from 'node:fs/promises';\nimport { promisify } from 'node:util';\nimport cp from 'node:child_process';\nimport { join } from 'node:path';\n\nconst exec = promisify(cp.exec);\n\nexport interface FaviconOptions {\n /** Source image — an SVG or PNG. */\n source: string;\n /** Optional simplified source for the 16px icon. */\n lowResSource?: string;\n /** Directory to write into (default: current directory). */\n outputDir?: string;\n /** Run `oxipng` on the larger PNGs when available (default: true). */\n optimize?: boolean;\n /**\n * Background composited under the two MASKABLE outputs — `icon-mask.png` and\n * `apple-touch-icon.png` (default `#ffffff`, matching the web manifest's\n * `background_color`). The other outputs keep the source's transparency.\n *\n * Maskable means the OS crops the image to its own shape and expects full\n * bleed, so transparency there is not \"no background\", it is whatever the\n * launcher happens to composite onto — usually black. iOS discards alpha on the\n * apple-touch-icon outright. Since both files sit a deliberately-sized logo on a\n * larger canvas (the maskable safe zone), leaving that canvas transparent turned\n * ~36% of one and ~40% of the other into a black frame on the home screen.\n */\n backgroundColor?: string;\n}\n\n/** `#rgb` / `#rrggbb` → a sharp background. Anything else is rejected loudly. */\nfunction parseBackground(color: string): { r: number; g: number; b: number; alpha: number } {\n const hex = color.trim().replace(/^#/, '');\n const full =\n hex.length === 3 ? [...hex].map((c) => c + c).join('') : hex.length === 6 ? hex : null;\n if (full == null || !/^[0-9a-f]{6}$/i.test(full))\n throw new Error(\n `favicon: backgroundColor must be a hex colour like \"#ffffff\" or \"#fff\" (got ${JSON.stringify(color)}).`,\n );\n const n = Number.parseInt(full, 16);\n return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255, alpha: 1 };\n}\n\nlet warnedNoOxipng = false;\nasync function optimizePng(file: string, enabled: boolean): Promise<void> {\n if (!enabled) return;\n try {\n await exec(`oxipng -o 3 \"${file}\"`);\n } catch {\n // oxipng missing or failed — lossless crush is best-effort, so skip quietly.\n if (!warnedNoOxipng) {\n warnedNoOxipng = true;\n console.warn('favicon: oxipng not available — skipping lossless PNG optimization.');\n }\n }\n}\n\n/**\n * Does the source carry any transparency at all?\n *\n * Best-effort and deliberately quiet on failure — this only decides whether to\n * print a warning, so a probe that throws must not take the build down with it.\n * `stats().isOpaque` is sharp's own answer and covers the SVG case too, since it\n * rasterises first.\n */\nasync function hasTransparency(\n sharp: typeof import('sharp').default,\n source: string,\n): Promise<boolean> {\n try {\n return !(await sharp(source, { density: 384 }).stats()).isOpaque;\n } catch {\n return false;\n }\n}\n\n/**\n * Generate the standard favicon set from an SVG/PNG source into `outputDir`:\n * `favicon.ico`, `icon-{16?,32,192,512}.png`, `apple-touch-icon.png`, `icon-mask.png`.\n * Returns the list of written file paths.\n */\nexport async function generateFavicons(opts: FaviconOptions): Promise<string[]> {\n const { source, lowResSource } = opts;\n if (!source) throw new Error('favicon: no source path provided');\n if (!source.endsWith('.svg') && !source.endsWith('.png'))\n throw new Error('favicon: source must be an SVG or PNG file');\n\n const dir = (opts.outputDir ?? '.').replace(/\\/+$/, '');\n const optimize = opts.optimize ?? true;\n // Same default as the web manifest's `background_color`. The two disagreeing is\n // the actual bug: `backgroundColor` reached the manifest and never the raster.\n const maskBg = parseBackground(opts.backgroundColor ?? '#ffffff');\n mkdirSync(dir, { recursive: true });\n const out = (name: string) => join(dir, name);\n\n const written: string[] = [];\n\n // Modern browsers prefer a scalable SVG favicon (and it supports dark-mode via\n // CSS media queries) — ship the source verbatim as favicon.svg when it is one.\n if (source.endsWith('.svg')) {\n await copyFile(source, out('favicon.svg'));\n written.push(out('favicon.svg'));\n }\n\n // Lazy-load the native/heavy deps only when actually generating.\n const [{ default: sharp }, { default: pngToIco }] = await Promise.all([\n import('sharp'),\n import('png-to-ico'),\n ]);\n\n // Rasterize the main source at each size. sharp reads SVG natively via libvips;\n // rendering at high density first keeps small-size edges crisp (ignored for PNG).\n await Promise.all(\n [32, 192, 512].map((size) =>\n sharp(source, { density: 384 })\n .resize(size, size, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } })\n .png()\n .toFile(out(`icon-${size}.png`))\n .then(() => written.push(out(`icon-${size}.png`))),\n ),\n );\n\n // Optional low-res 16px variant.\n if (lowResSource) {\n await sharp(lowResSource, { density: 384 })\n .resize(16, 16, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } })\n .png()\n .toFile(out('icon-16.png'));\n written.push(out('icon-16.png'));\n }\n\n // favicon.ico — sharp can't encode .ico, so png-to-ico packs the PNGs into the\n // multi-resolution container. Browsers pick the best size inside the file.\n const icoSources = [out('icon-32.png')];\n if (lowResSource) icoSources.unshift(out('icon-16.png'));\n await writeFile(out('favicon.ico'), await pngToIco(icoSources));\n written.push(out('favicon.ico'));\n\n // The two MASKABLE outputs below are composited onto an opaque background: the\n // OS crops them to its own shape, so transparency reads as a black frame rather\n // than as \"no background\". Warn when we're inventing that colour rather than\n // being told it, since white is a guess that a dark logo would lose against.\n if (opts.backgroundColor == null && (await hasTransparency(sharp, source))) {\n console.warn(\n `favicon: ${source} has transparency, and the maskable outputs (icon-mask.png, ` +\n 'apple-touch-icon.png) must be opaque — the OS crops them to its own shape. ' +\n 'Defaulting their background to #ffffff; set backgroundColor to choose.',\n );\n }\n\n // apple-touch-icon: 140x140 logo centered on a 180x180 canvas.\n await sharp(out('icon-512.png'))\n .resize(140, 140, { fit: 'contain', background: maskBg })\n .extend({ top: 20, bottom: 20, left: 20, right: 20, background: maskBg })\n .flatten({ background: maskBg }) // iOS discards alpha; do it ourselves so we pick the colour\n .png()\n .toFile(out('apple-touch-icon.png'));\n written.push(out('apple-touch-icon.png'));\n\n // icon-mask (maskable): 409x409 logo centered on a 512x512 canvas. The 409/512\n // inset IS the maskable safe zone — the geometry was always right, only the\n // fill was wrong.\n await sharp(out('icon-512.png'))\n .resize(409, 409, { fit: 'contain', background: maskBg })\n .extend({ top: 52, bottom: 51, left: 52, right: 51, background: maskBg })\n .flatten({ background: maskBg })\n .png()\n .toFile(out('icon-mask.png'));\n written.push(out('icon-mask.png'));\n\n // Lossless crush of the larger PNGs (best-effort; needs oxipng on PATH).\n await Promise.all(\n ['icon-192.png', 'icon-512.png', 'apple-touch-icon.png', 'icon-mask.png'].map((image) =>\n optimizePng(out(image), optimize),\n ),\n );\n\n return written;\n}\n\n// ── Head tags + web manifest (the \"tag layer\" over the generated image files) ──\n\nexport interface FaviconLink {\n rel: string;\n href: string;\n type?: string;\n sizes?: string;\n}\n\nexport interface FaviconTagOptions {\n /** Whether a favicon.svg was emitted (source was an SVG). */\n hasSvg?: boolean;\n /** Include the `<link rel=\"manifest\">` (default true). */\n manifest?: boolean;\n /** URL base the favicon files are served from (default '' → site root). */\n base?: string;\n}\n\n/**\n * The ordered `<link>` data matching what `generateFavicons` writes. Pure — no\n * I/O — so it can drive an Astro `<Head />`, the CLI, or plain HTML.\n */\nexport function faviconLinks(opts: FaviconTagOptions = {}): FaviconLink[] {\n const base = (opts.base ?? '').replace(/\\/+$/, '');\n const href = (f: string) => `${base}/${f}`;\n const links: FaviconLink[] = [{ rel: 'icon', href: href('favicon.ico'), sizes: '32x32' }];\n if (opts.hasSvg) links.push({ rel: 'icon', type: 'image/svg+xml', href: href('favicon.svg') });\n links.push({ rel: 'icon', type: 'image/png', sizes: '32x32', href: href('icon-32.png') });\n links.push({ rel: 'apple-touch-icon', href: href('apple-touch-icon.png') });\n if (opts.manifest !== false) links.push({ rel: 'manifest', href: href('site.webmanifest') });\n return links;\n}\n\nexport interface WebManifestOptions {\n name: string;\n shortName?: string;\n themeColor?: string;\n backgroundColor?: string;\n /** URL base the icon files are served from (default '' → site root). */\n base?: string;\n}\n\n/** Build the web-app-manifest object (icons match `generateFavicons` output). */\nexport function faviconManifest(opts: WebManifestOptions): Record<string, unknown> {\n const base = (opts.base ?? '').replace(/\\/+$/, '');\n const src = (f: string) => `${base}/${f}`;\n return {\n name: opts.name,\n short_name: opts.shortName ?? opts.name,\n // `purpose` is stated on all three rather than left to default. An entry with\n // no purpose is implicitly \"any\", so omitting it worked — but with a maskable\n // present and nothing else claiming \"any\", some launchers picked the maskable\n // for slots that wanted a plain icon, i.e. the one with the safe-zone inset.\n icons: [\n { src: src('icon-192.png'), sizes: '192x192', type: 'image/png', purpose: 'any' },\n { src: src('icon-512.png'), sizes: '512x512', type: 'image/png', purpose: 'any' },\n { src: src('icon-mask.png'), sizes: '512x512', type: 'image/png', purpose: 'maskable' },\n ],\n theme_color: opts.themeColor ?? '#ffffff',\n background_color: opts.backgroundColor ?? '#ffffff',\n display: 'standalone',\n start_url: '/',\n };\n}\n\n/** Write `site.webmanifest` into `dir`. Returns the written path. */\nexport async function writeFaviconManifest(dir: string, opts: WebManifestOptions): Promise<string> {\n const path = join(dir.replace(/\\/+$/, ''), 'site.webmanifest');\n await writeFile(path, `${JSON.stringify(faviconManifest(opts), null, 2)}\\n`);\n return path;\n}\n"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -225,6 +225,16 @@ declare function organizationGraph(options: OrganizationGraphOptions): Record<st
|
|
|
225
225
|
* and map to the 'fa7' key. Other sets map to themselves.
|
|
226
226
|
*/
|
|
227
227
|
declare const prefixToMapKey: Record<string, string>;
|
|
228
|
+
/**
|
|
229
|
+
* Sets whose weights are a name SUFFIX inside one collection rather than
|
|
230
|
+
* separate prefixed collections. Phosphor is the case that forced this:
|
|
231
|
+
* `ph:lightning`, `ph:lightning-bold`, `ph:lightning-fill` all live in `ph`,
|
|
232
|
+
* whereas Font Awesome splits the same idea across `fa7-solid`/`fa7-regular`/…
|
|
233
|
+
* (which is what `prefixToMapKey` collapses).
|
|
234
|
+
*
|
|
235
|
+
* The first entry is the unsuffixed default — asking for it adds nothing.
|
|
236
|
+
*/
|
|
237
|
+
declare const WEIGHTED_SETS: Record<string, readonly string[]>;
|
|
228
238
|
declare const iconMap: {
|
|
229
239
|
readonly fa7: {
|
|
230
240
|
readonly menu: "bars";
|
|
@@ -232,12 +242,14 @@ declare const iconMap: {
|
|
|
232
242
|
readonly home: "home";
|
|
233
243
|
readonly settings: "gear";
|
|
234
244
|
readonly search: "magnifying-glass";
|
|
235
|
-
readonly 'expand-more': "chevron-down";
|
|
236
|
-
readonly 'expand-less': "chevron-up";
|
|
237
|
-
readonly 'chevron-right': "chevron-right";
|
|
238
245
|
readonly 'chevron-left': "chevron-left";
|
|
239
|
-
readonly '
|
|
240
|
-
readonly '
|
|
246
|
+
readonly 'chevron-right': "chevron-right";
|
|
247
|
+
readonly 'chevron-up': "chevron-up";
|
|
248
|
+
readonly 'chevron-down': "chevron-down";
|
|
249
|
+
readonly 'arrow-left': "arrow-left";
|
|
250
|
+
readonly 'arrow-right': "arrow-right";
|
|
251
|
+
readonly 'arrow-up': "arrow-up";
|
|
252
|
+
readonly 'arrow-down': "arrow-down";
|
|
241
253
|
readonly 'external-link': "arrow-up-right-from-square";
|
|
242
254
|
readonly 'more-vert': "ellipsis-vertical";
|
|
243
255
|
readonly 'more-horiz': "ellipsis";
|
|
@@ -255,8 +267,8 @@ declare const iconMap: {
|
|
|
255
267
|
readonly bookmark: "bookmark";
|
|
256
268
|
readonly favorite: "heart";
|
|
257
269
|
readonly star: "star";
|
|
258
|
-
readonly login: "
|
|
259
|
-
readonly logout: "
|
|
270
|
+
readonly login: "right-to-bracket";
|
|
271
|
+
readonly logout: "right-from-bracket";
|
|
260
272
|
readonly email: "envelope";
|
|
261
273
|
readonly phone: "phone";
|
|
262
274
|
readonly location: "location-dot";
|
|
@@ -275,7 +287,7 @@ declare const iconMap: {
|
|
|
275
287
|
readonly image: "image";
|
|
276
288
|
readonly export: "file-export";
|
|
277
289
|
readonly import: "file-import";
|
|
278
|
-
readonly backup: "
|
|
290
|
+
readonly backup: "cloud-arrow-up";
|
|
279
291
|
readonly compress: "compress";
|
|
280
292
|
readonly check: "check";
|
|
281
293
|
readonly error: "circle-exclamation";
|
|
@@ -310,6 +322,7 @@ declare const iconMap: {
|
|
|
310
322
|
readonly code: "code";
|
|
311
323
|
readonly palette: "palette";
|
|
312
324
|
readonly lightbulb: "lightbulb";
|
|
325
|
+
readonly lightning: "bolt";
|
|
313
326
|
};
|
|
314
327
|
readonly 'fa7-brands': {
|
|
315
328
|
readonly facebook: "facebook";
|
|
@@ -400,12 +413,14 @@ declare const iconMap: {
|
|
|
400
413
|
readonly home: "home";
|
|
401
414
|
readonly settings: "settings";
|
|
402
415
|
readonly search: "search";
|
|
403
|
-
readonly 'expand-more': "expand-more";
|
|
404
|
-
readonly 'expand-less': "expand-less";
|
|
405
|
-
readonly 'chevron-right': "chevron-right";
|
|
406
416
|
readonly 'chevron-left': "chevron-left";
|
|
407
|
-
readonly '
|
|
408
|
-
readonly '
|
|
417
|
+
readonly 'chevron-right': "chevron-right";
|
|
418
|
+
readonly 'chevron-up': "expand-less";
|
|
419
|
+
readonly 'chevron-down': "expand-more";
|
|
420
|
+
readonly 'arrow-left': "arrow-back";
|
|
421
|
+
readonly 'arrow-right': "arrow-forward";
|
|
422
|
+
readonly 'arrow-up': "arrow-upward";
|
|
423
|
+
readonly 'arrow-down': "arrow-downward";
|
|
409
424
|
readonly 'external-link': "open-in-new";
|
|
410
425
|
readonly 'more-vert': "more-vert";
|
|
411
426
|
readonly 'more-horiz': "more-horiz";
|
|
@@ -478,6 +493,7 @@ declare const iconMap: {
|
|
|
478
493
|
readonly code: "code";
|
|
479
494
|
readonly palette: "palette";
|
|
480
495
|
readonly lightbulb: "lightbulb";
|
|
496
|
+
readonly lightning: "bolt";
|
|
481
497
|
};
|
|
482
498
|
readonly lucide: {
|
|
483
499
|
readonly menu: "menu";
|
|
@@ -485,12 +501,14 @@ declare const iconMap: {
|
|
|
485
501
|
readonly home: "house";
|
|
486
502
|
readonly settings: "settings";
|
|
487
503
|
readonly search: "search";
|
|
488
|
-
readonly 'expand-more': "chevron-down";
|
|
489
|
-
readonly 'expand-less': "chevron-up";
|
|
490
|
-
readonly 'chevron-right': "chevron-right";
|
|
491
504
|
readonly 'chevron-left': "chevron-left";
|
|
492
|
-
readonly '
|
|
493
|
-
readonly '
|
|
505
|
+
readonly 'chevron-right': "chevron-right";
|
|
506
|
+
readonly 'chevron-up': "chevron-up";
|
|
507
|
+
readonly 'chevron-down': "chevron-down";
|
|
508
|
+
readonly 'arrow-left': "arrow-left";
|
|
509
|
+
readonly 'arrow-right': "arrow-right";
|
|
510
|
+
readonly 'arrow-up': "arrow-up";
|
|
511
|
+
readonly 'arrow-down': "arrow-down";
|
|
494
512
|
readonly 'external-link': "external-link";
|
|
495
513
|
readonly 'more-vert': "ellipsis-vertical";
|
|
496
514
|
readonly 'more-horiz': "ellipsis";
|
|
@@ -563,6 +581,95 @@ declare const iconMap: {
|
|
|
563
581
|
readonly code: "code";
|
|
564
582
|
readonly palette: "palette";
|
|
565
583
|
readonly lightbulb: "lightbulb";
|
|
584
|
+
readonly lightning: "zap";
|
|
585
|
+
};
|
|
586
|
+
readonly ph: {
|
|
587
|
+
readonly menu: "list";
|
|
588
|
+
readonly close: "x";
|
|
589
|
+
readonly home: "house";
|
|
590
|
+
readonly settings: "gear";
|
|
591
|
+
readonly search: "magnifying-glass";
|
|
592
|
+
readonly 'chevron-left': "caret-left";
|
|
593
|
+
readonly 'chevron-right': "caret-right";
|
|
594
|
+
readonly 'chevron-up': "caret-up";
|
|
595
|
+
readonly 'chevron-down': "caret-down";
|
|
596
|
+
readonly 'arrow-left': "arrow-left";
|
|
597
|
+
readonly 'arrow-right': "arrow-right";
|
|
598
|
+
readonly 'arrow-up': "arrow-up";
|
|
599
|
+
readonly 'arrow-down': "arrow-down";
|
|
600
|
+
readonly 'external-link': "arrow-square-out";
|
|
601
|
+
readonly 'more-vert': "dots-three-vertical";
|
|
602
|
+
readonly 'more-horiz': "dots-three";
|
|
603
|
+
readonly add: "plus";
|
|
604
|
+
readonly remove: "minus";
|
|
605
|
+
readonly delete: "trash";
|
|
606
|
+
readonly edit: "pencil";
|
|
607
|
+
readonly save: "floppy-disk";
|
|
608
|
+
readonly copy: "copy";
|
|
609
|
+
readonly paste: "clipboard";
|
|
610
|
+
readonly attach: "paperclip";
|
|
611
|
+
readonly upload: "upload";
|
|
612
|
+
readonly download: "download";
|
|
613
|
+
readonly share: "share";
|
|
614
|
+
readonly bookmark: "bookmark";
|
|
615
|
+
readonly favorite: "heart";
|
|
616
|
+
readonly star: "star";
|
|
617
|
+
readonly login: "sign-in";
|
|
618
|
+
readonly logout: "sign-out";
|
|
619
|
+
readonly email: "envelope";
|
|
620
|
+
readonly phone: "phone";
|
|
621
|
+
readonly location: "map-pin";
|
|
622
|
+
readonly globe: "globe";
|
|
623
|
+
readonly link: "link";
|
|
624
|
+
readonly clock: "clock";
|
|
625
|
+
readonly calendar: "calendar";
|
|
626
|
+
readonly schedule: "calendar-dots";
|
|
627
|
+
readonly person: "person";
|
|
628
|
+
readonly group: "users";
|
|
629
|
+
readonly file: "file";
|
|
630
|
+
readonly 'file-add': "file-plus";
|
|
631
|
+
readonly folder: "folder";
|
|
632
|
+
readonly 'folder-open': "folder-open";
|
|
633
|
+
readonly 'folder-add': "folder-plus";
|
|
634
|
+
readonly image: "image";
|
|
635
|
+
readonly export: "upload-simple";
|
|
636
|
+
readonly import: "download-simple";
|
|
637
|
+
readonly backup: "cloud-arrow-up";
|
|
638
|
+
readonly compress: "arrows-in";
|
|
639
|
+
readonly check: "check";
|
|
640
|
+
readonly error: "warning-circle";
|
|
641
|
+
readonly warning: "warning";
|
|
642
|
+
readonly info: "info";
|
|
643
|
+
readonly help: "question";
|
|
644
|
+
readonly cart: "shopping-cart";
|
|
645
|
+
readonly tag: "tag";
|
|
646
|
+
readonly 'credit-card': "credit-card";
|
|
647
|
+
readonly receipt: "receipt";
|
|
648
|
+
readonly leaf: "leaf";
|
|
649
|
+
readonly tree: "tree";
|
|
650
|
+
readonly seedling: "plant";
|
|
651
|
+
readonly trowel: "shovel";
|
|
652
|
+
readonly droplet: "drop";
|
|
653
|
+
readonly snowflake: "snowflake";
|
|
654
|
+
readonly sun: "sun";
|
|
655
|
+
readonly cloud: "cloud";
|
|
656
|
+
readonly grid: "squares-four";
|
|
657
|
+
readonly list: "list";
|
|
658
|
+
readonly filter: "funnel";
|
|
659
|
+
readonly sort: "arrows-down-up";
|
|
660
|
+
readonly fullscreen: "corners-out";
|
|
661
|
+
readonly collapse: "corners-in";
|
|
662
|
+
readonly building: "building";
|
|
663
|
+
readonly video: "video";
|
|
664
|
+
readonly lock: "lock";
|
|
665
|
+
readonly unlock: "lock-open";
|
|
666
|
+
readonly eye: "eye";
|
|
667
|
+
readonly 'eye-off': "eye-slash";
|
|
668
|
+
readonly print: "printer";
|
|
669
|
+
readonly code: "code";
|
|
670
|
+
readonly palette: "palette";
|
|
671
|
+
readonly lightbulb: "lightbulb";
|
|
672
|
+
readonly lightning: "lightning";
|
|
566
673
|
};
|
|
567
674
|
};
|
|
568
675
|
type IconSet = keyof typeof iconMap;
|
|
@@ -573,9 +680,15 @@ type BrandIcon = keyof (typeof iconMap)['simple-icons'];
|
|
|
573
680
|
* Names containing ':' are returned as-is (pass-through for fully-qualified names).
|
|
574
681
|
*
|
|
575
682
|
* @param name - Semantic name ('email') or fully-qualified ('fa7-solid:envelope')
|
|
576
|
-
* @param prefix - astro-icon prefix, e.g. 'fa7-solid', 'material-symbols', 'lucide'
|
|
683
|
+
* @param prefix - astro-icon prefix, e.g. 'fa7-solid', 'material-symbols', 'lucide', 'ph'
|
|
684
|
+
* @param opts.weight - Weight for suffix-weighted sets (see `WEIGHTED_SETS`), e.g.
|
|
685
|
+
* `resolveIcon('menu', 'ph', { weight: 'bold' })` → `'ph:list-bold'`. Ignored for
|
|
686
|
+
* sets that aren't suffix-weighted; an unknown weight throws rather than silently
|
|
687
|
+
* resolving to the regular glyph, which would be indistinguishable from a typo.
|
|
577
688
|
*/
|
|
578
|
-
declare function resolveIcon(name: string, prefix: string
|
|
689
|
+
declare function resolveIcon(name: string, prefix: string, opts?: {
|
|
690
|
+
weight?: string;
|
|
691
|
+
}): string;
|
|
579
692
|
/**
|
|
580
693
|
* Resolve a brand icon name to a fully-qualified astro-icon string.
|
|
581
694
|
* Names containing ':' are returned as-is (pass-through).
|
|
@@ -600,9 +713,91 @@ declare function resolveBrandIcon(name: string, prefix: string): string;
|
|
|
600
713
|
declare function generateIconInclude(iconsConfig?: {
|
|
601
714
|
ui?: string;
|
|
602
715
|
brand?: string;
|
|
716
|
+
weight?: string;
|
|
603
717
|
semantic?: string[];
|
|
604
718
|
[prefix: string]: string | string[] | undefined;
|
|
605
719
|
}): Record<string, string[]>;
|
|
606
720
|
//#endregion
|
|
607
|
-
|
|
721
|
+
//#region src/scan.d.ts
|
|
722
|
+
/** A file the scanner found, with its contents already read. */
|
|
723
|
+
interface SourceFile {
|
|
724
|
+
path: string;
|
|
725
|
+
text: string;
|
|
726
|
+
}
|
|
727
|
+
interface ScanOptions {
|
|
728
|
+
/** File extensions to read. Defaults to `SCAN_EXT`. */
|
|
729
|
+
exts?: Iterable<string>;
|
|
730
|
+
/** Directory names to skip entirely. Defaults to `SCAN_SKIP`. */
|
|
731
|
+
skipDirs?: Iterable<string>;
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* Extensions worth scanning: every template language the framework's classes
|
|
735
|
+
* and icon names can appear in, plus the markdown that can embed them.
|
|
736
|
+
*/
|
|
737
|
+
declare const SCAN_EXT: ReadonlySet<string>;
|
|
738
|
+
/** Directories that only ever hold dependencies or build output. */
|
|
739
|
+
declare const SCAN_SKIP: ReadonlySet<string>;
|
|
740
|
+
/**
|
|
741
|
+
* Recursively read every scannable file under `dir`.
|
|
742
|
+
*
|
|
743
|
+
* Dotfiles and dot-directories are skipped wholesale — they hold tooling config,
|
|
744
|
+
* not templates, and `.astro`/`.git` would otherwise be walked twice over.
|
|
745
|
+
*/
|
|
746
|
+
declare function scanFiles(dir: string, opts?: ScanOptions): SourceFile[];
|
|
747
|
+
//#endregion
|
|
748
|
+
//#region src/icons-scan.d.ts
|
|
749
|
+
/**
|
|
750
|
+
* Find the icons a consumer's source actually uses.
|
|
751
|
+
*
|
|
752
|
+
* This exists for one reason: bundle size under `output: 'server'`. astro-icon
|
|
753
|
+
* is zero-config for static builds, but on a server/hybrid build it bundles
|
|
754
|
+
* EVERY icon in a set unless given an `include` map — so consumers hand-maintain
|
|
755
|
+
* a list, and hand-maintained lists rot. Scanning derives it instead.
|
|
756
|
+
*
|
|
757
|
+
* The judgement call throughout is the same one `vitops lint`'s `extractClasses`
|
|
758
|
+
* makes, and for the same reason: a template hole (`name={expr}`) is not a typo
|
|
759
|
+
* and must not be guessed at. An unresolvable reference is REPORTED, never
|
|
760
|
+
* invented — the caller warns and asks the author to declare it. Quietly
|
|
761
|
+
* inferring would produce an `include` that is confidently wrong, which is worse
|
|
762
|
+
* than one that is honestly incomplete.
|
|
763
|
+
*/
|
|
764
|
+
/** How an icon reference was written. Useful for phrasing the warning. */
|
|
765
|
+
type IconRefKind = 'component' | 'prop' | 'object' | 'sprite';
|
|
766
|
+
/** A statically resolvable icon name. */
|
|
767
|
+
interface IconRef {
|
|
768
|
+
name: string;
|
|
769
|
+
kind: IconRefKind;
|
|
770
|
+
attr: string;
|
|
771
|
+
file: string;
|
|
772
|
+
line: number;
|
|
773
|
+
}
|
|
774
|
+
/** A reference whose name is computed at runtime and cannot be read statically. */
|
|
775
|
+
interface DynamicIconRef {
|
|
776
|
+
expr: string;
|
|
777
|
+
attr: string;
|
|
778
|
+
file: string;
|
|
779
|
+
line: number;
|
|
780
|
+
}
|
|
781
|
+
interface IconScanResult {
|
|
782
|
+
refs: IconRef[];
|
|
783
|
+
dynamic: DynamicIconRef[];
|
|
784
|
+
/** Unique static names, in first-seen order. */
|
|
785
|
+
names: string[];
|
|
786
|
+
}
|
|
787
|
+
interface IconScanOptions {
|
|
788
|
+
/** Extra prop names to treat as icon-bearing, beyond the defaults. */
|
|
789
|
+
props?: string[];
|
|
790
|
+
}
|
|
791
|
+
/** Extract every icon reference from one file's text. */
|
|
792
|
+
declare function extractIconRefs(src: string, file?: string, opts?: IconScanOptions): {
|
|
793
|
+
refs: IconRef[];
|
|
794
|
+
dynamic: DynamicIconRef[];
|
|
795
|
+
};
|
|
796
|
+
/** Run `extractIconRefs` across a file set and collect unique names. */
|
|
797
|
+
declare function collectIconRefs(files: readonly {
|
|
798
|
+
path: string;
|
|
799
|
+
text: string;
|
|
800
|
+
}[], opts?: IconScanOptions): IconScanResult;
|
|
801
|
+
//#endregion
|
|
802
|
+
export { type ArticleAuthor, type ArticleGraphOptions, type Attrs, type BrandIcon, type BreadcrumbGraphOptions, type BreadcrumbItem, type ChildNode, type ContentNode, type DynamicIconRef, type El, type Elmnt, type FAQGraphOptions, type FAQItem, type FaviconLink, type FaviconOptions, type FaviconTagOptions, type IconRef, type IconRefKind, type IconScanOptions, type IconScanResult, type IconSet, type ImageLink, type ImageRef, type Link, type Localizable, type OrganizationGraphOptions, SCAN_EXT, SCAN_SKIP, type ScanOptions, type SemanticIcon, type SourceFile, type StyleList, type StyleValue, type TextLink, WEIGHTED_SETS, type WebManifestOptions, articleGraph, breadcrumbGraph, collectIconRefs, extractIconRefs, faqGraph, faviconLinks, faviconManifest, generateFavicons, generateIconInclude, getAttribute, iconMap, isElmnt, isImageLink, isLink, isTextLink, nodesToHtml, organizationGraph, parseRenderedSlots, partAttrs, prefixToMapKey, resolveBrandIcon, resolveIcon, scanFiles, serialize, styleList, t, toHtml, writeFaviconManifest };
|
|
608
803
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/content.ts","../src/html.ts","../src/schema/article.ts","../src/schema/breadcrumb.ts","../src/schema/faq.ts","../src/schema/organization.ts","../src/icons.ts"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/content.ts","../src/html.ts","../src/schema/article.ts","../src/schema/breadcrumb.ts","../src/schema/faq.ts","../src/schema/organization.ts","../src/icons.ts","../src/scan.ts","../src/icons-scan.ts"],"mappings":"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"}
|