/* Syntax highlighting (Prism) + file-type icon metadata. */ (function () { const EXT_LANG = { php: "php", js: "javascript", mjs: "javascript", cjs: "javascript", jsx: "jsx", ts: "typescript", tsx: "tsx", py: "python", html: "markup", xml: "markup", svg: "markup", vue: "markup", css: "css", scss: "css", json: "json", md: "markdown", sh: "bash", bash: "bash", yml: "yaml", yaml: "yaml", env: "bash", }; function ext(path) { const base = path.split("/").pop() || ""; if (base === ".env" || base.startsWith(".env")) return "env"; const i = base.lastIndexOf("."); return i >= 0 ? base.slice(i + 1).toLowerCase() : ""; } function langFor(path) { return EXT_LANG[ext(path)] || null; } function langLabel(path) { const e = ext(path); const map = { php: "PHP", js: "JavaScript", mjs: "JavaScript", ts: "TypeScript", tsx: "TypeScript", jsx: "JavaScript", py: "Python", html: "HTML", css: "CSS", json: "JSON", md: "Markdown", sh: "Shell", env: "Dotenv", yml: "YAML", yaml: "YAML", }; return map[e] || (e ? e.toUpperCase() : "Plain Text"); } function escapeHtml(s) { return s.replace(/[&<>]/g, (c) => ({ "&": "&", "<": "<", ">": ">" }[c])); } // highlight a single line independently (keeps line numbering robust) function hlLine(line, lang) { if (line === "") return " "; try { const grammar = lang && window.Prism && Prism.languages[lang]; if (grammar) return Prism.highlight(line, grammar, lang); } catch (e) { /* fall through */ } return escapeHtml(line); } // ---- file-type icon: colored monogram chip -------------------------- const ICONS = { php: { c: "#a78bdb", t: "php" }, js: { c: "#e6c860", t: "js" }, mjs: { c: "#e6c860", t: "js" }, ts: { c: "#5a9bd6", t: "ts" }, tsx: { c: "#5a9bd6", t: "ts" }, jsx: { c: "#5a9bd6", t: "jsx" }, py: { c: "#5fa8d6", t: "py" }, html: { c: "#e08b6a", t: "<>" }, css: { c: "#5a9bd6", t: "{}" }, scss: { c: "#d6699e", t: "{}" }, json: { c: "#d8a85c", t: "{}" }, md: { c: "#9aa0a8", t: "md" }, env: { c: "#7fc6a0", t: "$" }, sh: { c: "#7fc6a0", t: "$" }, yml: { c: "#cf7a6a", t: "yml" }, yaml: { c: "#cf7a6a", t: "yml" }, lock: { c: "#8a8f98", t: "lk" }, }; const NAME_ICONS = { "composer.json": { c: "#a78bdb", t: "co" }, "package.json": { c: "#cf7a6a", t: "pk" }, "README.md": { c: "#5a9bd6", t: "md" }, ".env": { c: "#7fc6a0", t: "$" }, }; function iconFor(path) { const base = path.split("/").pop() || ""; if (NAME_ICONS[base]) return NAME_ICONS[base]; return ICONS[ext(path)] || { c: "#7d838c", t: base.slice(0, 2) || "ยท" }; } window.HL = { ext, langFor, langLabel, hlLine, iconFor, escapeHtml }; })();