const isNum = (v: unknown): v is number => typeof v === "number" && Number.isFinite(v); const toNum = (v: unknown): number | null => { if (isNum(v)) return v; if (typeof v === "string" && v.trim() !== "" && Number.isFinite(Number(v))) return Number(v); return null; }; export const fmtNum = (v: unknown, digits = 2): string => { const n = toNum(v); return n === null ? "—" : n.toLocaleString("en-US", { minimumFractionDigits: digits, maximumFractionDigits: digits }); }; export const fmtPrice = (v: unknown): string => { const n = toNum(v); if (n === null) return "—"; const d = n >= 1000 ? 1 : n >= 10 ? 2 : n >= 1 ? 3 : 5; return n.toLocaleString("en-US", { minimumFractionDigits: d, maximumFractionDigits: d }); }; export const fmtPct = (v: unknown, digits = 2, alreadyPct = false): string => { const n = toNum(v); if (n === null) return "—"; const p = alreadyPct ? n : n * 100; return `${p >= 0 ? "+" : ""}${p.toFixed(digits)}%`; }; export const fmtPctPlain = (v: unknown, digits = 1): string => { const n = toNum(v); return n === null ? "—" : `${(n * 100).toFixed(digits)}%`; }; export const fmtBps = (v: unknown, digits = 1): string => { const n = toNum(v); return n === null ? "—" : `${n.toFixed(digits)} bps`; }; export const fmtUsd = (v: unknown, digits = 2): string => { const n = toNum(v); return n === null ? "—" : n.toLocaleString("en-US", { style: "currency", currency: "USD", minimumFractionDigits: digits, maximumFractionDigits: digits }); }; export const fmtRatio = (v: unknown, digits = 2): string => { const n = toNum(v); if (n === null) return "—"; if (!Number.isFinite(n)) return n > 0 ? "∞" : "—"; return n.toFixed(digits); }; export const fmtTs = (ts: unknown): string => { const n = toNum(ts); if (n === null) return "—"; const ms = n > 1e12 ? n : n * 1000; return new Date(ms).toISOString().replace("T", " ").slice(0, 19) + "Z"; }; export const fmtDate = (ts: unknown): string => { const n = toNum(ts); if (n === null) return "—"; return new Date((n > 1e12 ? n : n * 1000)).toISOString().slice(0, 10); }; export const fmtIso = (s: unknown): string => (typeof s === "string" ? s.replace("T", " ").slice(0, 19) : "—"); export const fmtAge = (s: unknown): string => { const n = toNum(s); if (n === null) return "—"; if (n < 60) return `${n.toFixed(0)}s`; if (n < 3600) return `${(n / 60).toFixed(0)}m`; return `${(n / 3600).toFixed(1)}h`; }; export const signClass = (v: unknown): string => { const n = toNum(v); if (n === null || n === 0) return "text-fg-muted"; return n > 0 ? "text-up" : "text-down"; }; export { toNum };