import switchSound from "../assets/sounds/ui/switch.mp3"; import popup from "../assets/sounds/ui/popup_open.mp3"; import notification from "../assets/sounds/ui/notification.mp3"; import beep from "../assets/sounds/ui/Beep.wav"; import warning from "../assets/sounds/ui/Warning.wav"; import ding from "../assets/sounds/ui/Ding.wav"; import shutter from "../assets/sounds/ui/shutter.mp3"; import attention from "../assets/sounds/ui/Attention.wav"; import type { HotlistMatches, SightingType } from "../types/types"; export function getSoundFileURL(name: string) { const sounds: Record = { switch: switchSound, popup: popup, notification: notification, beep: beep, warning: warning, ding: ding, shutter: shutter, attention: attention, }; return sounds[name] ?? null; } export const showSoundURL = (url: URL | string | undefined) => { console.log(url); }; const randomChars = () => { const uppercaseAsciiStart = 65; const letterIndex = Math.floor(Math.random() * 26); const letter = String.fromCharCode(uppercaseAsciiStart + letterIndex); return letter; }; export function cleanArray(str: string) { const toArr = str?.split(","); const cleaned = toArr?.map((el: string) => { const test = el.replace(/[^0-9a-z]/gi, ""); return test; }); return cleaned; } export function parseRTSPUrl(url: string) { const regex = /rtsp:\/\/([^:]+):([^@]+)@([^:/]+):?(\d+)?(\/.*)?/; const match = url?.match(regex); if (!match) { return null; } return { username: match[1], password: match[2], ip: match[3], port: match[4] || "554", // default RTSP port path: match[5] || "/", }; } const generateNumberPlate = () => { const numberPlateLetters = new Array(4); const characters: string[] = []; for (let index = 0; index <= numberPlateLetters.length; index++) { const letter = randomChars(); characters.push(letter); } const number = Math.floor(Math.random() * 99); characters.splice(2, 0, number + " "); const numberPlate = characters.join(""); return numberPlate; }; export const generateNumberPlateList = (numberofSightings = 5) => { const numberPlates = []; for (let i = 0; i <= numberofSightings; i++) { numberPlates.push(generateNumberPlate()); } return numberPlates; }; export const formatNumberPlate = (plate: string) => { const splittedPlate = plate?.split(""); splittedPlate?.splice(4, 0, " "); const formattedPlate = splittedPlate?.join(""); return formattedPlate; }; export const BLANK_IMG = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; export function capitalize(s?: string) { return s ? s.charAt(0).toUpperCase() + s.slice(1) : ""; } export function formatAge(tsMillis: number) { const ms = Date.now() - tsMillis; const seconds = 5 * Math.floor(ms / 5000); // quantize to 5s like the original const d = Math.floor(seconds / (3600 * 24)); const h = Math.floor((seconds % (3600 * 24)) / 3600); const m = Math.floor((seconds % 3600) / 60); const s = Math.floor(seconds % 60); if (d > 0) return `${d}d ago`; if (h > 0) return `${h}h ago`; if (m > 0) return `${m}m ago`; return `${s}s ago`; } export function drawRects( canvas: HTMLCanvasElement, imageEl: HTMLImageElement, rects: [number, number, number, number][], color: string ) { const ctx = canvas.getContext("2d"); if (!ctx) return; // Ensure canvas size matches displayed image size const w = imageEl.clientWidth || imageEl.naturalWidth; const h = imageEl.clientHeight || imageEl.naturalHeight; if (canvas.width !== w) canvas.width = w; if (canvas.height !== h) canvas.height = h; ctx.imageSmoothingEnabled = false; ctx.lineWidth = 1; ctx.strokeStyle = color; rects.forEach((r) => { const [x, y, rw, rh] = r; ctx.beginPath(); ctx.rect(Math.round(x * w), Math.round(y * h), Math.round(rw * w), Math.round(rh * h)); ctx.stroke(); }); } export const checkIsHotListHit = (sigthing: SightingType | null) => { if (!sigthing) return; if (sigthing?.metadata?.hotlistMatches) { const isHotListHit = Object.values(sigthing?.metadata?.hotlistMatches).includes(true); return isHotListHit; } }; export function getHotlistName(obj: HotlistMatches | undefined) { if (!obj) return; const hotlistNames = Object.entries(obj) .filter(([, value]) => value === true) .map(([key]) => key); return hotlistNames; } export const getNPEDCategory = (r?: SightingType | null) => r?.metadata?.npedJSON?.["NPED CATEGORY"] as "A" | "B" | "C" | "D" | undefined; export const zoomMapping = (zoomLevel: number | undefined) => { switch (zoomLevel) { case 1: return "Near"; case 2: return "Mid"; case 4: return "Far"; default: break; } }; export const reverseZoomMapping = (magnification: string) => { switch (magnification) { case "near": return 1; case "mid": return 2; case "far": return 4; default: break; } }; export const ValidateIPaddress = (value: string | undefined) => { if (!value) return; const regex = /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/; if (!regex.test(value)) { return "Invalid IP address format"; } };