@robosophy/ui-vue 1.1.8 → 1.1.10
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/ai-context.md +8 -0
- package/components.md +95 -0
- package/dist/components/RsIcon/RsIcon.types.d.ts +1 -1
- package/dist/components/RsIcon/RsIcon.types.d.ts.map +1 -1
- package/dist/components/RsIcon/RsIcon.vue.d.ts.map +1 -1
- package/dist/icon-manifest.json +1 -1
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/dist/vite.d.ts +2 -1
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +289 -43
- package/dist/vite.js.map +1 -1
- package/icon-scanner.md +293 -0
- package/package.json +4 -2
package/dist/vite.js
CHANGED
|
@@ -19,6 +19,7 @@ const internalIconNames = [
|
|
|
19
19
|
const GITHUB_RAW = "https://raw.githubusercontent.com/google/material-design-icons/master/symbols/web";
|
|
20
20
|
const CACHE_BASE = join("node_modules", ".cache", "robosophy-svgs");
|
|
21
21
|
const BASE_OPSZ = 24;
|
|
22
|
+
const DEFAULT_WEIGHT = 400;
|
|
22
23
|
const GRADE_VARIANTS = [0, -25, 200];
|
|
23
24
|
function robosophyMaterialSymbols(options = {}) {
|
|
24
25
|
const raw = (options.outputDir ?? "").trim().replace(/^\/+/, "");
|
|
@@ -31,10 +32,10 @@ function robosophyMaterialSymbols(options = {}) {
|
|
|
31
32
|
function usageMapKey(usages) {
|
|
32
33
|
const parts = [];
|
|
33
34
|
for (const family of families) {
|
|
34
|
-
const
|
|
35
|
-
if (
|
|
36
|
-
|
|
37
|
-
}
|
|
35
|
+
const iconWeights = usages.get(family);
|
|
36
|
+
if (!iconWeights || iconWeights.size === 0) continue;
|
|
37
|
+
const entries = [...iconWeights.entries()].map(([name, weights]) => `${name}[${[...weights].sort().join(",")}]`).sort();
|
|
38
|
+
parts.push(`${family}:${entries.join(",")}`);
|
|
38
39
|
}
|
|
39
40
|
return parts.join("|") || "(empty)";
|
|
40
41
|
}
|
|
@@ -123,7 +124,7 @@ function robosophyMaterialSymbols(options = {}) {
|
|
|
123
124
|
}
|
|
124
125
|
};
|
|
125
126
|
}
|
|
126
|
-
function buildSvgVariants() {
|
|
127
|
+
function buildSvgVariants(weight = DEFAULT_WEIGHT) {
|
|
127
128
|
const variants = [];
|
|
128
129
|
for (const grade of GRADE_VARIANTS) {
|
|
129
130
|
const gradeSuffix = grade === 0 ? "" : grade > 0 ? `grad${grade}` : `gradN${Math.abs(grade)}`;
|
|
@@ -131,10 +132,12 @@ function buildSvgVariants() {
|
|
|
131
132
|
for (const fill of [false, true]) {
|
|
132
133
|
const fillSuffix = fill ? "fill1" : "";
|
|
133
134
|
const symbolFillSuffix = fill ? "-fill" : "";
|
|
134
|
-
const
|
|
135
|
+
const weightSuffix = weight !== DEFAULT_WEIGHT ? `wght${weight}` : "";
|
|
136
|
+
const weightSymbolSuffix = weight !== DEFAULT_WEIGHT ? `-wght${weight}` : "";
|
|
137
|
+
const parts = [gradeSuffix, fillSuffix, weightSuffix].filter(Boolean);
|
|
135
138
|
variants.push({
|
|
136
139
|
suffix: parts.length > 0 ? `${parts.join("")}_${BASE_OPSZ}px` : `${BASE_OPSZ}px`,
|
|
137
|
-
symbolSuffix: `${symbolGradeSuffix}${symbolFillSuffix}`
|
|
140
|
+
symbolSuffix: `${symbolGradeSuffix}${symbolFillSuffix}${weightSymbolSuffix}`
|
|
138
141
|
});
|
|
139
142
|
}
|
|
140
143
|
}
|
|
@@ -190,39 +193,44 @@ function parseSvgPaths(svgContent) {
|
|
|
190
193
|
async function generateSpriteAssets(usages, cacheDir, config) {
|
|
191
194
|
const symbols = [];
|
|
192
195
|
const iconClasses = [];
|
|
193
|
-
const variants = buildSvgVariants();
|
|
194
196
|
let totalFetched = 0;
|
|
195
197
|
let totalBytes = 0;
|
|
196
198
|
for (const family of families) {
|
|
197
|
-
const
|
|
198
|
-
if (
|
|
199
|
-
for (const name of
|
|
200
|
-
for (const
|
|
201
|
-
const
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
svgContent = await
|
|
207
|
-
if (!svgContent)
|
|
208
|
-
|
|
209
|
-
|
|
199
|
+
const iconWeights = usages.get(family);
|
|
200
|
+
if (!iconWeights || iconWeights.size === 0) continue;
|
|
201
|
+
for (const [name, weights] of [...iconWeights.entries()].sort()) {
|
|
202
|
+
for (const weight of [...weights].sort()) {
|
|
203
|
+
const variants = buildSvgVariants(weight);
|
|
204
|
+
for (const variant of variants) {
|
|
205
|
+
const symbolId = buildSymbolId(name, family, variant.symbolSuffix);
|
|
206
|
+
const url = buildSvgUrl(name, family, variant.suffix);
|
|
207
|
+
const cacheKey = createHash("sha256").update(url).digest("hex").slice(0, 12);
|
|
208
|
+
let svgContent = cacheDir ? await loadSvgFromCache(cacheDir, cacheKey) : null;
|
|
209
|
+
if (!svgContent) {
|
|
210
|
+
svgContent = await fetchSvg(url);
|
|
211
|
+
if (!svgContent) continue;
|
|
212
|
+
if (cacheDir) {
|
|
213
|
+
await saveSvgToCache(cacheDir, cacheKey, svgContent);
|
|
214
|
+
}
|
|
210
215
|
}
|
|
216
|
+
const pathContent = parseSvgPaths(svgContent);
|
|
217
|
+
if (!pathContent) continue;
|
|
218
|
+
symbols.push(
|
|
219
|
+
`<symbol id="${symbolId}" viewBox="0 -960 960 960" fill="currentColor">${pathContent}</symbol>`
|
|
220
|
+
);
|
|
221
|
+
totalFetched++;
|
|
222
|
+
totalBytes += svgContent.length;
|
|
211
223
|
}
|
|
212
|
-
const pathContent = parseSvgPaths(svgContent);
|
|
213
|
-
if (!pathContent) continue;
|
|
214
|
-
symbols.push(
|
|
215
|
-
`<symbol id="${symbolId}" viewBox="0 -960 960 960" fill="currentColor">${pathContent}</symbol>`
|
|
216
|
-
);
|
|
217
|
-
totalFetched++;
|
|
218
|
-
totalBytes += svgContent.length;
|
|
219
224
|
}
|
|
220
225
|
}
|
|
221
226
|
}
|
|
222
227
|
const iconNames = /* @__PURE__ */ new Set();
|
|
223
228
|
for (const family of families) {
|
|
224
|
-
|
|
225
|
-
|
|
229
|
+
const iconWeights = usages.get(family);
|
|
230
|
+
if (iconWeights) {
|
|
231
|
+
for (const name of iconWeights.keys()) {
|
|
232
|
+
iconNames.add(name);
|
|
233
|
+
}
|
|
226
234
|
}
|
|
227
235
|
}
|
|
228
236
|
for (const name of [...iconNames].sort()) {
|
|
@@ -231,7 +239,7 @@ async function generateSpriteAssets(usages, cacheDir, config) {
|
|
|
231
239
|
const spriteContent = `<defs>${symbols.join("")}</defs>`;
|
|
232
240
|
const fullSprite = `<svg xmlns="http://www.w3.org/2000/svg" style="display:none" aria-hidden="true">${spriteContent}</svg>`;
|
|
233
241
|
const css = iconClasses.join("\n");
|
|
234
|
-
const totalIcons = [...usages.values()].reduce((sum,
|
|
242
|
+
const totalIcons = [...usages.values()].reduce((sum, m) => sum + m.size, 0);
|
|
235
243
|
if (totalIcons > 0) {
|
|
236
244
|
const summary = formatDetectedMaterialSymbols(usages);
|
|
237
245
|
config.logger.info(
|
|
@@ -266,7 +274,14 @@ async function collectMaterialSymbolUsages(config, options = {}) {
|
|
|
266
274
|
}
|
|
267
275
|
}
|
|
268
276
|
for (const icon of options.include ?? []) {
|
|
269
|
-
|
|
277
|
+
const resolved = typeof icon === "string" ? { family: defaultFamily, name: icon } : icon;
|
|
278
|
+
if (resolved.weight !== void 0) {
|
|
279
|
+
addUsage(usages, resolved);
|
|
280
|
+
} else {
|
|
281
|
+
for (const w of VALID_WEIGHTS) {
|
|
282
|
+
addUsage(usages, { ...resolved, weight: w });
|
|
283
|
+
}
|
|
284
|
+
}
|
|
270
285
|
}
|
|
271
286
|
if (options.scan !== false) {
|
|
272
287
|
const roots = options.roots ?? [join(config.root, "src")];
|
|
@@ -289,6 +304,121 @@ function buildMaterialSymbolsCss(iconClasses) {
|
|
|
289
304
|
}
|
|
290
305
|
];
|
|
291
306
|
}
|
|
307
|
+
function skipStringBackward(source, pos, quote) {
|
|
308
|
+
pos--;
|
|
309
|
+
while (pos >= 0) {
|
|
310
|
+
if (source[pos] === "\\") {
|
|
311
|
+
pos -= 2;
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
if (source[pos] === quote) {
|
|
315
|
+
let backslashCount = 0;
|
|
316
|
+
let k = pos - 1;
|
|
317
|
+
while (k >= 0 && source[k] === "\\") {
|
|
318
|
+
backslashCount++;
|
|
319
|
+
k--;
|
|
320
|
+
}
|
|
321
|
+
if (backslashCount % 2 === 1) {
|
|
322
|
+
pos = pos - backslashCount - 1;
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
return pos - 1;
|
|
326
|
+
}
|
|
327
|
+
pos--;
|
|
328
|
+
}
|
|
329
|
+
return -1;
|
|
330
|
+
}
|
|
331
|
+
function skipStringForward(source, pos, quote) {
|
|
332
|
+
pos++;
|
|
333
|
+
while (pos < source.length) {
|
|
334
|
+
if (source[pos] === "\\") {
|
|
335
|
+
pos += 2;
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
if (source[pos] === quote) {
|
|
339
|
+
return pos + 1;
|
|
340
|
+
}
|
|
341
|
+
pos++;
|
|
342
|
+
}
|
|
343
|
+
return source.length;
|
|
344
|
+
}
|
|
345
|
+
function findEnclosingObject(source, fromIndex) {
|
|
346
|
+
let depth = 0;
|
|
347
|
+
let i = fromIndex;
|
|
348
|
+
while (i >= 0) {
|
|
349
|
+
const char = source[i];
|
|
350
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
351
|
+
i = skipStringBackward(source, i, char);
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
if (char === "/" && i > 0 && source[i - 1] === "/") {
|
|
355
|
+
i -= 2;
|
|
356
|
+
while (i >= 0 && source[i] !== "\n") i--;
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
if (char === "/" && i > 0 && source[i - 1] === "*") {
|
|
360
|
+
i -= 2;
|
|
361
|
+
while (i >= 0) {
|
|
362
|
+
if (source[i] === "/" && i + 1 < source.length && source[i + 1] === "*") {
|
|
363
|
+
i--;
|
|
364
|
+
break;
|
|
365
|
+
}
|
|
366
|
+
i--;
|
|
367
|
+
}
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
if (char === "}") {
|
|
371
|
+
depth++;
|
|
372
|
+
} else if (char === "{") {
|
|
373
|
+
if (depth === 0) {
|
|
374
|
+
const start = i;
|
|
375
|
+
let j = i + 1;
|
|
376
|
+
let innerDepth = 1;
|
|
377
|
+
while (j < source.length) {
|
|
378
|
+
const c = source[j];
|
|
379
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
380
|
+
j = skipStringForward(source, j, c);
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
if (c === "/") {
|
|
384
|
+
if (j + 1 < source.length && source[j + 1] === "/") {
|
|
385
|
+
j += 2;
|
|
386
|
+
while (j < source.length && source[j] !== "\n") j++;
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
if (j + 1 < source.length && source[j + 1] === "*") {
|
|
390
|
+
j += 2;
|
|
391
|
+
while (j + 1 < source.length) {
|
|
392
|
+
if (source[j] === "*" && source[j + 1] === "/") {
|
|
393
|
+
j += 2;
|
|
394
|
+
break;
|
|
395
|
+
}
|
|
396
|
+
j++;
|
|
397
|
+
}
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
if (c === "{") innerDepth++;
|
|
402
|
+
else if (c === "}") {
|
|
403
|
+
innerDepth--;
|
|
404
|
+
if (innerDepth === 0) {
|
|
405
|
+
return {
|
|
406
|
+
start,
|
|
407
|
+
end: j,
|
|
408
|
+
body: source.slice(start + 1, j)
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
j++;
|
|
413
|
+
}
|
|
414
|
+
return null;
|
|
415
|
+
}
|
|
416
|
+
depth--;
|
|
417
|
+
}
|
|
418
|
+
i--;
|
|
419
|
+
}
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
292
422
|
function collectFromSource(source, usages) {
|
|
293
423
|
const rsIconTagPattern = /<RsIcon\b([^>]*)>/g;
|
|
294
424
|
let tagMatch;
|
|
@@ -297,12 +427,16 @@ function collectFromSource(source, usages) {
|
|
|
297
427
|
const rawName = attrs.name ?? attrs[":name"];
|
|
298
428
|
const hasFamily = "family" in attrs || ":family" in attrs;
|
|
299
429
|
const rawFamily = attrs.family ?? attrs[":family"] ?? "";
|
|
430
|
+
const rawWeight = attrs.weight ?? attrs[":weight"] ?? "";
|
|
431
|
+
const weight = rawWeight ? parseInt(rawWeight, 10) : DEFAULT_WEIGHT;
|
|
432
|
+
const resolvedWeight = !isNaN(weight) && weight > 0 ? weight : DEFAULT_WEIGHT;
|
|
300
433
|
if (rawName) {
|
|
434
|
+
const isNameDynamic = ":name" in attrs;
|
|
301
435
|
const familyList = resolveFamilies(rawFamily, hasFamily);
|
|
302
|
-
const names = resolveNames(rawName);
|
|
436
|
+
const names = resolveNames(rawName, isNameDynamic);
|
|
303
437
|
for (const family of familyList) {
|
|
304
438
|
for (const name of names) {
|
|
305
|
-
addUsage(usages, { family, name });
|
|
439
|
+
addUsage(usages, { family, name, weight: resolvedWeight });
|
|
306
440
|
}
|
|
307
441
|
}
|
|
308
442
|
}
|
|
@@ -319,11 +453,107 @@ function collectFromSource(source, usages) {
|
|
|
319
453
|
const objectIconPattern = /\bicon\s*:\s*["']([a-z0-9_]+)["']/g;
|
|
320
454
|
let objectMatch;
|
|
321
455
|
while (objectMatch = objectIconPattern.exec(source)) {
|
|
456
|
+
const name = objectMatch[1] ?? "";
|
|
457
|
+
const obj = findEnclosingObject(source, objectMatch.index);
|
|
458
|
+
if (obj) {
|
|
459
|
+
const cleanBody = obj.body.replace(/\/\/.*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
460
|
+
const weightMatch = cleanBody.match(/\bweight\s*:\s*(\d+)/);
|
|
461
|
+
const familyMatch = cleanBody.match(/\bfamily\s*:\s*["'](\w+)["']/);
|
|
462
|
+
addUsage(usages, {
|
|
463
|
+
family: familyMatch ? familyMatch[1] : defaultFamily,
|
|
464
|
+
name,
|
|
465
|
+
weight: weightMatch ? parseInt(weightMatch[1], 10) : void 0
|
|
466
|
+
});
|
|
467
|
+
} else {
|
|
468
|
+
addUsage(usages, { family: defaultFamily, name });
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
const magicCommentPattern = /\/\/\s*@robosophy-icon:\s*([a-z0-9_]+)/g;
|
|
472
|
+
let magicMatch;
|
|
473
|
+
while (magicMatch = magicCommentPattern.exec(source)) {
|
|
474
|
+
const name = magicMatch[1] ?? "";
|
|
475
|
+
const lineEnd = source.indexOf("\n", magicMatch.index);
|
|
476
|
+
const line = lineEnd === -1 ? source.slice(magicMatch.index) : source.slice(magicMatch.index, lineEnd);
|
|
477
|
+
const familyMatch = line.match(/\bfamily\s*=\s*["']?(\w+)["']?/);
|
|
478
|
+
const weightMatch = line.match(/\bweight\s*=\s*(\d+)/);
|
|
322
479
|
addUsage(usages, {
|
|
323
|
-
family: defaultFamily,
|
|
324
|
-
name
|
|
480
|
+
family: familyMatch ? familyMatch[1] : defaultFamily,
|
|
481
|
+
name,
|
|
482
|
+
weight: weightMatch ? parseInt(weightMatch[1], 10) : void 0
|
|
325
483
|
});
|
|
326
484
|
}
|
|
485
|
+
const iconArrayPattern = /(?:const|let|var)\s+(\w*[Ii]con\w*)\s*=\s*\[/g;
|
|
486
|
+
let arrayMatch;
|
|
487
|
+
while (arrayMatch = iconArrayPattern.exec(source)) {
|
|
488
|
+
const bracketStart = arrayMatch.index + arrayMatch[0].length - 1;
|
|
489
|
+
let depth = 1;
|
|
490
|
+
let j = bracketStart + 1;
|
|
491
|
+
while (j < source.length) {
|
|
492
|
+
const c = source[j];
|
|
493
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
494
|
+
j = skipStringForward(source, j, c);
|
|
495
|
+
continue;
|
|
496
|
+
}
|
|
497
|
+
if (c === "/") {
|
|
498
|
+
if (j + 1 < source.length && source[j + 1] === "/") {
|
|
499
|
+
j += 2;
|
|
500
|
+
while (j < source.length && source[j] !== "\n") j++;
|
|
501
|
+
continue;
|
|
502
|
+
}
|
|
503
|
+
if (j + 1 < source.length && source[j + 1] === "*") {
|
|
504
|
+
j += 2;
|
|
505
|
+
while (j + 1 < source.length) {
|
|
506
|
+
if (source[j] === "*" && source[j + 1] === "/") {
|
|
507
|
+
j += 2;
|
|
508
|
+
break;
|
|
509
|
+
}
|
|
510
|
+
j++;
|
|
511
|
+
}
|
|
512
|
+
continue;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
if (c === "[") depth++;
|
|
516
|
+
else if (c === "]") {
|
|
517
|
+
depth--;
|
|
518
|
+
if (depth === 0) break;
|
|
519
|
+
}
|
|
520
|
+
j++;
|
|
521
|
+
}
|
|
522
|
+
if (depth === 0) {
|
|
523
|
+
const arrayContent = source.slice(bracketStart + 1, j);
|
|
524
|
+
let braceDepth = 0;
|
|
525
|
+
let k = 0;
|
|
526
|
+
while (k < arrayContent.length) {
|
|
527
|
+
const c = arrayContent[k];
|
|
528
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
529
|
+
if (braceDepth === 0) {
|
|
530
|
+
const quote = c;
|
|
531
|
+
let strEnd = k + 1;
|
|
532
|
+
while (strEnd < arrayContent.length) {
|
|
533
|
+
if (arrayContent[strEnd] === "\\") {
|
|
534
|
+
strEnd += 2;
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
if (arrayContent[strEnd] === quote) break;
|
|
538
|
+
strEnd++;
|
|
539
|
+
}
|
|
540
|
+
const iconName = arrayContent.slice(k + 1, strEnd);
|
|
541
|
+
if (iconNamePattern.test(iconName)) {
|
|
542
|
+
addUsage(usages, { family: defaultFamily, name: iconName });
|
|
543
|
+
}
|
|
544
|
+
k = strEnd + 1;
|
|
545
|
+
continue;
|
|
546
|
+
} else {
|
|
547
|
+
k = skipStringForward(arrayContent, k, c);
|
|
548
|
+
continue;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
if (c === "{") braceDepth++;
|
|
552
|
+
else if (c === "}") braceDepth--;
|
|
553
|
+
k++;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
327
557
|
}
|
|
328
558
|
function parseStaticAttributes(source) {
|
|
329
559
|
const attrs = {};
|
|
@@ -335,15 +565,25 @@ function parseStaticAttributes(source) {
|
|
|
335
565
|
return attrs;
|
|
336
566
|
}
|
|
337
567
|
function unwrapStaticValue(value) {
|
|
338
|
-
return value.replace(/^['"](.+)['"]$/, "$1");
|
|
568
|
+
return value.replace(/^['"`](.+)['"`]$/, "$1");
|
|
339
569
|
}
|
|
570
|
+
const VALID_WEIGHTS = [100, 200, 300, 400, 500, 600, 700];
|
|
340
571
|
function addUsage(usages, icon) {
|
|
341
572
|
const family = icon.family ?? defaultFamily;
|
|
342
573
|
const name = icon.name.trim();
|
|
574
|
+
const weight = icon.weight ?? DEFAULT_WEIGHT;
|
|
343
575
|
if (!families.includes(family) || !iconNamePattern.test(name)) {
|
|
344
576
|
return;
|
|
345
577
|
}
|
|
346
|
-
|
|
578
|
+
if (!VALID_WEIGHTS.includes(weight)) return;
|
|
579
|
+
const iconMap = usages.get(family);
|
|
580
|
+
if (!iconMap) return;
|
|
581
|
+
const existing = iconMap.get(name);
|
|
582
|
+
if (existing) {
|
|
583
|
+
existing.add(weight);
|
|
584
|
+
} else {
|
|
585
|
+
iconMap.set(name, /* @__PURE__ */ new Set([weight]));
|
|
586
|
+
}
|
|
347
587
|
}
|
|
348
588
|
async function loadIconManifest() {
|
|
349
589
|
try {
|
|
@@ -359,8 +599,8 @@ function toFamily(value) {
|
|
|
359
599
|
const normalized = value ? unwrapStaticValue(value) : "";
|
|
360
600
|
return families.includes(normalized) ? normalized : void 0;
|
|
361
601
|
}
|
|
362
|
-
function resolveNames(rawName) {
|
|
363
|
-
const stringLiterals = /["']([a-z0-9_]+)["']/g;
|
|
602
|
+
function resolveNames(rawName, isDynamic = false) {
|
|
603
|
+
const stringLiterals = /["'`]([a-z0-9_]+)["'`]/g;
|
|
364
604
|
let strMatch;
|
|
365
605
|
const names = [];
|
|
366
606
|
while (strMatch = stringLiterals.exec(rawName)) {
|
|
@@ -370,6 +610,7 @@ function resolveNames(rawName) {
|
|
|
370
610
|
}
|
|
371
611
|
}
|
|
372
612
|
if (names.length === 0) {
|
|
613
|
+
if (isDynamic) return names;
|
|
373
614
|
const name = unwrapStaticValue(rawName);
|
|
374
615
|
if (iconNamePattern.test(name)) {
|
|
375
616
|
names.push(name);
|
|
@@ -380,7 +621,7 @@ function resolveNames(rawName) {
|
|
|
380
621
|
function resolveFamilies(rawFamily, hasFamily = true) {
|
|
381
622
|
const family = toFamily(rawFamily);
|
|
382
623
|
if (family) return [family];
|
|
383
|
-
const stringLiterals = /["'](\w+)["']/g;
|
|
624
|
+
const stringLiterals = /["'`](\w+)["'`]/g;
|
|
384
625
|
let strMatch;
|
|
385
626
|
const found = /* @__PURE__ */ new Set();
|
|
386
627
|
while (strMatch = stringLiterals.exec(rawFamily)) {
|
|
@@ -395,7 +636,7 @@ function resolveFamilies(rawFamily, hasFamily = true) {
|
|
|
395
636
|
return [...families];
|
|
396
637
|
}
|
|
397
638
|
function createUsageMap() {
|
|
398
|
-
return new Map(families.map((family) => [family, /* @__PURE__ */ new
|
|
639
|
+
return new Map(families.map((family) => [family, /* @__PURE__ */ new Map()]));
|
|
399
640
|
}
|
|
400
641
|
async function listSourceFiles(root) {
|
|
401
642
|
try {
|
|
@@ -415,7 +656,12 @@ async function listSourceFiles(root) {
|
|
|
415
656
|
}
|
|
416
657
|
}
|
|
417
658
|
function formatDetectedMaterialSymbols(usages) {
|
|
418
|
-
return families.map((family) =>
|
|
659
|
+
return families.map((family) => {
|
|
660
|
+
const iconWeights = usages.get(family);
|
|
661
|
+
if (!iconWeights || iconWeights.size === 0) return `${family}: (none)`;
|
|
662
|
+
const entries = [...iconWeights.entries()].map(([name, weights]) => `${name}[${[...weights].sort().join(",")}]`).sort().join(", ");
|
|
663
|
+
return `${family}: ${entries}`;
|
|
664
|
+
}).join("\n");
|
|
419
665
|
}
|
|
420
666
|
export {
|
|
421
667
|
buildMaterialSymbolsCss,
|
package/dist/vite.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.js","sources":["../src/vite.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { mkdir, readFile, readdir, writeFile } from \"node:fs/promises\";\nimport { extname, join, sep } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { HtmlTagDescriptor, IndexHtmlTransformResult, Plugin, ResolvedConfig } from \"vite\";\n\nimport type { RsIconFamily } from \"./components/RsIcon\";\n\ntype IconInput = string | { family?: RsIconFamily; name: string };\nexport type RsIconFontDisplay = \"block\" | \"swap\" | \"fallback\" | \"optional\";\n\nexport type RobosophyMaterialSymbolsOptions = {\n outputDir?: string;\n fontDisplay?: RsIconFontDisplay;\n fontVariant?: string;\n include?: IconInput[];\n preload?: boolean;\n roots?: string[];\n scan?: boolean;\n};\n\ntype IconUsageMap = Map<RsIconFamily, Set<string>>;\n\nconst families = [\"outlined\", \"rounded\", \"sharp\"] as const satisfies readonly RsIconFamily[];\nconst defaultFamily: RsIconFamily = \"outlined\";\nconst iconNamePattern = /^[a-z0-9_]+$/;\nconst sourceExtensions = new Set([\".js\", \".jsx\", \".mjs\", \".ts\", \".tsx\", \".vue\"]);\nconst skippedDirs = new Set([\".git\", \"dist\", \"node_modules\", \"storybook-static\"]);\nconst internalIconNames = [\n \"arrow_drop_down\",\n \"arrow_drop_up\",\n \"arrow_left\",\n \"chevron_right\",\n \"close\",\n \"login\",\n \"nest_eco_leaf\",\n];\n\nconst GITHUB_RAW =\n \"https://raw.githubusercontent.com/google/material-design-icons/master/symbols/web\";\nconst CACHE_BASE = join(\"node_modules\", \".cache\", \"robosophy-svgs\");\nconst BASE_OPSZ = 24;\nconst DEFAULT_WEIGHT = 400;\n\nconst GRADE_VARIANTS = [0, -25, 200] as const;\n\nexport function robosophyMaterialSymbols(\n options: RobosophyMaterialSymbolsOptions = {},\n): Plugin {\n const raw = (options.outputDir ?? \"\").trim().replace(/^\\/+/, \"\");\n const outputDir = raw\n .split(\"/\")\n .filter((part) => part && part !== \"..\")\n .join(\"/\") || \"assets\";\n let config: ResolvedConfig;\n let cacheDir: string;\n let cachedAssets: GeneratedMaterialSymbolsAssets | null = null;\n let cachedUsagesKey = \"\";\n let needsRegeneration = true;\n\n function usageMapKey(usages: IconUsageMap): string {\n const parts: string[] = [];\n for (const family of families) {\n const names = [...(usages.get(family) ?? [])].sort();\n if (names.length > 0) {\n parts.push(`${family}:${names.join(\",\")}`);\n }\n }\n return parts.join(\"|\") || \"(empty)\";\n }\n\n async function getAssets(): Promise<GeneratedMaterialSymbolsAssets> {\n if (!needsRegeneration && cachedAssets) return cachedAssets;\n\n const usages = await collectMaterialSymbolUsages(config, options);\n const newKey = usageMapKey(usages);\n\n if (newKey === cachedUsagesKey && cachedAssets) {\n needsRegeneration = false;\n return cachedAssets;\n }\n\n if (config.command !== \"build\" && cachedUsagesKey !== \"\") {\n config.logger.info(\n \"[robosophy-material-symbols] icon usage changed, regenerating SVG sprite\",\n );\n }\n\n cachedUsagesKey = newKey;\n cachedAssets = await ensureGeneratedAssets(config, options, cacheDir);\n needsRegeneration = false;\n return cachedAssets;\n }\n\n return {\n name: \"robosophy-material-symbols\",\n async configResolved(resolvedConfig) {\n config = resolvedConfig;\n cacheDir = join(config.root, CACHE_BASE);\n await mkdir(cacheDir, { recursive: true });\n },\n async buildStart() {\n if (config.command === \"serve\" || config.command === \"build\") {\n await getAssets();\n }\n },\n async transformIndexHtml(): Promise<IndexHtmlTransformResult> {\n const assets = await getAssets();\n\n const tag: HtmlTagDescriptor = {\n tag: \"svg\",\n attrs: {\n xmlns: \"http://www.w3.org/2000/svg\",\n style: \"display:none;\",\n \"aria-hidden\": \"true\",\n },\n children: assets.spriteContent,\n injectTo: \"body-prepend\",\n };\n\n return [tag, ...buildMaterialSymbolsCss(assets.css)];\n },\n configureServer(server) {\n server.watcher.on(\"all\", (_event, file) => {\n if (sourceExtensions.has(extname(file))) {\n needsRegeneration = true;\n }\n });\n server.middlewares.use(async (request, response, next) => {\n if (!request.url?.startsWith(\"/@robosophy-material-symbols/\")) {\n next();\n return;\n }\n\n try {\n const assets = await getAssets();\n const fileName = decodeURIComponent(\n request.url.replace(\"/@robosophy-material-symbols/\", \"\").split(\"?\")[0] ?? \"\",\n );\n\n if (fileName === \"rs-material-symbols.svg\") {\n response.setHeader(\"Content-Type\", \"image/svg+xml; charset=utf-8\");\n response.setHeader(\"Cache-Control\", \"no-cache\");\n response.end(assets.fullSprite);\n return;\n }\n\n next();\n } catch (error) {\n next(error);\n }\n });\n },\n async generateBundle(_outputOptions) {\n const assets = await getAssets();\n\n if (assets.fullSprite) {\n this.emitFile({\n fileName: `${outputDir}/rs-material-symbols.svg`,\n name: \"rs-material-symbols.svg\",\n source: assets.fullSprite,\n type: \"asset\",\n });\n }\n },\n };\n}\n\ntype GeneratedMaterialSymbolsAssets = {\n fullSprite: string;\n spriteContent: string;\n css: string;\n};\n\ntype SvgVariant = {\n suffix: string;\n symbolSuffix: string;\n};\n\nfunction buildSvgVariants(): SvgVariant[] {\n const variants: SvgVariant[] = [];\n for (const grade of GRADE_VARIANTS) {\n const gradeSuffix = grade === 0 ? \"\" : grade > 0 ? `grad${grade}` : `gradN${Math.abs(grade)}`;\n const symbolGradeSuffix = grade === 0 ? \"\" : `-${gradeSuffix}`;\n\n for (const fill of [false, true]) {\n const fillSuffix = fill ? \"fill1\" : \"\";\n const symbolFillSuffix = fill ? \"-fill\" : \"\";\n const parts = [gradeSuffix, fillSuffix].filter(Boolean);\n\n variants.push({\n suffix: parts.length > 0 ? `${parts.join(\"\")}_${BASE_OPSZ}px` : `${BASE_OPSZ}px`,\n symbolSuffix: `${symbolGradeSuffix}${symbolFillSuffix}`,\n });\n }\n }\n return variants;\n}\n\nfunction buildSvgUrl(name: string, family: RsIconFamily, suffix: string): string {\n const style = family === \"outlined\" ? \"materialsymbolsoutlined\"\n : family === \"rounded\" ? \"materialsymbolsrounded\"\n : \"materialsymbolssharp\";\n return `${GITHUB_RAW}/${name.toLowerCase()}/${style}/${name.toLowerCase()}_${suffix}.svg`;\n}\n\nfunction buildSymbolId(name: string, family: RsIconFamily, symbolSuffix: string): string {\n return `rs-icon-${family}-${name}${symbolSuffix}`;\n}\n\nasync function fetchSvg(url: string): Promise<string | null> {\n try {\n const response = await fetch(url);\n if (!response.ok) return null;\n return await response.text();\n } catch {\n return null;\n }\n}\n\nasync function loadSvgFromCache(cacheDir: string, cacheKey: string): Promise<string | null> {\n const cachePath = join(cacheDir, `${cacheKey}.svg`);\n try {\n return await readFile(cachePath, \"utf8\");\n } catch {\n return null;\n }\n}\n\nasync function saveSvgToCache(cacheDir: string, cacheKey: string, content: string): Promise<void> {\n const cachePath = join(cacheDir, `${cacheKey}.svg`);\n try {\n await writeFile(cachePath, content, \"utf8\");\n } catch {\n // Ignore cache write errors\n }\n}\n\nfunction parseSvgPaths(svgContent: string): string | null {\n const viewBoxMatch = svgContent.match(/viewBox=\"([^\"]+)\"/i);\n if (!viewBoxMatch) return null;\n\n const paths: string[] = [];\n const pathRegex = /<path\\s+([^>]*)>/g;\n let pathMatch: RegExpExecArray | null;\n\n while ((pathMatch = pathRegex.exec(svgContent))) {\n const attrs = pathMatch[1] ?? \"\";\n const dMatch = attrs.match(/d=\"([^\"]*)\"/);\n if (dMatch) {\n paths.push(dMatch[1] ?? \"\");\n }\n }\n\n if (paths.length === 0) return null;\n\n return paths\n .map((d) => `<path fill=\"currentColor\" d=\"${d}\"/>`)\n .join(\"\");\n}\n\nasync function generateSpriteAssets(\n usages: IconUsageMap,\n cacheDir: string,\n config: ResolvedConfig,\n): Promise<GeneratedMaterialSymbolsAssets> {\n const symbols: string[] = [];\n const iconClasses: string[] = [];\n const variants = buildSvgVariants();\n let totalFetched = 0;\n let totalBytes = 0;\n\n for (const family of families) {\n const names = [...(usages.get(family) ?? [])].sort();\n if (names.length === 0) continue;\n\n for (const name of names) {\n for (const variant of variants) {\n const symbolId = buildSymbolId(name, family, variant.symbolSuffix);\n const url = buildSvgUrl(name, family, variant.suffix);\n const cacheKey = createHash(\"sha256\")\n .update(url)\n .digest(\"hex\")\n .slice(0, 12);\n\n let svgContent = cacheDir ? await loadSvgFromCache(cacheDir, cacheKey) : null;\n\n if (!svgContent) {\n svgContent = await fetchSvg(url);\n if (!svgContent) continue;\n\n if (cacheDir) {\n await saveSvgToCache(cacheDir, cacheKey, svgContent);\n }\n }\n\n const pathContent = parseSvgPaths(svgContent);\n if (!pathContent) continue;\n\n symbols.push(\n `<symbol id=\"${symbolId}\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">${pathContent}</symbol>`,\n );\n\n totalFetched++;\n totalBytes += svgContent.length;\n }\n }\n }\n\n const iconNames = new Set<string>();\n for (const family of families) {\n for (const name of usages.get(family) ?? []) {\n iconNames.add(name);\n }\n }\n for (const name of [...iconNames].sort()) {\n iconClasses.push(`.rs-icon-${name} { --rs-icon-content: \"${name}\"; }`);\n }\n\n const spriteContent = `<defs>${symbols.join(\"\")}</defs>`;\n const fullSprite = `<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display:none\" aria-hidden=\"true\">${spriteContent}</svg>`;\n const css = iconClasses.join(\"\\n\");\n\n const totalIcons = [...usages.values()].reduce((sum, s) => sum + s.size, 0);\n if (totalIcons > 0) {\n const summary = formatDetectedMaterialSymbols(usages);\n config.logger.info(\n `[robosophy-material-symbols] ${totalIcons} icons detected, ${totalFetched} SVG variants (${(totalBytes / 1024).toFixed(1)} KB)\\n${summary}`,\n );\n } else {\n config.logger.warn(\n \"[robosophy-material-symbols] No Material Symbols icons detected in source. Add them via the include option.\",\n );\n }\n\n return { fullSprite, spriteContent, css };\n}\n\nasync function ensureGeneratedAssets(\n config: ResolvedConfig,\n options: RobosophyMaterialSymbolsOptions,\n cacheDir: string,\n): Promise<GeneratedMaterialSymbolsAssets> {\n const usages = await collectMaterialSymbolUsages(config, options);\n return generateSpriteAssets(usages, cacheDir, config);\n}\n\nexport async function collectMaterialSymbolUsages(\n config: Pick<ResolvedConfig, \"root\">,\n options: RobosophyMaterialSymbolsOptions = {},\n): Promise<IconUsageMap> {\n const usages = createUsageMap();\n\n const manifest = await loadIconManifest();\n\n if (manifest) {\n for (const family of families) {\n for (const name of manifest[family] ?? []) {\n addUsage(usages, { family, name });\n }\n }\n } else {\n for (const name of internalIconNames) {\n for (const family of families) {\n addUsage(usages, { family, name });\n }\n }\n }\n\n for (const icon of options.include ?? []) {\n addUsage(usages, typeof icon === \"string\" ? { family: defaultFamily, name: icon } : icon);\n }\n\n if (options.scan !== false) {\n const roots = options.roots ?? [join(config.root, \"src\")];\n\n for (const root of roots) {\n for (const filePath of await listSourceFiles(root)) {\n const source = await readFile(filePath, \"utf8\");\n collectFromSource(source, usages);\n }\n }\n }\n\n return usages;\n}\n\nexport function buildMaterialSymbolsCss(\n iconClasses: string,\n): HtmlTagDescriptor[] {\n if (!iconClasses) return [];\n\n return [\n {\n tag: \"style\",\n children: iconClasses,\n injectTo: \"head\",\n },\n ];\n}\n\nfunction collectFromSource(source: string, usages: IconUsageMap): void {\n const rsIconTagPattern = /<RsIcon\\b([^>]*)>/g;\n let tagMatch: RegExpExecArray | null;\n\n while ((tagMatch = rsIconTagPattern.exec(source))) {\n const attrs = parseStaticAttributes(tagMatch[1] ?? \"\");\n const rawName = attrs.name ?? attrs[\":name\"];\n const hasFamily = \"family\" in attrs || \":family\" in attrs;\n const rawFamily = attrs.family ?? attrs[\":family\"] ?? \"\";\n\n if (rawName) {\n const familyList = resolveFamilies(rawFamily, hasFamily);\n const names = resolveNames(rawName);\n\n for (const family of familyList) {\n for (const name of names) {\n addUsage(usages, { family, name });\n }\n }\n }\n }\n\n const primeHelperPattern =\n /\\brsPrimeIcon\\(\\s*[\"']([a-z0-9_]+)[\"'](?:\\s*,\\s*\\{([^)]*)\\})?/g;\n let helperMatch: RegExpExecArray | null;\n\n while ((helperMatch = primeHelperPattern.exec(source))) {\n const family = toFamily(helperMatch[2]?.match(/\\bfamily\\s*:\\s*[\"'](\\w+)[\"']/)?.[1]);\n addUsage(usages, {\n family: family ?? defaultFamily,\n name: helperMatch[1] ?? \"\",\n });\n }\n\n const objectIconPattern = /\\bicon\\s*:\\s*[\"']([a-z0-9_]+)[\"']/g;\n let objectMatch: RegExpExecArray | null;\n\n while ((objectMatch = objectIconPattern.exec(source))) {\n addUsage(usages, {\n family: defaultFamily,\n name: objectMatch[1] ?? \"\",\n });\n }\n}\n\nfunction parseStaticAttributes(source: string): Record<string, string> {\n const attrs: Record<string, string> = {};\n const attrPattern = /([:@\\w-]+)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)')/g;\n let match: RegExpExecArray | null;\n\n while ((match = attrPattern.exec(source))) {\n attrs[match[1] ?? \"\"] = match[2] ?? match[3] ?? \"\";\n }\n\n return attrs;\n}\n\nfunction unwrapStaticValue(value: string): string {\n return value.replace(/^['\"](.+)['\"]$/, \"$1\");\n}\n\nfunction addUsage(usages: IconUsageMap, icon: { family?: RsIconFamily; name: string }): void {\n const family = icon.family ?? defaultFamily;\n const name = icon.name.trim();\n\n if (!families.includes(family) || !iconNamePattern.test(name)) {\n return;\n }\n\n usages.get(family)?.add(name);\n}\n\nasync function loadIconManifest(): Promise<Record<RsIconFamily, string[]> | null> {\n try {\n const dir = join(fileURLToPath(import.meta.url), \"..\");\n const manifestPath = join(dir, \"icon-manifest.json\");\n const source = await readFile(manifestPath, \"utf8\");\n return JSON.parse(source) as Record<RsIconFamily, string[]>;\n } catch {\n return null;\n }\n}\n\nfunction toFamily(value?: string): RsIconFamily | undefined {\n const normalized = value ? unwrapStaticValue(value) : \"\";\n return families.includes(normalized as RsIconFamily)\n ? (normalized as RsIconFamily)\n : undefined;\n}\n\nfunction resolveNames(rawName: string): string[] {\n const stringLiterals = /[\"']([a-z0-9_]+)[\"']/g;\n let strMatch: RegExpExecArray | null;\n const names: string[] = [];\n\n while ((strMatch = stringLiterals.exec(rawName))) {\n const candidate = strMatch[1] ?? \"\";\n if (iconNamePattern.test(candidate)) {\n names.push(candidate);\n }\n }\n\n if (names.length === 0) {\n const name = unwrapStaticValue(rawName);\n if (iconNamePattern.test(name)) {\n names.push(name);\n }\n }\n\n return names;\n}\n\nfunction resolveFamilies(rawFamily: string, hasFamily = true): RsIconFamily[] {\n const family = toFamily(rawFamily);\n if (family) return [family];\n\n const stringLiterals = /[\"'](\\w+)[\"']/g;\n let strMatch: RegExpExecArray | null;\n const found = new Set<RsIconFamily>();\n\n while ((strMatch = stringLiterals.exec(rawFamily))) {\n const candidate = strMatch[1] ?? \"\";\n const f = toFamily(candidate);\n if (f) {\n found.add(f);\n }\n }\n\n if (found.size > 0) return [...found];\n\n if (!hasFamily) return [defaultFamily];\n\n return [...families];\n}\n\nfunction createUsageMap(): IconUsageMap {\n return new Map(families.map((family) => [family, new Set<string>()]));\n}\n\nasync function listSourceFiles(root: string): Promise<string[]> {\n try {\n const entries = await readdir(root, { withFileTypes: true });\n const files = await Promise.all(\n entries.map(async (entry) => {\n const path = join(root, entry.name);\n\n if (entry.isDirectory()) {\n return skippedDirs.has(entry.name) ? [] : listSourceFiles(path);\n }\n\n return sourceExtensions.has(extname(entry.name)) ? [path] : [];\n }),\n );\n\n return files.flat();\n } catch {\n return [];\n }\n}\n\nfunction withBase(base: string, path: string): string {\n const cleanBase = base.endsWith(\"/\") ? base : `${base}/`;\n return `${cleanBase}${path}`.replaceAll(`${sep}`, \"/\");\n}\n\nexport function formatDetectedMaterialSymbols(usages: IconUsageMap): string {\n return families\n .map((family) => `${family}: ${[...(usages.get(family) ?? [])].sort().join(\", \")}`)\n .join(\"\\n\");\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vite.js","sources":["../src/vite.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { mkdir, readFile, readdir, writeFile } from \"node:fs/promises\";\nimport { extname, join, sep } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { HtmlTagDescriptor, IndexHtmlTransformResult, Plugin, ResolvedConfig } from \"vite\";\n\nimport type { RsIconFamily } from \"./components/RsIcon\";\n\ntype IconInput = string | { family?: RsIconFamily; name: string; weight?: number };\nexport type RsIconFontDisplay = \"block\" | \"swap\" | \"fallback\" | \"optional\";\n\nexport type RobosophyMaterialSymbolsOptions = {\n outputDir?: string;\n fontDisplay?: RsIconFontDisplay;\n fontVariant?: string;\n include?: IconInput[];\n preload?: boolean;\n roots?: string[];\n scan?: boolean;\n};\n\ntype IconUsageMap = Map<RsIconFamily, Map<string, Set<number>>>;\n\nconst families = [\"outlined\", \"rounded\", \"sharp\"] as const satisfies readonly RsIconFamily[];\nconst defaultFamily: RsIconFamily = \"outlined\";\nconst iconNamePattern = /^[a-z0-9_]+$/;\nconst sourceExtensions = new Set([\".js\", \".jsx\", \".mjs\", \".ts\", \".tsx\", \".vue\"]);\nconst skippedDirs = new Set([\".git\", \"dist\", \"node_modules\", \"storybook-static\"]);\nconst internalIconNames = [\n \"arrow_drop_down\",\n \"arrow_drop_up\",\n \"arrow_left\",\n \"chevron_right\",\n \"close\",\n \"login\",\n \"nest_eco_leaf\",\n];\n\nconst GITHUB_RAW =\n \"https://raw.githubusercontent.com/google/material-design-icons/master/symbols/web\";\nconst CACHE_BASE = join(\"node_modules\", \".cache\", \"robosophy-svgs\");\nconst BASE_OPSZ = 24;\nconst DEFAULT_WEIGHT = 400;\n\nconst GRADE_VARIANTS = [0, -25, 200] as const;\n\nexport function robosophyMaterialSymbols(\n options: RobosophyMaterialSymbolsOptions = {},\n): Plugin {\n const raw = (options.outputDir ?? \"\").trim().replace(/^\\/+/, \"\");\n const outputDir = raw\n .split(\"/\")\n .filter((part) => part && part !== \"..\")\n .join(\"/\") || \"assets\";\n let config: ResolvedConfig;\n let cacheDir: string;\n let cachedAssets: GeneratedMaterialSymbolsAssets | null = null;\n let cachedUsagesKey = \"\";\n let needsRegeneration = true;\n\n function usageMapKey(usages: IconUsageMap): string {\n const parts: string[] = [];\n for (const family of families) {\n const iconWeights = usages.get(family);\n if (!iconWeights || iconWeights.size === 0) continue;\n const entries = [...iconWeights.entries()]\n .map(([name, weights]) => `${name}[${[...weights].sort().join(\",\")}]`)\n .sort();\n parts.push(`${family}:${entries.join(\",\")}`);\n }\n return parts.join(\"|\") || \"(empty)\";\n }\n\n async function getAssets(): Promise<GeneratedMaterialSymbolsAssets> {\n if (!needsRegeneration && cachedAssets) return cachedAssets;\n\n const usages = await collectMaterialSymbolUsages(config, options);\n const newKey = usageMapKey(usages);\n\n if (newKey === cachedUsagesKey && cachedAssets) {\n needsRegeneration = false;\n return cachedAssets;\n }\n\n if (config.command !== \"build\" && cachedUsagesKey !== \"\") {\n config.logger.info(\n \"[robosophy-material-symbols] icon usage changed, regenerating SVG sprite\",\n );\n }\n\n cachedUsagesKey = newKey;\n cachedAssets = await ensureGeneratedAssets(config, options, cacheDir);\n needsRegeneration = false;\n return cachedAssets;\n }\n\n return {\n name: \"robosophy-material-symbols\",\n async configResolved(resolvedConfig) {\n config = resolvedConfig;\n cacheDir = join(config.root, CACHE_BASE);\n await mkdir(cacheDir, { recursive: true });\n },\n async buildStart() {\n if (config.command === \"serve\" || config.command === \"build\") {\n await getAssets();\n }\n },\n async transformIndexHtml(): Promise<IndexHtmlTransformResult> {\n const assets = await getAssets();\n\n const tag: HtmlTagDescriptor = {\n tag: \"svg\",\n attrs: {\n xmlns: \"http://www.w3.org/2000/svg\",\n style: \"display:none;\",\n \"aria-hidden\": \"true\",\n },\n children: assets.spriteContent,\n injectTo: \"body-prepend\",\n };\n\n return [tag, ...buildMaterialSymbolsCss(assets.css)];\n },\n configureServer(server) {\n server.watcher.on(\"all\", (_event, file) => {\n if (sourceExtensions.has(extname(file))) {\n needsRegeneration = true;\n }\n });\n server.middlewares.use(async (request, response, next) => {\n if (!request.url?.startsWith(\"/@robosophy-material-symbols/\")) {\n next();\n return;\n }\n\n try {\n const assets = await getAssets();\n const fileName = decodeURIComponent(\n request.url.replace(\"/@robosophy-material-symbols/\", \"\").split(\"?\")[0] ?? \"\",\n );\n\n if (fileName === \"rs-material-symbols.svg\") {\n response.setHeader(\"Content-Type\", \"image/svg+xml; charset=utf-8\");\n response.setHeader(\"Cache-Control\", \"no-cache\");\n response.end(assets.fullSprite);\n return;\n }\n\n next();\n } catch (error) {\n next(error);\n }\n });\n },\n async generateBundle(_outputOptions) {\n const assets = await getAssets();\n\n if (assets.fullSprite) {\n this.emitFile({\n fileName: `${outputDir}/rs-material-symbols.svg`,\n name: \"rs-material-symbols.svg\",\n source: assets.fullSprite,\n type: \"asset\",\n });\n }\n },\n };\n}\n\ntype GeneratedMaterialSymbolsAssets = {\n fullSprite: string;\n spriteContent: string;\n css: string;\n};\n\ntype SvgVariant = {\n suffix: string;\n symbolSuffix: string;\n};\n\nfunction buildSvgVariants(weight: number = DEFAULT_WEIGHT): SvgVariant[] {\n const variants: SvgVariant[] = [];\n for (const grade of GRADE_VARIANTS) {\n const gradeSuffix = grade === 0 ? \"\" : grade > 0 ? `grad${grade}` : `gradN${Math.abs(grade)}`;\n const symbolGradeSuffix = grade === 0 ? \"\" : `-${gradeSuffix}`;\n\n for (const fill of [false, true]) {\n const fillSuffix = fill ? \"fill1\" : \"\";\n const symbolFillSuffix = fill ? \"-fill\" : \"\";\n const weightSuffix = weight !== DEFAULT_WEIGHT ? `wght${weight}` : \"\";\n const weightSymbolSuffix = weight !== DEFAULT_WEIGHT ? `-wght${weight}` : \"\";\n const parts = [gradeSuffix, fillSuffix, weightSuffix].filter(Boolean);\n\n variants.push({\n suffix: parts.length > 0 ? `${parts.join(\"\")}_${BASE_OPSZ}px` : `${BASE_OPSZ}px`,\n symbolSuffix: `${symbolGradeSuffix}${symbolFillSuffix}${weightSymbolSuffix}`,\n });\n }\n }\n return variants;\n}\n\nfunction buildSvgUrl(name: string, family: RsIconFamily, suffix: string): string {\n const style = family === \"outlined\" ? \"materialsymbolsoutlined\"\n : family === \"rounded\" ? \"materialsymbolsrounded\"\n : \"materialsymbolssharp\";\n return `${GITHUB_RAW}/${name.toLowerCase()}/${style}/${name.toLowerCase()}_${suffix}.svg`;\n}\n\nfunction buildSymbolId(name: string, family: RsIconFamily, symbolSuffix: string): string {\n return `rs-icon-${family}-${name}${symbolSuffix}`;\n}\n\nasync function fetchSvg(url: string): Promise<string | null> {\n try {\n const response = await fetch(url);\n if (!response.ok) return null;\n return await response.text();\n } catch {\n return null;\n }\n}\n\nasync function loadSvgFromCache(cacheDir: string, cacheKey: string): Promise<string | null> {\n const cachePath = join(cacheDir, `${cacheKey}.svg`);\n try {\n return await readFile(cachePath, \"utf8\");\n } catch {\n return null;\n }\n}\n\nasync function saveSvgToCache(cacheDir: string, cacheKey: string, content: string): Promise<void> {\n const cachePath = join(cacheDir, `${cacheKey}.svg`);\n try {\n await writeFile(cachePath, content, \"utf8\");\n } catch {\n // Ignore cache write errors\n }\n}\n\nfunction parseSvgPaths(svgContent: string): string | null {\n const viewBoxMatch = svgContent.match(/viewBox=\"([^\"]+)\"/i);\n if (!viewBoxMatch) return null;\n\n const paths: string[] = [];\n const pathRegex = /<path\\s+([^>]*)>/g;\n let pathMatch: RegExpExecArray | null;\n\n while ((pathMatch = pathRegex.exec(svgContent))) {\n const attrs = pathMatch[1] ?? \"\";\n const dMatch = attrs.match(/d=\"([^\"]*)\"/);\n if (dMatch) {\n paths.push(dMatch[1] ?? \"\");\n }\n }\n\n if (paths.length === 0) return null;\n\n return paths\n .map((d) => `<path fill=\"currentColor\" d=\"${d}\"/>`)\n .join(\"\");\n}\n\nasync function generateSpriteAssets(\n usages: IconUsageMap,\n cacheDir: string,\n config: ResolvedConfig,\n): Promise<GeneratedMaterialSymbolsAssets> {\n const symbols: string[] = [];\n const iconClasses: string[] = [];\n let totalFetched = 0;\n let totalBytes = 0;\n\n for (const family of families) {\n const iconWeights = usages.get(family);\n if (!iconWeights || iconWeights.size === 0) continue;\n\n for (const [name, weights] of [...iconWeights.entries()].sort()) {\n for (const weight of [...weights].sort()) {\n const variants = buildSvgVariants(weight);\n for (const variant of variants) {\n const symbolId = buildSymbolId(name, family, variant.symbolSuffix);\n const url = buildSvgUrl(name, family, variant.suffix);\n const cacheKey = createHash(\"sha256\")\n .update(url)\n .digest(\"hex\")\n .slice(0, 12);\n\n let svgContent = cacheDir ? await loadSvgFromCache(cacheDir, cacheKey) : null;\n\n if (!svgContent) {\n svgContent = await fetchSvg(url);\n if (!svgContent) continue;\n\n if (cacheDir) {\n await saveSvgToCache(cacheDir, cacheKey, svgContent);\n }\n }\n\n const pathContent = parseSvgPaths(svgContent);\n if (!pathContent) continue;\n\n symbols.push(\n `<symbol id=\"${symbolId}\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">${pathContent}</symbol>`,\n );\n\n totalFetched++;\n totalBytes += svgContent.length;\n }\n }\n }\n }\n\n const iconNames = new Set<string>();\n for (const family of families) {\n const iconWeights = usages.get(family);\n if (iconWeights) {\n for (const name of iconWeights.keys()) {\n iconNames.add(name);\n }\n }\n }\n for (const name of [...iconNames].sort()) {\n iconClasses.push(`.rs-icon-${name} { --rs-icon-content: \"${name}\"; }`);\n }\n\n const spriteContent = `<defs>${symbols.join(\"\")}</defs>`;\n const fullSprite = `<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display:none\" aria-hidden=\"true\">${spriteContent}</svg>`;\n const css = iconClasses.join(\"\\n\");\n\n const totalIcons = [...usages.values()].reduce((sum, m) => sum + m.size, 0);\n if (totalIcons > 0) {\n const summary = formatDetectedMaterialSymbols(usages);\n config.logger.info(\n `[robosophy-material-symbols] ${totalIcons} icons detected, ${totalFetched} SVG variants (${(totalBytes / 1024).toFixed(1)} KB)\\n${summary}`,\n );\n } else {\n config.logger.warn(\n \"[robosophy-material-symbols] No Material Symbols icons detected in source. Add them via the include option.\",\n );\n }\n\n return { fullSprite, spriteContent, css };\n}\n\nasync function ensureGeneratedAssets(\n config: ResolvedConfig,\n options: RobosophyMaterialSymbolsOptions,\n cacheDir: string,\n): Promise<GeneratedMaterialSymbolsAssets> {\n const usages = await collectMaterialSymbolUsages(config, options);\n return generateSpriteAssets(usages, cacheDir, config);\n}\n\nexport async function collectMaterialSymbolUsages(\n config: Pick<ResolvedConfig, \"root\">,\n options: RobosophyMaterialSymbolsOptions = {},\n): Promise<IconUsageMap> {\n const usages = createUsageMap();\n\n const manifest = await loadIconManifest();\n\n if (manifest) {\n for (const family of families) {\n for (const name of manifest[family] ?? []) {\n addUsage(usages, { family, name });\n }\n }\n } else {\n for (const name of internalIconNames) {\n for (const family of families) {\n addUsage(usages, { family, name });\n }\n }\n }\n\n for (const icon of options.include ?? []) {\n const resolved = typeof icon === \"string\" ? { family: defaultFamily, name: icon } : icon;\n if (resolved.weight !== undefined) {\n addUsage(usages, resolved);\n } else {\n for (const w of VALID_WEIGHTS) {\n addUsage(usages, { ...resolved, weight: w });\n }\n }\n }\n\n if (options.scan !== false) {\n const roots = options.roots ?? [join(config.root, \"src\")];\n\n for (const root of roots) {\n for (const filePath of await listSourceFiles(root)) {\n const source = await readFile(filePath, \"utf8\");\n collectFromSource(source, usages);\n }\n }\n }\n\n return usages;\n}\n\nexport function buildMaterialSymbolsCss(\n iconClasses: string,\n): HtmlTagDescriptor[] {\n if (!iconClasses) return [];\n\n return [\n {\n tag: \"style\",\n children: iconClasses,\n injectTo: \"head\",\n },\n ];\n}\n\nfunction skipStringBackward(source: string, pos: number, quote: string): number {\n pos--;\n while (pos >= 0) {\n if (source[pos] === \"\\\\\") {\n pos -= 2;\n continue;\n }\n if (source[pos] === quote) {\n let backslashCount = 0;\n let k = pos - 1;\n while (k >= 0 && source[k] === \"\\\\\") {\n backslashCount++;\n k--;\n }\n if (backslashCount % 2 === 1) {\n pos = pos - backslashCount - 1;\n continue;\n }\n return pos - 1;\n }\n pos--;\n }\n return -1;\n}\n\nfunction skipStringForward(source: string, pos: number, quote: string): number {\n pos++;\n while (pos < source.length) {\n if (source[pos] === \"\\\\\") {\n pos += 2;\n continue;\n }\n if (source[pos] === quote) {\n return pos + 1;\n }\n pos++;\n }\n return source.length;\n}\n\nfunction findEnclosingObject(\n source: string,\n fromIndex: number,\n): { start: number; end: number; body: string } | null {\n let depth = 0;\n let i = fromIndex;\n\n while (i >= 0) {\n const char = source[i];\n\n if (char === '\"' || char === \"'\" || char === \"`\") {\n i = skipStringBackward(source, i, char);\n continue;\n }\n\n // Line comment //\n if (char === \"/\" && i > 0 && source[i - 1] === \"/\") {\n i -= 2;\n while (i >= 0 && source[i] !== \"\\n\") i--;\n continue;\n }\n\n // Block comment */\n if (char === \"/\" && i > 0 && source[i - 1] === \"*\") {\n i -= 2;\n while (i >= 0) {\n if (source[i] === \"/\" && i + 1 < source.length && source[i + 1] === \"*\") {\n i--;\n break;\n }\n i--;\n }\n continue;\n }\n\n if (char === \"}\") {\n depth++;\n } else if (char === \"{\") {\n if (depth === 0) {\n const start = i;\n let j = i + 1;\n let innerDepth = 1;\n\n while (j < source.length) {\n const c = source[j];\n\n if (c === '\"' || c === \"'\" || c === \"`\") {\n j = skipStringForward(source, j, c);\n continue;\n }\n\n if (c === \"/\") {\n // Line comment //\n if (j + 1 < source.length && source[j + 1] === \"/\") {\n j += 2;\n while (j < source.length && source[j] !== \"\\n\") j++;\n continue;\n }\n // Block comment /*\n if (j + 1 < source.length && source[j + 1] === \"*\") {\n j += 2;\n while (j + 1 < source.length) {\n if (source[j] === \"*\" && source[j + 1] === \"/\") {\n j += 2;\n break;\n }\n j++;\n }\n continue;\n }\n }\n\n if (c === \"{\") innerDepth++;\n else if (c === \"}\") {\n innerDepth--;\n if (innerDepth === 0) {\n return {\n start,\n end: j,\n body: source.slice(start + 1, j),\n };\n }\n }\n\n j++;\n }\n\n return null;\n }\n depth--;\n }\n\n i--;\n }\n\n return null;\n}\n\nfunction collectFromSource(source: string, usages: IconUsageMap): void {\n const rsIconTagPattern = /<RsIcon\\b([^>]*)>/g;\n let tagMatch: RegExpExecArray | null;\n\n while ((tagMatch = rsIconTagPattern.exec(source))) {\n const attrs = parseStaticAttributes(tagMatch[1] ?? \"\");\n const rawName = attrs.name ?? attrs[\":name\"];\n const hasFamily = \"family\" in attrs || \":family\" in attrs;\n const rawFamily = attrs.family ?? attrs[\":family\"] ?? \"\";\n const rawWeight = attrs.weight ?? attrs[\":weight\"] ?? \"\";\n const weight = rawWeight ? parseInt(rawWeight, 10) : DEFAULT_WEIGHT;\n const resolvedWeight = !isNaN(weight) && weight > 0 ? weight : DEFAULT_WEIGHT;\n\n if (rawName) {\n const isNameDynamic = \":name\" in attrs;\n const familyList = resolveFamilies(rawFamily, hasFamily);\n const names = resolveNames(rawName, isNameDynamic);\n\n for (const family of familyList) {\n for (const name of names) {\n addUsage(usages, { family, name, weight: resolvedWeight });\n }\n }\n }\n }\n\n const primeHelperPattern =\n /\\brsPrimeIcon\\(\\s*[\"']([a-z0-9_]+)[\"'](?:\\s*,\\s*\\{([^)]*)\\})?/g;\n let helperMatch: RegExpExecArray | null;\n\n while ((helperMatch = primeHelperPattern.exec(source))) {\n const family = toFamily(helperMatch[2]?.match(/\\bfamily\\s*:\\s*[\"'](\\w+)[\"']/)?.[1]);\n addUsage(usages, {\n family: family ?? defaultFamily,\n name: helperMatch[1] ?? \"\",\n });\n }\n\n const objectIconPattern = /\\bicon\\s*:\\s*[\"']([a-z0-9_]+)[\"']/g;\n let objectMatch: RegExpExecArray | null;\n\n while ((objectMatch = objectIconPattern.exec(source))) {\n const name = objectMatch[1] ?? \"\";\n const obj = findEnclosingObject(source, objectMatch.index);\n if (obj) {\n const cleanBody = obj.body.replace(/\\/\\/.*/g, \"\").replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\");\n const weightMatch = cleanBody.match(/\\bweight\\s*:\\s*(\\d+)/);\n const familyMatch = cleanBody.match(/\\bfamily\\s*:\\s*[\"'](\\w+)[\"']/);\n addUsage(usages, {\n family: familyMatch ? (familyMatch[1] as RsIconFamily) : defaultFamily,\n name,\n weight: weightMatch ? parseInt(weightMatch[1], 10) : undefined,\n });\n } else {\n addUsage(usages, { family: defaultFamily, name });\n }\n }\n\n // Pattern 4: magic comments @robosophy-icon\n // Use for icons that cannot be detected statically (props, variables, API, etc.)\n const magicCommentPattern = /\\/\\/\\s*@robosophy-icon:\\s*([a-z0-9_]+)/g;\n let magicMatch: RegExpExecArray | null;\n\n while ((magicMatch = magicCommentPattern.exec(source))) {\n const name = magicMatch[1] ?? \"\";\n const lineEnd = source.indexOf(\"\\n\", magicMatch.index);\n const line = lineEnd === -1 ? source.slice(magicMatch.index) : source.slice(magicMatch.index, lineEnd);\n const familyMatch = line.match(/\\bfamily\\s*=\\s*[\"']?(\\w+)[\"']?/);\n const weightMatch = line.match(/\\bweight\\s*=\\s*(\\d+)/);\n addUsage(usages, {\n family: familyMatch ? (familyMatch[1] as RsIconFamily) : defaultFamily,\n name,\n weight: weightMatch ? parseInt(weightMatch[1], 10) : undefined,\n });\n }\n\n // Pattern 5: icon arrays — detect arrays assigned to variables with \"icon\" in the name\n // e.g. const iconNames = [\"home\", \"search\"]\n const iconArrayPattern = /(?:const|let|var)\\s+(\\w*[Ii]con\\w*)\\s*=\\s*\\[/g;\n let arrayMatch: RegExpExecArray | null;\n\n while ((arrayMatch = iconArrayPattern.exec(source))) {\n const bracketStart = arrayMatch.index + arrayMatch[0].length - 1;\n let depth = 1;\n let j = bracketStart + 1;\n\n while (j < source.length) {\n const c = source[j];\n\n if (c === '\"' || c === \"'\" || c === \"`\") {\n j = skipStringForward(source, j, c);\n continue;\n }\n\n if (c === \"/\") {\n if (j + 1 < source.length && source[j + 1] === \"/\") {\n j += 2;\n while (j < source.length && source[j] !== \"\\n\") j++;\n continue;\n }\n if (j + 1 < source.length && source[j + 1] === \"*\") {\n j += 2;\n while (j + 1 < source.length) {\n if (source[j] === \"*\" && source[j + 1] === \"/\") {\n j += 2;\n break;\n }\n j++;\n }\n continue;\n }\n }\n\n if (c === \"[\") depth++;\n else if (c === \"]\") {\n depth--;\n if (depth === 0) break;\n }\n\n j++;\n }\n\n if (depth === 0) {\n const arrayContent = source.slice(bracketStart + 1, j);\n let braceDepth = 0;\n let k = 0;\n\n while (k < arrayContent.length) {\n const c = arrayContent[k];\n\n if (c === '\"' || c === \"'\" || c === \"`\") {\n if (braceDepth === 0) {\n const quote = c;\n let strEnd = k + 1;\n while (strEnd < arrayContent.length) {\n if (arrayContent[strEnd] === \"\\\\\") {\n strEnd += 2;\n continue;\n }\n if (arrayContent[strEnd] === quote) break;\n strEnd++;\n }\n const iconName = arrayContent.slice(k + 1, strEnd);\n if (iconNamePattern.test(iconName)) {\n addUsage(usages, { family: defaultFamily, name: iconName });\n }\n k = strEnd + 1;\n continue;\n } else {\n k = skipStringForward(arrayContent, k, c);\n continue;\n }\n }\n\n if (c === \"{\") braceDepth++;\n else if (c === \"}\") braceDepth--;\n\n k++;\n }\n }\n }\n}\n\nfunction parseStaticAttributes(source: string): Record<string, string> {\n const attrs: Record<string, string> = {};\n const attrPattern = /([:@\\w-]+)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)')/g;\n let match: RegExpExecArray | null;\n\n while ((match = attrPattern.exec(source))) {\n attrs[match[1] ?? \"\"] = match[2] ?? match[3] ?? \"\";\n }\n\n return attrs;\n}\n\nfunction unwrapStaticValue(value: string): string {\n return value.replace(/^['\"`](.+)['\"`]$/, \"$1\");\n}\n\nconst VALID_WEIGHTS = [100, 200, 300, 400, 500, 600, 700] as const;\n\nfunction addUsage(\n usages: IconUsageMap,\n icon: { family?: RsIconFamily; name: string; weight?: number },\n): void {\n const family = icon.family ?? defaultFamily;\n const name = icon.name.trim();\n const weight = icon.weight ?? DEFAULT_WEIGHT;\n\n if (!families.includes(family) || !iconNamePattern.test(name)) {\n return;\n }\n\n if (!VALID_WEIGHTS.includes(weight as never)) return;\n\n const iconMap = usages.get(family);\n if (!iconMap) return;\n\n const existing = iconMap.get(name);\n if (existing) {\n existing.add(weight);\n } else {\n iconMap.set(name, new Set([weight]));\n }\n}\n\nasync function loadIconManifest(): Promise<Record<RsIconFamily, string[]> | null> {\n try {\n const dir = join(fileURLToPath(import.meta.url), \"..\");\n const manifestPath = join(dir, \"icon-manifest.json\");\n const source = await readFile(manifestPath, \"utf8\");\n return JSON.parse(source) as Record<RsIconFamily, string[]>;\n } catch {\n return null;\n }\n}\n\nfunction toFamily(value?: string): RsIconFamily | undefined {\n const normalized = value ? unwrapStaticValue(value) : \"\";\n return families.includes(normalized as RsIconFamily)\n ? (normalized as RsIconFamily)\n : undefined;\n}\n\nfunction resolveNames(rawName: string, isDynamic = false): string[] {\n const stringLiterals = /[\"'`]([a-z0-9_]+)[\"'`]/g;\n let strMatch: RegExpExecArray | null;\n const names: string[] = [];\n\n while ((strMatch = stringLiterals.exec(rawName))) {\n const candidate = strMatch[1] ?? \"\";\n if (iconNamePattern.test(candidate)) {\n names.push(candidate);\n }\n }\n\n if (names.length === 0) {\n if (isDynamic) return names;\n const name = unwrapStaticValue(rawName);\n if (iconNamePattern.test(name)) {\n names.push(name);\n }\n }\n\n return names;\n}\n\nfunction resolveFamilies(rawFamily: string, hasFamily = true): RsIconFamily[] {\n const family = toFamily(rawFamily);\n if (family) return [family];\n\n const stringLiterals = /[\"'`](\\w+)[\"'`]/g;\n let strMatch: RegExpExecArray | null;\n const found = new Set<RsIconFamily>();\n\n while ((strMatch = stringLiterals.exec(rawFamily))) {\n const candidate = strMatch[1] ?? \"\";\n const f = toFamily(candidate);\n if (f) {\n found.add(f);\n }\n }\n\n if (found.size > 0) return [...found];\n\n if (!hasFamily) return [defaultFamily];\n\n return [...families];\n}\n\nfunction createUsageMap(): IconUsageMap {\n return new Map(families.map((family) => [family, new Map<string, Set<number>>()]));\n}\n\nasync function listSourceFiles(root: string): Promise<string[]> {\n try {\n const entries = await readdir(root, { withFileTypes: true });\n const files = await Promise.all(\n entries.map(async (entry) => {\n const path = join(root, entry.name);\n\n if (entry.isDirectory()) {\n return skippedDirs.has(entry.name) ? [] : listSourceFiles(path);\n }\n\n return sourceExtensions.has(extname(entry.name)) ? [path] : [];\n }),\n );\n\n return files.flat();\n } catch {\n return [];\n }\n}\n\nexport function formatDetectedMaterialSymbols(usages: IconUsageMap): string {\n return families\n .map((family) => {\n const iconWeights = usages.get(family);\n if (!iconWeights || iconWeights.size === 0) return `${family}: (none)`;\n const entries = [...iconWeights.entries()]\n .map(([name, weights]) => `${name}[${[...weights].sort().join(\",\")}]`)\n .sort()\n .join(\", \");\n return `${family}: ${entries}`;\n })\n .join(\"\\n\");\n}\n"],"names":[],"mappings":"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"}
|