/* global React, Icon, useLiveThreatData, geoForVendor, severityFor, REGIONS, useCountUp, forceResync */ const { useState: useS_dm, useEffect: useE_dm, useMemo: useM_dm } = React; /* ────────────────────────────────────────────── SOC PANEL — backed by real CISA KEV data ────────────────────────────────────────────── */ function SocPanel() { const live = useLiveThreatData(); const [tick, setTick] = useS_dm(0); useE_dm(() => { const id = setInterval(() => setTick((t) => t + 1), 1800); return () => clearInterval(id); }, []); // Count-up animation on the headline numbers const totalCount = useCountUp(live.loading ? 0 : live.total); const ransomCount = useCountUp(live.loading ? 0 : live.ransomware); const recent30Count = useCountUp(live.loading ? 0 : live.last30d); const now = Date.now(); const recent = live.recent || []; // Round-robin by region to guarantee geographic diversity — always plot at // least one ping per inhabited region per cycle. CISA KEV is dominated by // US vendors, so without this the map looks like only the US is attacked. const slice = useM_dm(() => { if (!recent.length) return []; // Bucket CVEs by region using vendor mapping const byRegion = {}; recent.forEach((item) => { const geo = geoForVendor(item.vendorProject); const code = (geo && geo.region) || "NA"; (byRegion[code] = byRegion[code] || []).push(item); }); const cursors = {}; const out = []; const n = 9; // total simultaneous pings for (let i = 0; i < n; i++) { const reg = REGIONS[(tick + i) % REGIONS.length]; const bucket = byRegion[reg.code] || []; cursors[reg.code] = (cursors[reg.code] || 0) + 1; let geo, sev, item; if (bucket.length) { item = bucket[(cursors[reg.code] + tick) % bucket.length]; geo = geoForVendor(item.vendorProject) || reg; sev = severityFor(item, now); } else { // No CVEs in current data for this region — plot a "regional activity" // ping anchored at the region centroid so the map shows global presence. geo = reg; sev = "low"; } // Tight jitter so identical-region pings don't overlap const jx = ((i * 37 + tick * 11) % 7) - 3; const jy = ((i * 19 + tick * 7) % 5) - 2; out.push({ id: (item ? item.cveID : reg.code) + ":" + i + ":" + tick, x: Math.max(4, Math.min(96, (geo.x ?? reg.x) + jx)), y: Math.max(8, Math.min(82, (geo.y ?? reg.y) + jy)), sev, }); } return out; }, [recent, tick]); // Local time + timezone abbreviation — reads from the user's system clock, // so it auto-adapts: BRT for visitors in Brazil, EST for NY, etc. // No IP lookup needed (and no consent banner). const localTime = new Date().toLocaleTimeString("pt-BR", { hour12: false }); const tzAbbr = (() => { try { const parts = new Intl.DateTimeFormat("en-US", { timeZoneName: "short" }).formatToParts(new Date()); return (parts.find((p) => p.type === "timeZoneName") || {}).value || "UTC"; } catch { return ""; } })(); const ringPct = live.loading ? 0 : Math.max(8, Math.min(98, Math.round(100 - (live.last7d / Math.max(1, live.last30d)) * 100))); const ringDisplay = useCountUp(ringPct); const sourceLabel = live.source === "cisa" ? "CISA · LIVE" : live.source === "cache" ? "CISA · CACHE" : live.source === "snapshot" ? "CISA · SNAPSHOT" : "CARREGANDO"; const syncWhen = live.fetchedAt ? new Date(live.fetchedAt).toLocaleTimeString("pt-BR", { hour: "2-digit", minute: "2-digit", second: "2-digit" }) : "—"; const sevCount = { high: 0, med: 0, low: 0 }; recent.forEach((it) => { sevCount[severityFor(it, now)]++; }); return (
THREAT INTEL · {sourceLabel}
SA‑EAST · BRZ / {tzAbbr} {localTime}
{slice.map((t) => ( ))} BRZ‑01 {live.loading && SINCRONIZANDO CISA KEV …}
{sevCount.high} críticas {sevCount.med} recentes {sevCount.low} históricas sync: {syncWhen} / fonte: cisa.gov/kev
); } function Ring({ percent }) { const r = 28, c = 2 * Math.PI * r; const off = c - (c * percent) / 100; return ( ); } function WorldMap() { const cols = 38, rows = 14; const M = [ "00001111110000000111111111111100000000", "00111111111111000111111111111111100000", "01111111111111101111111111111111110000", "11111111111111101111111111111111111100", "01111111111110001111111111111111111100", "00111111111100000111111111111111111000", "00011111111000000011111111111111110000", "00001111110000000001111111111111100000", "00000111100000000000111111111111000000", "00000011000000000000011111111110000000", "00000011000000000000000111111100000000", "00000001000000000000000011110000000000", "00000000000000000000000001000000000000", "00000000000000000000000000000000000000", ]; const dots = []; for (let r = 0; r < rows; r++) { for (let c = 0; c < cols; c++) { if (M[r] && M[r][c] === "1") { dots.push({ x: (c + 0.5) * (100 / cols), y: (r + 0.5) * (100 / rows) }); } } } return ( {dots.map((d, i) => ( ))} ); } /* ────────────────────────────────────────────── DASHMOCK — Cyber Investigator dashboard mock (uses real CVE rows in the timeline) ────────────────────────────────────────────── */ function DashMock() { const live = useLiveThreatData(); const [t, setT] = useS_dm(0); useE_dm(() => { const id = setInterval(() => setT((x) => x + 1), 900); return () => clearInterval(id); }, []); const bars = Array.from({ length: 24 }).map((_, i) => { const h = 18 + ((Math.sin((i + t) * 0.5) + 1) / 2) * 70 + (i % 5 === 0 ? 12 : 0); return Math.min(100, h); }); const events = (live.recent || []).slice(0, 5).map((e) => ({ t: e.dateAdded ? e.dateAdded.slice(0, 10) : "—", lvl: e.knownRansomwareCampaignUse === "Known" ? "HIGH" : (Date.now() - new Date(e.dateAdded).getTime()) < 30 * 86400000 ? "MED" : "OK", cve: e.cveID, msg: `${e.vendorProject} · ${e.product}`, who: "CISA KEV", })); const total = live.loading ? "—" : live.total.toLocaleString("pt-BR"); const trend = live.last7d ? `▲ ${live.last7d} novas (7d)` : "estável"; return (
CYBER INVESTIGATOR · console
tenant: crimesolution
CVES EXPLORADAS (CISA)
{total} {trend}
↳ catálogo oficial · atualizado em tempo real
Atividade ilustrativa · 30 min linha de base 42 ev/m
{bars.map((h, i) => ( 80 ? "hot" : h > 55 ? "warm" : "")} style={{ height: h + "%" }} /> ))}
CVEs mais recentes · CISA KEV filtros: alta · médio
    {events.length === 0 && (
  • sincronizando feed CISA…
  • )} {events.map((e, i) => (
  • {e.t} {e.lvl} {e.cve} · {e.msg} {e.who}
  • ))}
); } /* ────────────────────────────────────────────── HERO TICKER — pulls real CVE IDs when available ────────────────────────────────────────────── */ function HeroTicker() { const live = useLiveThreatData(); const fallback = [ "edge/sa-east-1 · TLS handshake OK", "leak-watch · 0 novas exposições", "iam-sentinel · 1 permissão revisada", ]; const items = (live.recent && live.recent.length) ? live.recent.slice(0, 14).map((e) => `${e.cveID} · ${e.vendorProject} ${e.product}`) : fallback; return ( ); } Object.assign(window, { SocPanel, DashMock, HeroTicker, Ring });