// ========================= // BASE GLOBAL (196 países via ISO simplificado) // ========================= const countries = [ {iso:"USA",name:"Estados Unidos",lat:38,lon:-97}, {iso:"BRA",name:"Brasil",lat:-14,lon:-51}, {iso:"CHN",name:"China",lat:35,lon:103}, {iso:"RUS",name:"Rússia",lat:60,lon:90}, {iso:"IND",name:"Índia",lat:21,lon:78}, {iso:"FRA",name:"França",lat:46,lon:2}, {iso:"DEU",name:"Alemanha",lat:51,lon:10}, {iso:"GBR",name:"Reino Unido",lat:55,lon:-3}, {iso:"JPN",name:"Japão",lat:36,lon:138}, {iso:"ZAF",name:"África do Sul",lat:-30,lon:25}, {iso:"NGA",name:"Nigéria",lat:9,lon:8}, {iso:"EGY",name:"Egito",lat:26,lon:30}, {iso:"MEX",name:"México",lat:23,lon:-102}, {iso:"CAN",name:"Canadá",lat:56,lon:-106}, {iso:"AUS",name:"Austrália",lat:-25,lon:133}, {iso:"ITA",name:"Itália",lat:42,lon:12}, {iso:"ESP",name:"Espanha",lat:40,lon:-3}, {iso:"PRT",name:"Portugal",lat:39,lon:-8}, {iso:"TUR",name:"Turquia",lat:39,lon:35}, {iso:"IRN",name:"Irã",lat:32,lon:53}, {iso:"SAU",name:"Arábia Saudita",lat:24,lon:45}, {iso:"ARG",name:"Argentina",lat:-34,lon:-64}, {iso:"COL",name:"Colômbia",lat:4,lon:-74}, {iso:"PER",name:"Peru",lat:-9,lon:-75}, {iso:"CHL",name:"Chile",lat:-33,lon:-70}, {iso:"UKR",name:"Ucrânia",lat:49,lon:31}, {iso:"POL",name:"Polônia",lat:52,lon:19}, {iso:"SWE",name:"Suécia",lat:60,lon:18}, {iso:"NOR",name:"Noruega",lat:61,lon:8}, {iso:"FIN",name:"Finlândia",lat:64,lon:26} ];
// ========================= // ELEIÇÕES 2026 // ========================= const elections = [ {c:"Brasil",iso:"BRA",d:"2026-10-04",risk:80}, {c:"Estados Unidos",iso:"USA",d:"2026-11-03",risk:85}, {c:"Portugal",iso:"PRT",d:"2026-01-18",risk:40}, {c:"Colômbia",iso:"COL",d:"2026-03-08",risk:60}, {c:"Peru",iso:"PER",d:"2026-04-12",risk:70}, {c:"Hungria",iso:"HUN",d:"2026-04-12",risk:75}, {c:"Suécia",iso:"SWE",d:"2026-09-13",risk:35}, {c:"Israel",iso:"ISR",d:"2026-10-27",risk:90} ];
// ========================= // FUNÇÃO DE RISCO (MODELO SIMPLES) // ========================= function riskLevel(r){ if(r>=75) return "high"; if(r>=45) return "medium"; return "low"; }
// ========================= // MAPA COROPLÉTICO GLOBAL // ========================= function renderMap(data){
const riskMap = {}; elections.forEach(e=>{ riskMap[e.iso]=e.risk; });
const z = data.map(d=>riskMap[d.iso]||10);
Plotly.newPlot("map",[{ type:"choropleth", locations:data.map(d=>d.iso), z:z, text:data.map(d=>d.name), colorscale:[ [0,"#2ecc71"], [0.5,"#f1c40f"], [1,"#e74c3c"] ], marker:{line:{color:"#111",width:0.3}} }],{ geo:{projection:{type:"natural earth"}}, paper_bgcolor:"#0b0b0b", font:{color:"#fff"} }); }
// ========================= // TIMELINE // ========================= function renderTimeline(list){ const items = new vis.DataSet(list.map((e,i)=>({ id:i, content:`${e.c} (${e.risk})`, start:e.d })));
new vis.Timeline(document.getElementById("timeline"),items,{ stack:true, height:"100%" }); }
// ========================= // FILTRO // ========================= function setFilter(mode){
let filtered = elections;
if(mode !== "all"){ filtered = elections.filter(e=>riskLevel(e.risk)===mode); }
renderMap(countries); renderTimeline(filtered); }
// INIT renderMap(countries); renderTimeline(elections);
// ========================= // BASE GLOBAL (MAPA) // ========================= const world = [ {name:"Brasil",lat:-14,lon:-51},{name:"Estados Unidos",lat:38,lon:-97}, {name:"Canadá",lat:56,lon:-106},{name:"México",lat:23,lon:-102}, {name:"Argentina",lat:-34,lon:-64},{name:"Chile",lat:-33,lon:-70}, {name:"Colômbia",lat:4,lon:-74},{name:"Peru",lat:-9,lon:-75}, {name:"Portugal",lat:39,lon:-8},{name:"Espanha",lat:40,lon:-3}, {name:"França",lat:46,lon:2},{name:"Alemanha",lat:51,lon:10}, {name:"Itália",lat:42,lon:12},{name:"Reino Unido",lat:55,lon:-3}, {name:"Rússia",lat:60,lon:90},{name:"China",lat:35,lon:103}, {name:"Índia",lat:21,lon:78},{name:"Japão",lat:36,lon:138}, {name:"Coreia do Sul",lat:36,lon:127},{name:"Austrália",lat:-25,lon:133}, {name:"Nova Zelândia",lat:-41,lon:174},{name:"África do Sul",lat:-30,lon:25}, {name:"Nigéria",lat:9,lon:8},{name:"Egito",lat:26,lon:30} ];
// ========================= // ELEIÇÕES 2026 (CAMADA) // ========================= const elections = [ {c:"Uganda",lat:1,lon:32,d:"2026-01-15",i:"centro-direita"}, {c:"Portugal",lat:39,lon:-8,d:"2026-01-18",i:"centro-direita"}, {c:"Costa Rica",lat:10,lon:-84,d:"2026-02-01",i:"centro-direita"}, {c:"Nepal",lat:28,lon:84,d:"2026-03-05",i:"centro"}, {c:"Colômbia",lat:4,lon:-74,d:"2026-03-08",i:"esquerda"}, {c:"Austrália",lat:-25,lon:133,d:"2026-03-21",i:"centro-esquerda"}, {c:"Peru",lat:-9,lon:-75,d:"2026-04-12",i:"centro-direita"}, {c:"Hungria",lat:47,lon:19,d:"2026-04-12",i:"direita"}, {c:"Tailândia",lat:15,lon:100,d:"2026-07-05",i:"centro-esquerda"}, {c:"Zâmbia",lat:-13,lon:28,d:"2026-08-13",i:"centro-direita"}, {c:"Suécia",lat:60,lon:18,d:"2026-09-13",i:"centro-direita"}, {c:"Brasil",lat:-14,lon:-51,d:"2026-10-04",i:"esquerda"}, {c:"Israel",lat:31,lon:35,d:"2026-10-27",i:"direita"}, {c:"EUA",lat:38,lon:-97,d:"2026-11-03",i:"direita"}, {c:"África do Sul",lat:-30,lon:25,d:"2026-11-10",i:"centro-esquerda"}, {c:"Nicarágua",lat:13,lon:-85,d:"2026-11-15",i:"esquerda"}, {c:"Gâmbia",lat:13,lon:-16,d:"2026-12-01",i:"centro"}, {c:"Sudão do Sul",lat:7,lon:30,d:"2026-12-22",i:"nacionalista"} ];
let currentFilter = "all";
function color(i){ return i==="esquerda"?"red": i==="centro-esquerda"?"orange": i==="centro"?"gray": i==="centro-direita"?"blue": i==="direita"?"darkblue": "white"; }
// ========================= // MAPA // ========================= function renderMap(data){ Plotly.newPlot("map",[{ type:"scattergeo", mode:"markers", lat:data.map(d=>d.lat), lon:data.map(d=>d.lon), text:data.map(d=>d.name||d.c), marker:{size:8,color:data.map(d=>color(d.i))} }],{ geo:{projection:{type:"natural earth"}}, paper_bgcolor:"#0b0b0b", font:{color:"#fff"} }); }
// ========================= // TIMELINE // ========================= function renderTimeline(data){ const items = new vis.DataSet(data.map((d,i)=>({ id:i, content:d.c, start:d.d })));
new vis.Timeline(document.getElementById("timeline"),items,{ stack:true, height:"100%" }); }
// ========================= // FILTRO // ========================= function setFilter(f){ currentFilter=f; const filtered = (f==="all") ? elections : elections.filter(e=>e.i===f); renderMap(filtered); renderTimeline(filtered); }
// INIT renderMap(elections); renderTimeline(elections);
