Spaces:
Sleeping
Sleeping
| // Format numbers to 2-3 decimal places for better readability | |
| export const formatNumber = (num, decimals = 2) => { | |
| if (typeof num !== 'number' || isNaN(num)) return '0.00'; | |
| return Number(num.toFixed(decimals)); | |
| }; | |
| // Format risk score with appropriate color class | |
| export const getRiskLevel = (score) => { | |
| if (score < 0.3) return { level: 'Low', class: 'risk-low' }; | |
| if (score < 0.7) return { level: 'Medium', class: 'risk-medium' }; | |
| return { level: 'High', class: 'risk-high' }; | |
| }; | |
| // Format timestamp to readable time | |
| export const formatTime = (timestamp) => { | |
| try { | |
| const date = new Date(timestamp); | |
| return date.toLocaleTimeString('en-US', { | |
| hour: 'numeric', | |
| minute: '2-digit', | |
| second: '2-digit', | |
| hour12: true | |
| }); | |
| } catch (error) { | |
| return 'Invalid time'; | |
| } | |
| }; | |
| // Format device ID for display | |
| export const formatDeviceId = (vid, pid) => { | |
| return `${vid}/${pid}`; | |
| }; | |
| // Calculate progress bar width and color | |
| export const getProgressBarStyle = (value, type = 'default') => { | |
| const width = Math.max(0, Math.min(100, value * 100)); | |
| let backgroundColor = '#3b82f6'; // Default blue | |
| switch (type) { | |
| case 'risk': | |
| if (value > 0.7) backgroundColor = '#dc2626'; // Red | |
| else if (value > 0.3) backgroundColor = '#d97706'; // Orange | |
| else backgroundColor = '#059669'; // Green | |
| break; | |
| case 'ml-score': | |
| if (value > 0.7) backgroundColor = '#dc2626'; // Red for high anomaly | |
| else if (value > 0.3) backgroundColor = '#d97706'; // Orange for medium | |
| else backgroundColor = '#059669'; // Green for low anomaly | |
| break; | |
| case 'confidence': | |
| if (value > 0.8) backgroundColor = '#1e59f0'; // Blue for high confidence | |
| else if (value > 0.6) backgroundColor = '#d97706'; // Orange for medium | |
| else backgroundColor = '#dc2626'; // Red for low confidence | |
| break; | |
| default: | |
| backgroundColor = '#3b82f6'; // Default blue | |
| } | |
| return { | |
| width: `${width}%`, | |
| backgroundColor, | |
| }; | |
| }; | |
| // Device reference database | |
| export const DEVICE_DATABASE = { | |
| '0x046d': { | |
| name: 'Logitech', | |
| devices: { | |
| '0xc077': 'MX Master 3', | |
| '0xc52b': 'MX Master 2S', | |
| '0xc548': 'MX Master 3S', | |
| '0xc52f': 'MX Anywhere 2S', | |
| '0xc541': 'MX Anywhere 3', | |
| '0xc52e': 'G Pro Wireless', | |
| '0xc539': 'G Pro X Superlight', | |
| '0xc534': 'G502 Hero', | |
| '0xc332': 'G403 Hero', | |
| '0xc336': 'G703 Hero', | |
| } | |
| }, | |
| '0x045e': { | |
| name: 'Microsoft', | |
| devices: { | |
| '0x00cb': 'Surface Mouse', | |
| '0x00f6': 'Surface Precision Mouse', | |
| '0x0745': 'Wireless Mouse 5000', | |
| '0x07a5': 'Wireless Mouse 4000', | |
| '0x07b2': 'Wireless Mouse 3000', | |
| } | |
| }, | |
| '0x1532': { | |
| name: 'Razer', | |
| devices: { | |
| '0x0067': 'DeathAdder V2', | |
| '0x0073': 'Viper Ultimate', | |
| '0x007c': 'Basilisk V3', | |
| '0x0084': 'Naga Pro', | |
| '0x0090': 'DeathAdder V3 Pro', | |
| } | |
| }, | |
| '0x1038': { | |
| name: 'SteelSeries', | |
| devices: { | |
| '0x1384': 'Rival 600', | |
| '0x1392': 'Rival 650', | |
| '0x1394': 'Rival 710', | |
| '0x1396': 'Sensei 310', | |
| '0x1398': 'Rival 310', | |
| } | |
| } | |
| }; | |
| // Get device information from VID/PID | |
| export const getDeviceInfo = (vid, pid) => { | |
| const vendor = DEVICE_DATABASE[vid]; | |
| if (!vendor) { | |
| return { | |
| vendor: 'Unknown', | |
| model: 'Unknown Device', | |
| fullName: `${vid}/${pid}` | |
| }; | |
| } | |
| const model = vendor.devices[pid] || 'Unknown Model'; | |
| return { | |
| vendor: vendor.name, | |
| model, | |
| fullName: `${vendor.name} ${model}` | |
| }; | |
| }; | |