export function getVideoUrl(name: string): string { return `https://openlist.wufangzhen.com/d/139/wufangzhen.com/mp4/${name}` } export function clamp(value: number, min: number, max: number): number { return Math.min(Math.max(value, min), max) } export function isMobileDevice(): boolean { if (typeof window === 'undefined') return false return window.innerWidth < 768 || 'ontouchstart' in window } export function getOS(): 'mac' | 'windows' | 'linux' | 'unknown' { if (typeof window === 'undefined') return 'unknown' const userAgent = window.navigator.userAgent if (userAgent.includes('Mac')) return 'mac' if (userAgent.includes('Windows')) return 'windows' if (userAgent.includes('Linux')) return 'linux' return 'unknown' } export function debounce void>(fn: T, delay: number): T { let timeoutId: ReturnType return ((...args: Parameters) => { clearTimeout(timeoutId) timeoutId = setTimeout(() => fn(...args), delay) }) as T } export function throttle void>(fn: T, delay: number): T { let lastCall = 0 return ((...args: Parameters) => { const now = Date.now() if (now - lastCall >= delay) { lastCall = now fn(...args) } }) as T }