/** 扫描 wrap 型源的越界可疑图标(坐标与 transform scale 不匹配 → 24 视口外) */ const fs = require('fs'); const path = require('path'); const S = require('../js/data/icon-sources.js'); const wrap = []; for (const s of S) { if (s.scaleMode === 'wrap' && s.format === 'iconify') wrap.push(s); } console.log('wrap 源数:', wrap.length); for (const s of wrap) { const fp = path.join('js/data/sources', s.id + '.js'); if (!fs.existsSync(fp)) { console.log(s.id, '无数据文件'); continue; } global.window = {}; try { eval(fs.readFileSync(fp, 'utf8')); } catch (e) { console.log(s.id, '读取失败', e.message); continue; } const d = global.window['HGB_Source_' + s.id]; if (!d) { continue; } let bad = 0, anim = 0; const samples = []; for (const ic of d.icons) { const b = ic.svg || ''; if (/ m[1]); let max = 0; for (const dstr of ds) { const ns = dstr.match(/-?\d*\.?\d+/g); if (ns) for (const n of ns) { const v = Math.abs(parseFloat(n)); if (v > max) max = v; } } const am = [...b.matchAll(/(?:cx|cy|rx|ry|x|y|r|x1|y1|x2|y2|width|height)="([-\d.]+)"/g)]; for (const m of am) { const v = Math.abs(parseFloat(m[1])); if (v > max) max = v; } const limit = 25 / sc * 1.15; if (sc < 0.005 || max > limit) { bad++; if (samples.length < 6) samples.push(ic.name + ' max=' + max.toFixed(0) + ' sc=' + sc.toFixed(4)); } } if (bad) console.log(s.id + ': ' + bad + '/' + d.icons.length + ' 越界可疑 [' + samples.join('; ') + '] anim=' + anim); }