import { type ClassValue, clsx } from "clsx"; import { twMerge } from "tailwind-merge"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } export function formatDuration(seconds: number): string { const h = Math.floor(seconds / 3600); const m = Math.floor((seconds % 3600) / 60); const s = Math.floor(seconds % 60); const frames = Math.floor((seconds % 1) * 24); // rough if (h > 0) return `${h}:${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`; return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`; } export function formatTimecode(seconds: number, fps: number = 24): string { const h = Math.floor(seconds / 3600); const m = Math.floor((seconds % 3600) / 60); const s = Math.floor(seconds % 60); const f = Math.floor((seconds % 1) * fps); if (h > 0) { return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}:${String(f).padStart(2, "0")}`; } return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}:${String(f).padStart(2, "0")}`; } export function frameToTimecode(frame: number, fps: number): string { return formatTimecode(frame / fps, fps); } export function formatFileSize(bytes: number | bigint): string { const b = typeof bytes === "bigint" ? Number(bytes) : bytes; if (b < 1024) return `${b} B`; if (b < 1024 * 1024) return `${(b / 1024).toFixed(1)} KB`; if (b < 1024 * 1024 * 1024) return `${(b / 1024 / 1024).toFixed(1)} MB`; return `${(b / 1024 / 1024 / 1024).toFixed(2)} GB`; } export function formatRelativeDate(date: Date | string): string { const d = typeof date === "string" ? new Date(date) : date; const now = new Date(); const diff = now.getTime() - d.getTime(); const minutes = Math.floor(diff / 60000); const hours = Math.floor(diff / 3600000); const days = Math.floor(diff / 86400000); if (minutes < 1) return "just now"; if (minutes < 60) return `${minutes}m ago`; if (hours < 24) return `${hours}h ago`; if (days < 7) return `${days}d ago`; return d.toLocaleDateString("en-US", { month: "short", day: "numeric" }); } export function getInitials(name: string | null | undefined): string { if (!name) return "?"; return name .split(" ") .map((n) => n[0]) .join("") .toUpperCase() .slice(0, 2); } export function slugify(text: string): string { return text .toLowerCase() .replace(/[^\w\s-]/g, "") .replace(/[\s_-]+/g, "-") .replace(/^-+|-+$/g, ""); } export function versionLabel(n: number): string { return `v${String(n).padStart(3, "0")}`; }