/** Формат скорости: Кбит/с при < 1 Мбит/с, иначе Мбит/с / Гбит/с. */ export function fmtRate(v: number): string { if (!Number.isFinite(v) || v <= 0) return "0 Кбит/с" if (v >= 1000) return `${(v / 1000).toFixed(2)} Гбит/с` if (v < 1) return `${Math.round(v * 1000)} Кбит/с` if (v < 10) return `${v.toFixed(2)} Мбит/с` if (v < 100) return `${v.toFixed(1)} Мбит/с` return `${Math.round(v)} Мбит/с` } export function fmtGB(v: number): string { if (v >= 1000) return `${(v / 1000).toFixed(2)} ТБ` return `${v.toFixed(1)} ГБ` } export function formatBytes(n: number): string { if (!Number.isFinite(n) || n <= 0) return "0 Б" if (n >= 1_000_000_000_000) return `${(n / 1_000_000_000_000).toFixed(2)} ТБ` if (n >= 1_000_000_000) return `${(n / 1_000_000_000).toFixed(2)} ГБ` if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)} МБ` if (n >= 1000) return `${(n / 1000).toFixed(1)} КБ` return `${Math.round(n)} Б` } /** API bitrate is bits/s; fmtRate expects Мбит/с. */ export function fmtBps(bps: number): string { return fmtRate(bps / 1_000_000) } export const TRAFFIC_RANGE_MINUTES: Record = { "5m": 5, "15m": 15, "1h": 60, "4h": 240, "24h": 1440, } export function formatRangeAgo(minutesAgo: number): string { if (minutesAgo <= 0) return "сейчас" if (minutesAgo < 60) return `−${minutesAgo}м` return `−${Math.round(minutesAgo / 60)}ч` }