const BOT_PATTERNS = /bot|crawl|spider|slurp|mediapartners|adsbot|facebookexternalhit|twitterbot|linkedinbot|whatsapp|telegram|pinterest|slack|discordbot|applebot|bingpreview|google-read-aloud|ia_archiver|mj12bot|ahrefs|semrush|dotbot|rogerbot|screaming\.?frog/i; export function isBot(ua: string): boolean { return BOT_PATTERNS.test(ua); } export function anonymizeIp(ip: string): string { const mapped = ip.match(/^::ffff:(\d+\.\d+\.\d+)\.\d+$/i); if (mapped) return `${mapped[1]}.0`; const v4 = ip.match(/^(\d+\.\d+\.\d+)\.\d+$/); if (v4) return `${v4[1]}.0`; const v6parts = ip.split(":"); if (v6parts.length >= 3) return `${v6parts.slice(0, 3).join(":")}::`; return "0.0.0.0"; } export type DeviceType = "mobile" | "tablet" | "desktop"; export type BrowserName = "Chrome" | "Firefox" | "Safari" | "Edge" | "Opera" | "Other"; export type OsName = "Windows" | "macOS" | "iOS" | "Android" | "Linux" | "Other"; export function parseDevice(ua: string): DeviceType { if (/tablet|ipad|playbook|silk/i.test(ua)) return "tablet"; if (/mobile|android.*mobile|iphone|ipod|blackberry|windows phone/i.test(ua)) return "mobile"; return "desktop"; } export function parseBrowser(ua: string): BrowserName { if (/edg\//i.test(ua)) return "Edge"; if (/opr\//i.test(ua)) return "Opera"; if (/firefox\//i.test(ua)) return "Firefox"; if (/chrome\//i.test(ua)) return "Chrome"; if (/safari\//i.test(ua)) return "Safari"; return "Other"; } export function parseOs(ua: string): OsName { if (/windows/i.test(ua)) return "Windows"; if (/iphone|ipad|ipod/i.test(ua)) return "iOS"; if (/android/i.test(ua)) return "Android"; if (/mac os x|macintosh/i.test(ua)) return "macOS"; if (/linux/i.test(ua)) return "Linux"; return "Other"; }