Files
defiQUGandCursor 05978ae25c feat(mim): admin QR/brand API, public config hooks, and deploy workflow fix.
Split mim-api into modular routes, refresh nav brand assets, and pin reusable validate workflow to Order-of-Hospitallers/miracles_in_motion@main.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-19 16:17:10 -07:00

80 lines
2.1 KiB
JavaScript

#!/usr/bin/env node
/**
* Trace nav PNG lockups to SVG via potrace (high-fidelity paths from approved raster).
* Usage: node scripts/brand/trace-nav-svg.mjs
*/
import { promises as fs } from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import potrace from 'potrace'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const brandDir = path.join(__dirname, '../../public/brand')
const traces = [
{
input: 'logo-horizontal-nav.png',
output: 'logo-horizontal-nav.svg',
title: 'Miracles in Motion Foundation',
potrace: {
color: 'auto',
background: 'transparent',
turdSize: 2,
optTolerance: 0.2,
threshold: 180,
},
},
{
input: 'logo-symbol-nav.png',
output: 'logo-symbol-nav.svg',
title: 'Miracles in Motion Foundation symbol',
potrace: {
color: 'auto',
background: 'transparent',
turdSize: 2,
optTolerance: 0.15,
threshold: 200,
},
},
]
function tracePng(inputPath, options) {
return new Promise((resolve, reject) => {
potrace.trace(inputPath, options, (err, svg) => {
if (err) reject(err)
else resolve(svg)
})
})
}
function normalizeSvg(svg, title) {
let out = svg.replace(/<\?xml[^>]*>\s*/i, '')
out = out.replace(/fill="black"/gi, 'fill="#D9AA45"')
out = out.replace(/fill="#000000"/gi, 'fill="#D9AA45"')
out = out.replace(/fill="#000"/gi, 'fill="#D9AA45"')
if (!out.includes('aria-hidden')) {
out = out.replace(/<svg\b/, '<svg role="img" aria-hidden="true"')
}
if (!out.includes('<title>')) {
out = out.replace(/<svg([^>]*)>/, `<svg$1>\n <title>${title}</title>`)
}
return out.trim() + '\n'
}
async function main() {
for (const job of traces) {
const inputPath = path.join(brandDir, job.input)
const outputPath = path.join(brandDir, job.output)
await fs.access(inputPath)
const raw = await tracePng(inputPath, job.potrace)
const svg = normalizeSvg(raw, job.title)
await fs.writeFile(outputPath, svg)
console.log(`Wrote ${job.output} (${svg.length} bytes)`)
}
}
main().catch((err) => {
console.error(err)
process.exit(1)
})