RefAnalysis — Sistema de Avaliação Arbitral FIBA IOT v2.5
R
RefAnalysis
Arbitragem FIBA-Compliant
FIBA IOT v2.5 · 3PO Crew
Configurar nova avaliação
Cadastre o jogo e o crew de 3 árbitros (CC + U1 + U2). A taxonomia FIBA IOT v2.5 é aplicada em todas as marcações.
Dados do jogo
Crew de arbitragem (3PO)
CREW CHIEF (CC)
CC
UMPIRE 1 (U1)
U1
UMPIRE 2 (U2)
U2
Fonte de vídeo
Modo clipes: cada lance é marcado sem timestamp automático. O tempo de jogo é inserido manualmente.
JOGO
—
CREW 3PO
—
LANCES
0
Nenhum vídeo carregado
Volte para "Configurar jogo" e selecione uma fonte.
Q1 00:00
Dica:Cada lance exige identificar (1) o árbitro primário da ação e (2) a posição dele no momento: L, C ou T. Em INCs, o sistema pondera responsabilidade compartilhada do crew.
Controle de quarto
Q1
Q2
Q3
Q4
OT1
OT2
Lances marcados0
Nenhum lance marcado ainda. Clique em "Novo lance" para começar.
Avaliação qualitativa do crew
📊
Sem dados ainda. Marque ao menos um lance para gerar o relatório.
Exportar dados
Baixe os dados da avaliação em JSON, CSV, HTML ou PDF. O JSON inclui a estrutura completa do crew.
📄
PDF
Relatório PDF completo para enviar ao árbitro ou arquivar. Inclui crew + dashboard individual de cada árbitro.
📊
CSV
Uma linha por lance. Inclui árbitro primário, posição L/C/T e responsabilidade compartilhada.
🌐
HTML imprimível
Relatório completo em nova janela: visão do crew + dashboard individual de cada árbitro. Pronto para salvar como PDF.
{ }
JSON
Estrutura completa: jogo, crew de 3 árbitros, todos os lances com atribuições individuais e responsabilidade compartilhada (INC).
Gerenciar sessão
Os dados são salvos no navegador (localStorage). Para começar novo jogo, limpe a sessão atual.
Novo lance — FIBA IOT v2.5 · 3PO Crew
1. Tempo de jogo
Automaticamente marcado (Q4 ≤ 2:00 ou prorrogação)
2. Árbitro primário do lance
CC
—
U1
—
U2
—
LEAD
CENTER
TRAIL
3. Classificação da decisão
CC
Correct Call
CNC
Correct Non-Call
IC
Incorrect Call
INC
Incorrect Non-Call
INC — Responsabilidade compartilhada:o árbitro primário receberá 70% do peso negativo e os outros 2 árbitros dividirão 30%. Isso reflete a mecânica FIBA: o lance está na área primária de um, mas o crew inteiro falhou em identificá-lo.
4. Tipo de evento
5. Critérios de contato FIBA (Criteria for Contact)
Afetado
Marginal
Não afetado
Respeitado
Invadido
Vertical
Lateral
N/A
Estabelecida
Tardia
Não estabelecida
Obtida
Neutra
Sem vantagem
Soft
Hard
Excessive
6. Action Area FIBA
7. Análise do erro (IC / INC)
8. Comentário do instrutor
`;
const w = window.open("", "_blank");
w.document.write(html);
w.document.close();
toast(lang==='pt'?"HTML aberto ✓":lang==='es'?"HTML abierto ✓":"HTML opened ✓", "success");
}
function importJSON() { document.getElementById("import-file").click(); }
function handleImport(e) {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = ev => {
try {
const data = JSON.parse(ev.target.result);
if (data.game) state.game = data.game;
if (data.crew) state.crew = data.crew;
if (data.evaluator) state.evaluator = data.evaluator;
if (data.events) state.events = data.events;
if (data.qualitative) state.qualitative = data.qualitative;
saveState();
restoreSetupForm();
renderEvents();
updateGameInfoBar();
toast(state.lang==='pt'?"Dados importados ✓":state.lang==='es'?"Datos importados ✓":"Data imported ✓", "success");
} catch (err) { toast(state.lang==='pt'?"Erro: JSON inválido":state.lang==='es'?"Error: JSON inválido":"Error: invalid JSON", "error"); }
};
reader.readAsText(file);
}
function resetSession() {
const msg = state.lang === "pt" ? "Limpar todos os dados?" : state.lang === "es" ? "¿Borrar datos?" : "Clear all data?";
if (!confirm(msg)) return;
localStorage.removeItem(STORAGE_KEY);
location.reload();
}
// ==================== DEMO DATA ====================
function loadDemoData() {
document.getElementById("f-competition").value = "Liga Nacional 2025/26 — Playoffs Semifinais";
document.getElementById("f-date").value = "2026-04-15";
document.getElementById("f-home").value = "Flamengo";
document.getElementById("f-away").value = "Minas";
document.getElementById("f-venue").value = "Maracanãzinho";
document.getElementById("f-evaluator").value = "Ramiro Inchauspe";
document.getElementById("f-ref-cc-name").value = "Maria Santos";
document.getElementById("f-ref-cc-level").value = "international";
document.getElementById("f-ref-u1-name").value = "João Oliveira";
document.getElementById("f-ref-u1-level").value = "national";
document.getElementById("f-ref-u2-name").value = "Ana Costa";
document.getElementById("f-ref-u2-level").value = "national";
state.events = [
{ id:"d1", decision:"CC", primaryRef:"cc", position:"L", quarter:1, gameClock:"08:42", videoTime:78, eventType:"foul", eventSubtype:"defensive", contactCriteria:{rsbq:"affected",cylinder:"invaded",verticality:"lateral",lgp:"not_established",advantage:"gained",severity:"hard"}, actionArea:"on_ball_drive", areaStatus:"true", errorReason:null, comment:"CC como Lead — LGP mal estabelecida, apito correto.", markedAt:new Date().toISOString(), taxonomyVersion:"fiba_iot_v25" },
{ id:"d2", decision:"CNC", primaryRef:"u1", position:"T", quarter:1, gameClock:"05:18", videoTime:282, eventType:"foul", eventSubtype:"rebounding", contactCriteria:{rsbq:"not_affected",cylinder:"respected",verticality:"vertical",lgp:"established",advantage:"neutral",severity:"soft"}, actionArea:"rebound", areaStatus:"true", errorReason:null, comment:"U1 em Trail — contato incidental, correto no-call.", markedAt:new Date().toISOString(), taxonomyVersion:"fiba_iot_v25" },
{ id:"d3", decision:"CC", primaryRef:"u2", position:"C", quarter:2, gameClock:"07:22", videoTime:758, eventType:"foul", eventSubtype:"shooting", contactCriteria:{rsbq:"affected",cylinder:"invaded",verticality:"lateral",lgp:"late",advantage:"gained",severity:"hard"}, actionArea:"on_ball_drive", areaStatus:"true", errorReason:null, comment:"U2 em Center — shooting foul claro, 2 LLs.", markedAt:new Date().toISOString(), taxonomyVersion:"fiba_iot_v25" },
{ id:"d4", decision:"IC", primaryRef:"u1", position:"T", quarter:2, gameClock:"03:45", videoTime:1035, eventType:"foul", eventSubtype:"defensive", contactCriteria:{rsbq:"not_affected",cylinder:"respected",verticality:"vertical",lgp:"established",advantage:"none",severity:"soft"}, actionArea:"pnr", areaStatus:"secondary", errorReason:"rsbq_misread", comment:"U1 apitou no PnR com RSBQ não afetado — IC.", markedAt:new Date().toISOString(), taxonomyVersion:"fiba_iot_v25" },
{ id:"d5", decision:"CC", primaryRef:"cc", position:"L", quarter:2, gameClock:"01:12", videoTime:1288, eventType:"violation", eventSubtype:"travelling", contactCriteria:null, actionArea:"on_ball_drive", areaStatus:"true", errorReason:null, comment:"Travelling claro identificado pelo CC.", markedAt:new Date().toISOString(), taxonomyVersion:"fiba_iot_v25" },
{ id:"d6", decision:"CC", primaryRef:"u2", position:"T", quarter:3, gameClock:"09:33", videoTime:1567, eventType:"foul", eventSubtype:"offensive", contactCriteria:{rsbq:"affected",cylinder:"respected",verticality:"vertical",lgp:"established",advantage:"gained",severity:"hard"}, actionArea:"on_ball_drive", areaStatus:"true", errorReason:null, comment:"U2 em Trail — charge bem chamada, LGP estabelecida.", markedAt:new Date().toISOString(), taxonomyVersion:"fiba_iot_v25" },
{ id:"d7", decision:"INC", primaryRef:"cc", position:"L", quarter:3, gameClock:"06:48", videoTime:1762, eventType:"foul", eventSubtype:"illegal_hands", contactCriteria:{rsbq:"affected",cylinder:"invaded",verticality:"na",lgp:"not_established",advantage:"gained",severity:"hard"}, actionArea:"post_play", areaStatus:"true", errorReason:"angle_blocked", comment:"INC em post play — CC com ângulo obstruído. Crew falhou em ajudar.", markedAt:new Date().toISOString(), taxonomyVersion:"fiba_iot_v25" },
{ id:"d8", decision:"CC", primaryRef:"u1", position:"C", quarter:3, gameClock:"02:01", videoTime:2045, eventType:"foul", eventSubtype:"unsportsmanlike_c2", contactCriteria:{rsbq:"affected",cylinder:"invaded",verticality:"lateral",lgp:"not_established",advantage:"gained",severity:"hard"}, actionArea:"transition", areaStatus:"true", errorReason:null, comment:"U1 em Center — C2 em transição identificada corretamente.", markedAt:new Date().toISOString(), taxonomyVersion:"fiba_iot_v25" },
{ id:"d9", decision:"CC", primaryRef:"u2", position:"T", quarter:4, gameClock:"04:22", videoTime:2398, eventType:"foul", eventSubtype:"shooting", contactCriteria:{rsbq:"affected",cylinder:"invaded",verticality:"lateral",lgp:"late",advantage:"gained",severity:"hard"}, actionArea:"catch_shoot", areaStatus:"true", errorReason:null, comment:"U2 em Trail — shooting em 3pts, 3 LLs.", markedAt:new Date().toISOString(), taxonomyVersion:"fiba_iot_v25" },
{ id:"d10", decision:"CC", primaryRef:"cc", position:"C", quarter:4, gameClock:"01:08", videoTime:2612, eventType:"violation", eventSubtype:"24_seconds", contactCriteria:null, actionArea:"off_ball", areaStatus:"true", errorReason:null, comment:"CC em Center — 24s violados.", markedAt:new Date().toISOString(), taxonomyVersion:"fiba_iot_v25" },
{ id:"d11", decision:"CC", primaryRef:"u1", position:"L", quarter:4, gameClock:"00:18", videoTime:2688, eventType:"foul", eventSubtype:"defensive", contactCriteria:{rsbq:"affected",cylinder:"invaded",verticality:"lateral",lgp:"not_established",advantage:"gained",severity:"hard"}, actionArea:"on_ball_drive", areaStatus:"true", errorReason:null, comment:"U1 em Lead — clutch time, falta bem marcada sob pressão.", markedAt:new Date().toISOString(), taxonomyVersion:"fiba_iot_v25", isClutch:true },
{ id:"d12", decision:"CNC", primaryRef:"u2", position:"T", quarter:4, gameClock:"00:04", videoTime:2704, eventType:"foul", eventSubtype:"defensive", contactCriteria:{rsbq:"marginal",cylinder:"respected",verticality:"vertical",lgp:"established",advantage:"neutral",severity:"soft"}, actionArea:"catch_shoot", areaStatus:"true", errorReason:null, comment:"U2 em Trail — contato mínimo, correto no-call na última posse.", markedAt:new Date().toISOString(), taxonomyVersion:"fiba_iot_v25", isClutch:true },
{ id:"d13", decision:"INC", primaryRef:"u2", position:"C", quarter:3, gameClock:"04:15", videoTime:1892, eventType:"foul", eventSubtype:"defensive", contactCriteria:{rsbq:"affected",cylinder:"invaded",verticality:"lateral",lgp:"not_established",advantage:"gained",severity:"hard"}, actionArea:"pnr", areaStatus:"true", errorReason:"focus", comment:"U2 em Center — falta defensiva no PnR não vista. Crew falhou em assistir.", markedAt:new Date().toISOString(), taxonomyVersion:"fiba_iot_v25" },
{ id:"d14", decision:"IC", primaryRef:"cc", position:"L", quarter:1, gameClock:"06:30", videoTime:210, eventType:"foul", eventSubtype:"offensive", contactCriteria:{rsbq:"not_affected",cylinder:"respected",verticality:"vertical",lgp:"established",advantage:"none",severity:"soft"}, actionArea:"post_play", areaStatus:"true", errorReason:"rsbq_misread", comment:"CC como Lead — charge chamada sem contato real. IC.", markedAt:new Date().toISOString(), taxonomyVersion:"fiba_iot_v25" },
{ id:"d15", decision:"CC", primaryRef:"u2", position:"L", quarter:3, gameClock:"01:30", videoTime:2100, eventType:"foul", eventSubtype:"shooting", contactCriteria:{rsbq:"affected",cylinder:"invaded",verticality:"lateral",lgp:"late",advantage:"gained",severity:"hard"}, actionArea:"on_ball_drive", areaStatus:"true", errorReason:null, comment:"U2 após rotação, em Lead — shooting foul claro.", markedAt:new Date().toISOString(), taxonomyVersion:"fiba_iot_v25" }
];
state.qualitative = {
teamwork: "Rotações limpas entre CC e U2 no Q3. Comunicação não-verbal adequada em clutch time. Perdeu-se sincronia no PnR defensivo em duas situações do Q2.",
strengths: "Excelente identificação de C2 em transição (lance #8). Consistência nos clutch calls do Q4 (lances #11 e #12). Travelling calls claros do CC.",
improvements: "Atenção a post play quando CC está com ângulo obstruído (lance #7) — U1/U2 devem reforçar help. Reduzir false positives em PnR (lance #4)."
};
saveState();
toast(state.lang === "pt" ? "Demo carregado — 15 lances, crew completo ✓" : state.lang === "es" ? "Demo cargado ✓" : "Demo loaded ✓", "success");
}
function restoreSetupForm() {
if (state.game.competition) document.getElementById("f-competition").value = state.game.competition;
if (state.game.date) document.getElementById("f-date").value = state.game.date;
if (state.game.homeTeam) document.getElementById("f-home").value = state.game.homeTeam;
if (state.game.awayTeam) document.getElementById("f-away").value = state.game.awayTeam;
if (state.game.venue) document.getElementById("f-venue").value = state.game.venue;
if (state.game.quarterDurationMin) document.getElementById("f-quarter-duration").value = state.game.quarterDurationMin;
if (state.evaluator) document.getElementById("f-evaluator").value = state.evaluator;
["cc","u1","u2"].forEach(r => {
if (state.crew[r]?.name) document.getElementById(`f-ref-${r}-name`).value = state.crew[r].name;
if (state.crew[r]?.level) document.getElementById(`f-ref-${r}-level`).value = state.crew[r].level;
});
if (state.qualitative.teamwork) document.getElementById("qual-teamwork").value = state.qualitative.teamwork;
if (state.qualitative.strengths) document.getElementById("qual-strengths").value = state.qualitative.strengths;
if (state.qualitative.improvements) document.getElementById("qual-improvements").value = state.qualitative.improvements;
}
// ==================== TOAST ====================
function toast(msg, type) {
const c = document.getElementById("toast-container");
const el = document.createElement("div");
el.className = "toast " + (type || "");
el.textContent = msg;
c.appendChild(el);
setTimeout(() => { el.style.opacity = "0"; el.style.transform = "translateX(400px)"; el.style.transition = "all 0.3s"; }, 2400);
setTimeout(() => el.remove(), 2800);
}
// ==================== KEYBOARD ====================
document.addEventListener("keydown", e => {
if (e.target.tagName === "INPUT" || e.target.tagName === "TEXTAREA" || e.target.tagName === "SELECT") return;
if (!document.getElementById("view-evaluate").classList.contains("active")) return;
if (e.key === " ") { e.preventDefault(); togglePlay(); }
else if (e.key === "m" || e.key === "M") { e.preventDefault(); openEventModal(); }
else if (e.key === "ArrowLeft") { e.preventDefault(); seekRel(-5); }
else if (e.key === "ArrowRight") { e.preventDefault(); seekRel(5); }
});
// ==================== INIT ====================
loadState();
document.getElementById("langSelect").value = state.lang;
setLanguage(state.lang);
restoreSetupForm();
renderEvents();
updateGameInfoBar();
updateSubtype();
["qual-teamwork","qual-strengths","qual-improvements"].forEach(id => {
const el = document.getElementById(id);
if (el) el.addEventListener("blur", () => {
state.qualitative.teamwork = document.getElementById("qual-teamwork").value;
state.qualitative.strengths = document.getElementById("qual-strengths").value;
state.qualitative.improvements = document.getElementById("qual-improvements").value;
saveState();
});
});