const randomChars = () => { const uppercaseAsciiStart = 65; const letterIndex = Math.floor(Math.random() * 26); const letter = String.fromCharCode(uppercaseAsciiStart + letterIndex); return letter; }; 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(); }); }