`
}
let students=[
{name:'Ana Silva',phone:'(11) 99999-0001',email:'ana@email.com',birth:'1990-05-12',objective:'Força + Emagrecimento',secondary:'Melhorar condicionamento',level:'Intermediário',frequency:'3x/semana',availability:'Segunda, quarta e sexta',modalities:'Musculação e corrida',history:'Treina regularmente há 2 anos.',restrictions:'Sem restrições atuais.',notes:'Priorizar progressão de força.',status:'Ativo'},
{name:'Carlos Lima',phone:'',email:'',birth:'',objective:'Condicionamento',secondary:'',level:'Base',frequency:'2x/semana',availability:'',modalities:'',history:'',restrictions:'',notes:'',status:'Ativo'},
{name:'Mariana Costa',phone:'',email:'',birth:'',objective:'Qualidade de movimento',secondary:'',level:'Base',frequency:'2x/semana',availability:'',modalities:'',history:'',restrictions:'',notes:'',status:'Ativo'}
]; let studentIndex=0;
function newStudent(){studentIndex=-1;go('studentform')}
function editStudent(i){studentIndex=i;go('studentform')}
function saveStudent(){
const ids=['name','phone','email','birth','objective','secondary','level','frequency','availability','modalities','history','restrictions','notes','status'];
let s={}; ids.forEach(id=>s[id]=document.querySelector('#s_'+id)?.value||'');
if(!s.name){alert('Informe o nome do aluno.');return}
if(studentIndex<0){students.push(s);studentIndex=students.length-1}else students[studentIndex]=s;
go('studentprofile')
}
function val(s,k){return (s&&s[k])||''}
let assessments={};
const evalItems=[
['MOBILIDADE','Tornozelo'],['MOBILIDADE','Quadril'],['MOBILIDADE','Torácica'],['MOBILIDADE','Ombro'],
['ESTABILIDADE / CONTROLE','Core'],['ESTABILIDADE / CONTROLE','Lombo-pélvico'],['ESTABILIDADE / CONTROLE','Escápula'],
['PADRÕES DE MOVIMENTO','Dominância de Joelho'],['PADRÕES DE MOVIMENTO','Dominância de Quadril'],['PADRÕES DE MOVIMENTO','Empurrar'],['PADRÕES DE MOVIMENTO','Puxar'],
['CAPACIDADES','Força'],['CAPACIDADES','Equilíbrio'],['CAPACIDADES','Coordenação']
];
function assessmentKey(){return students[studentIndex]?.name||'aluno'}
function currentAssessment(){let k=assessmentKey();if(!assessments[k])assessments[k]={date:new Date().toISOString().slice(0,10),objective:'',pain:'',notes:'',items:{}};return assessments[k]}
function setEval(item,status){currentAssessment().items[item]=status;render()}
function saveAssessment(){
let a=currentAssessment();a.date=document.querySelector('#a_date')?.value||a.date;a.objective=document.querySelector('#a_objective')?.value||'';a.pain=document.querySelector('#a_pain')?.value||'';a.notes=document.querySelector('#a_notes')?.value||'';alert('Avaliação salva no protótipo.');render()
}
function evalColor(s){return s==='Adequado'?'green':s==='Atenção'?'yellow':s==='Prioridade'?'red':''}
let onlineA={goal:'',experience:'Intermediário',place:'Academia',minutes:'45',equipment:'',health:'',surgery:'',meds:'',restriction:'',pain:'Não',painArea:'',painScore:'0',painTime:'',painWorse:'',limitations:'',training:'',breaktime:'',familiar:'',sleep:'Bom',energy:'Boa',routine:'',sports:'',videos:'Não solicitados',decision:'Pendente',notes:''};
let oaStep=1;
function oaSet(k,v){onlineA[k]=v;render()}
function nextOA(){if(oaStep<6){oaStep++;render();scrollTo(0,0)}else saveOA()}
function prevOA(){if(oaStep>1){oaStep--;render();scrollTo(0,0)}else go('studentprofile')}
function saveStepFields(){
const ids=['goal','equipment','minutes','health','surgery','meds','restriction','painArea','painScore','painTime','painWorse','limitations','training','breaktime','familiar','routine','sports'];
ids.forEach(k=>{let e=document.querySelector('#w_'+k);if(e)onlineA[k]=e.value})
}
function nextSave(){saveStepFields();nextOA()}
function prevSave(){saveStepFields();prevOA()}
function choice(k,v){saveStepFields();onlineA[k]=v;render()}
function choiceButtons(k,vals){return `
${vals.map(v=>``).join('')}
`}
function saveOA(){
['goal','experience','place','minutes','equipment','health','surgery','meds','restriction','pain','painArea','painScore','painTime','painWorse','limitations','training','breaktime','familiar','sleep','energy','routine','sports','videos'].forEach(k=>{let e=document.querySelector('#oa_'+k);if(e)onlineA[k]=e.value});
go('onlineReview')
}
function oaAlerts(){let a=[];if(onlineA.pain==='Sim')a.push(`Dor/desconforto: ${onlineA.painArea||'região não informada'} • ${onlineA.painScore}/10`);if(onlineA.restriction.trim())a.push('Recomendação/restrição profissional informada');if(onlineA.surgery.trim())a.push('Cirurgia ou lesão anterior informada');if(onlineA.health.trim())a.push('Informação de saúde para revisão');return a}
function decision(d){onlineA.decision=d;render()}
let selectedStudentIndex=0;
function selectBuilderStudent(i){selectedStudentIndex=Number(i);studentIndex=selectedStudentIndex;render()}
function builderContext(){let s=students[selectedStudentIndex]||students[0],a=onlineA;return {s,a,alerts:oaAlerts()}}
function publishWorkout(){let c=builderContext(),total=workoutDraft.general.length+workoutDraft.specific.length+workoutDraft.blocks.reduce((n,b)=>n+b.length,0);if(!total){alert('Adicione pelo menos um exercício.');return}alert(`Treino publicado para ${c.s.name} • ${selectedType} • ${total} exercícios.`)}
let libFilter='TODOS';
function setLibFilter(f){libFilter=f;render()}
function filteredExercises(){
let f=libFilter.toUpperCase();
if(f==='TODOS')return exerciseDB;
return exerciseDB.filter(e=>(e.cat+' '+e.group+' '+e.level+' '+e.name).toUpperCase().includes(f))
}
function duplicateExercise(kind,bi,item){
let arr=kind==='general'?workoutDraft.general:kind==='specific'?workoutDraft.specific:workoutDraft.blocks[bi];
arr.splice(item+1,0,{...arr[item]});render()
}
function moveExercise(kind,bi,item,dir){
let arr=kind==='general'?workoutDraft.general:kind==='specific'?workoutDraft.specific:workoutDraft.blocks[bi],ni=item+dir;
if(ni<0||ni>=arr.length)return;[arr[item],arr[ni]]=[arr[ni],arr[item]];render()
}
function duplicateBlock(i){ensureBlocks();workoutDraft.blocks.splice(i+1,0,workoutDraft.blocks[i].map(x=>({...x})));blocks++;render()}
function removeBlock(i){if(blocks<=1)return;workoutDraft.blocks.splice(i,1);blocks--;render()}
let workoutTemplates=[
{name:'MMII • BASE',type:'MMII',level:'Base',general:[],specific:[],blocks:[[]]},
{name:'MMII • INTERMEDIÁRIO',type:'MMII',level:'Intermediário',general:[],specific:[],blocks:[[]]},
{name:'MMSS • BASE',type:'MMSS',level:'Base',general:[],specific:[],blocks:[[]]},
{name:'FULL BODY • INTERMEDIÁRIO',type:'FULL BODY',level:'Intermediário',general:[],specific:[],blocks:[[]]}
];
function cloneItems(a){return a.map(x=>({...x}))}
function loadTemplate(i){
let t=workoutTemplates[i];selectedType=t.type;workoutDraft={general:[],specific:[],blocks:t.blocks.map(cloneItems)};blocks=Math.max(1,workoutDraft.blocks.length);go('builder')
}
function saveAsTemplate(){
let n=prompt('Nome do modelo:',''+selectedType+' • NOVO MODELO');if(!n)return;
workoutTemplates.push({name:n,type:selectedType,level:'Personalizado',general:[],specific:[],blocks:workoutDraft.blocks.map(cloneItems)});
alert('Modelo salvo.');go('templates')
}
function deleteTemplate(i){if(confirm('Excluir este modelo?')){workoutTemplates.splice(i,1);render()}}
let studentWorkoutLog={done:{},load:{},reps:{},rpe:'',pain:'Não',painArea:'',note:'',finished:false};
function demoWorkout(){
let has=workoutDraft.general.length+workoutDraft.specific.length+workoutDraft.blocks.reduce((n,b)=>n+b.length,0);
if(has)return workoutDraft;
let pick=n=>({name:n,series:'3',reps:'10',load:'',rest:'60s',obs:''});
return {general:[pick('ESTEIRA')],specific:[pick('MOBILIDADE DE QUADRIL')],blocks:[[pick('AGACHAMENTO'),pick('TERRA KTB')],[pick('REMADA NO TRX'),pick('PRANCHA BÁSICA')]]}
}
function toggleDone(k){studentWorkoutLog.done[k]=!studentWorkoutLog.done[k];render()}
function setLog(k,t,v){studentWorkoutLog[t][k]=v}
function finishStudentWorkout(){studentWorkoutLog.finished=true;go('workoutFeedback')}
function studentExCard(e,k){
let d=studentWorkoutLog.done[k];
return `
${e.name}
${e.series||'-'} séries • ${e.reps||'-'} reps
${e.rest?`Descanso ${e.rest}`:''}
▶ VÍDEO / EXECUÇÃO DO EXERCÍCIO
${e.obs?`
💬 ${e.obs}
`:''}
`
}
let studentWarmups={};
function warmupFor(i=selectedStudentIndex){
if(!studentWarmups[i]) studentWarmups[i]={general:[],specific:[]};
return studentWarmups[i];
}
function warmAddedList(arr,kind){
return arr.map((e,i)=>`
`).join('')
}
function moveWarm(kind,i,d){let a=warmupFor()[kind],n=i+d;if(n<0||n>=a.length)return;[a[i],a[n]]=[a[n],a[i]];render()}
function removeWarm(kind,i){warmupFor()[kind].splice(i,1);render()}
function openWarmPicker(kind){pickerTarget='warm_'+kind;pickerOpen=true;searchTerm='';render()}
function saveWarmup(){alert(`Aquecimento padrão salvo para ${(students[selectedStudentIndex]||students[0]).name}. Ele será usado em todos os treinos deste aluno.`);go('builder')}
let workoutHistory=[
{date:'18/09/2026',name:'Treino A',type:'MMII',rpe:7,pain:'Não',done:100,note:'',loads:'Agachamento 20 kg'},
{date:'16/09/2026',name:'Treino B',type:'MMSS',rpe:6,pain:'Não',done:100,note:'Treino confortável',loads:'Remada 18 kg'},
{date:'14/09/2026',name:'Treino A',type:'MMII',rpe:8,pain:'Sim',painArea:'Joelho',done:92,note:'Desconforto leve no final',loads:'Agachamento 18 kg'}
];
function saveFeedback(){
workoutHistory.unshift({date:new Date().toLocaleDateString('pt-BR'),name:'Treino do dia',type:selectedType||'FULL BODY',rpe:Number(studentWorkoutLog.rpe||5),pain:studentWorkoutLog.pain,painArea:studentWorkoutLog.painArea,done:100,note:studentWorkoutLog.note,loads:Object.values(studentWorkoutLog.load).filter(Boolean).join(' • ')});
studentWorkoutLog={done:{},load:{},reps:{},rpe:'',pain:'Não',painArea:'',note:'',finished:false};go('evolution')
}
function avgRpe(){return workoutHistory.length?(workoutHistory.reduce((s,x)=>s+(Number(x.rpe)||0),0)/workoutHistory.length).toFixed(1):'—'}
function coachStudent(){return students[studentIndex]||students[0]}
function coachHistory(){return workoutHistory}
function attendanceRate(){let h=coachHistory();return h.length?Math.round(h.reduce((s,x)=>s+(Number(x.done)||0),0)/h.length):0}
function painFlags(){return coachHistory().filter(x=>x.pain==='Sim')}
function recentLoads(){return coachHistory().filter(x=>x.loads).slice(0,5)}
const SERVICE_TYPES={
'TREINO':{label:'TREINO',desc:'Aulas em Grupo'},
'PERSONALIZADO':{label:'PERSONALIZADO',desc:'Treinamento individualizado'},
'PERFORMANCE':{label:'PERFORMANCE',desc:'Preparação física e desempenho'}
};
let studentServiceFilter='TODOS';
students.forEach((s,i)=>{if(!s.service)s.service=i%3===0?'TREINO':(i%3===1?'PERSONALIZADO':'PERFORMANCE')});
function serviceCount(type){return students.filter(s=>s.service===type).length}
function serviceLabel(s){return (SERVICE_TYPES[s.service]||SERVICE_TYPES.TREINO).label}
function setServiceFilter(x){studentServiceFilter=x;go('serviceStudents')}
let prescriptionMode='PERSONALIZADO';
let groupClass={name:'Treino Coletivo 01',students:[],blocks:[]};
let performanceSport='CORRIDA',performanceGoal='PROVA / DESEMPENHO';
function openPrescription(type){prescriptionMode=type;go('prescriptionHub')}
function selectGroupStudent(i){let p=groupClass.students.indexOf(i);p>=0?groupClass.students.splice(p,1):groupClass.students.push(i);render()}
let monthlyPrograms=[
{id:1,month:'SETEMBRO',year:2026,status:'PUBLICADO',students:[],workouts:[
{name:'TREINO A',type:'FULL BODY',focus:'Força geral'},
{name:'TREINO B',type:'FULL BODY',focus:'Condicionamento'},
{name:'TREINO C',type:'FULL BODY',focus:'Força + core'}
]}
];
let activeMonthlyProgram=0;
function monthLabel(p){return `${p.month} ${p.year}`}
function newMonthlyProgram(){
let now=new Date(), months=['JANEIRO','FEVEREIRO','MARÇO','ABRIL','MAIO','JUNHO','JULHO','AGOSTO','SETEMBRO','OUTUBRO','NOVEMBRO','DEZEMBRO'];
monthlyPrograms.unshift({id:Date.now(),month:months[now.getMonth()],year:now.getFullYear(),status:'RASCUNHO',students:[],workouts:[{name:'TREINO A',type:'FULL BODY',focus:''}]});activeMonthlyProgram=0;go('monthlyEditor')
}
function duplicateMonthly(i){let x=JSON.parse(JSON.stringify(monthlyPrograms[i]));x.id=Date.now();x.status='RASCUNHO';monthlyPrograms.unshift(x);activeMonthlyProgram=0;go('monthlyEditor')}
function addMonthlyWorkout(){let p=monthlyPrograms[activeMonthlyProgram];let letter=String.fromCharCode(65+p.workouts.length);p.workouts.push({name:'TREINO '+letter,type:'FULL BODY',focus:''});render()}
function removeMonthlyWorkout(i){monthlyPrograms[activeMonthlyProgram].workouts.splice(i,1);render()}
function toggleMonthlyStudent(i){let a=monthlyPrograms[activeMonthlyProgram].students,p=a.indexOf(i);p>=0?a.splice(p,1):a.push(i);render()}
let activeWorkoutContext={scope:'MONTHLY',programIndex:0,workoutIndex:0};
function ensureWorkoutData(w){
if(!w.blocks) w.blocks=[{name:'BLOCO 1',exercises:[]}];
return w;
}
function editMonthlyWorkout(i){
activeWorkoutContext={scope:'MONTHLY',programIndex:activeMonthlyProgram,workoutIndex:i};
ensureWorkoutData(monthlyPrograms[activeMonthlyProgram].workouts[i]);go('connectedWorkoutEditor')
}
function currentConnectedWorkout(){
if(activeWorkoutContext.scope==='MONTHLY') return ensureWorkoutData(monthlyPrograms[activeWorkoutContext.programIndex].workouts[activeWorkoutContext.workoutIndex]);
if(activeWorkoutContext.scope==='V24') return ensureWorkoutData(v24Program(activeWorkoutContext.studentIndex).workouts[activeWorkoutContext.workoutIndex]);
return null;
}
function addConnectedBlock(){let w=currentConnectedWorkout();w.blocks.push({name:'BLOCO '+(w.blocks.length+1),exercises:[]});render()}
function deleteConnectedBlock(i){let w=currentConnectedWorkout();if(w.blocks.length>1)w.blocks.splice(i,1);render()}
function addDemoExerciseToBlock(b){
let w=currentConnectedWorkout(), pool=(typeof exerciseDB!=='undefined'&&exerciseDB.length)?exerciseDB:[{name:'AGACHAMENTO'},{name:'REMADA NO CABO'},{name:'TERRA KTB'}];
let ex=pool[(w.blocks[b].exercises.length)%pool.length], name=ex.name||ex.exercise||'EXERCÍCIO';
w.blocks[b].exercises.push({name,sets:'3',reps:'10',load:'',rest:'60s',note:''});render()
}
function removeConnectedExercise(b,e){currentConnectedWorkout().blocks[b].exercises.splice(e,1);render()}
function moveConnectedExercise(b,e,d){let a=currentConnectedWorkout().blocks[b].exercises,n=e+d;if(n<0||n>=a.length)return;[a[e],a[n]]=[a[n],a[e]];render()}
function saveConnectedWorkout(){alert(currentConnectedWorkout().name+' salvo com '+currentConnectedWorkout().blocks.length+' bloco(s).');go('monthlyEditor')}
let connectedPickerBlock=0,connectedLibraryQuery='',connectedLibraryFilter='TODOS';
function openConnectedLibrary(b){connectedPickerBlock=b;connectedLibraryQuery='';connectedLibraryFilter='TODOS';go('connectedLibrary')}
function exText(x){return String(x.name||x.exercise||x.nome||'EXERCÍCIO')}
function exMeta(x){return [x.cat||x.category||x.padrao||'',x.level||x.nivel||'',x.base||'',x.equipment||x.equipamento||''].filter(Boolean).join(' • ')}
function connectedFilteredExercises(){
let q=connectedLibraryQuery.toUpperCase(),f=connectedLibraryFilter;
return exerciseDB.filter(x=>{
let all=(exText(x)+' '+exMeta(x)).toUpperCase();
return (!q||all.includes(q))&&(f==='TODOS'||all.includes(f));
}).slice(0,120)
}
function chooseConnectedExercise(i){
let list=connectedFilteredExercises(),x=list[i]; if(!x)return;
currentConnectedWorkout().blocks[connectedPickerBlock].exercises.push({name:exText(x),meta:exMeta(x),sets:'3',reps:'10',load:'',rest:'60s',note:''});
go('connectedWorkoutEditor')
}
let studentDemoIndex=0,studentActiveProgram=null,studentActiveWorkout=0;
let studentMonthlyLogs={};
function publishedProgramForStudent(si){
return monthlyPrograms.find((p)=>p.status==='PUBLICADO' && (p.students.includes(si)|| (p.students.length===0 && students[si]?.service==='TREINO')));
}
function openStudentMonthly(si=0){studentDemoIndex=si;studentActiveProgram=publishedProgramForStudent(si);go('studentMonthly')}
function monthlyLogKey(pi,wi){return (studentActiveProgram?.id||'x')+'_'+studentDemoIndex+'_'+wi}
function getMonthlyLog(wi){let k=monthlyLogKey(0,wi);if(!studentMonthlyLogs[k])studentMonthlyLogs[k]={done:{},load:{},reps:{},rpe:'',pain:'Não',painArea:'',note:'',finished:false};return studentMonthlyLogs[k]}
function workoutExerciseCount(w){return (w.blocks||[]).reduce((n,b)=>n+(b.exercises||[]).length,0)}
function workoutDoneCount(w,wi){let l=getMonthlyLog(wi);return Object.values(l.done).filter(Boolean).length}
function monthlyProgress(w,wi){let n=workoutExerciseCount(w);return n?Math.round(workoutDoneCount(w,wi)/n*100):0}
function openStudentMonthlyWorkout(i){studentActiveWorkout=i;go('studentMonthlyWorkout')}
function finishMonthlyWorkout(){let l=getMonthlyLog(studentActiveWorkout);l.finished=true;go('studentMonthlyFeedback')}
function saveMonthlyFeedback(){let l=getMonthlyLog(studentActiveWorkout),w=studentActiveProgram.workouts[studentActiveWorkout];workoutHistory.unshift({date:new Date().toLocaleDateString('pt-BR'),name:w.name,type:w.type,rpe:Number(l.rpe||5),pain:l.pain,painArea:l.painArea,done:100,note:l.note,loads:Object.values(l.load).filter(Boolean).join(' • ')});go('studentMonthly')}
// ===== V24: PERSONALIZADO + PERFORMANCE COMPLETOS =====
let v24IndividualPrograms={};
let v24Exec={student:0,workout:0};
let v24Logs={};
function v24Program(si){
if(!v24IndividualPrograms[si]) v24IndividualPrograms[si]={workouts:[],phase:'',competitionDate:'',sportNotes:''};
return v24IndividualPrograms[si];
}
function v24NewWorkout(si){
let p=v24Program(si), letter=String.fromCharCode(65+p.workouts.length);
p.workouts.push({name:'TREINO '+letter,type:'FULL BODY',focus:'',blocks:[{name:'BLOCO 1',exercises:[]}],published:false});
activeWorkoutContext={scope:'V24',studentIndex:si,workoutIndex:p.workouts.length-1};go('connectedWorkoutEditor')
}
function v24EditWorkout(si,wi){activeWorkoutContext={scope:'V24',studentIndex:si,workoutIndex:wi};go('connectedWorkoutEditor')}
function v24Publish(si,wi){v24Program(si).workouts[wi].published=true;render()}
function v24LogKey(si,wi){return 'v24_'+si+'_'+wi}
function v24Log(si,wi){let k=v24LogKey(si,wi);if(!v24Logs[k])v24Logs[k]={done:{},load:{},reps:{},rpe:'',pain:'Não',painArea:'',note:'',finished:false};return v24Logs[k]}
function v24OpenStudent(si){studentDemoIndex=si;go('v24StudentProgram')}
function v24OpenExec(si,wi){v24Exec={student:si,workout:wi};go('v24StudentExec')}
function v24Finish(){go('v24StudentFeedback')}
function v24SaveFeedback(){
let si=v24Exec.student,wi=v24Exec.workout,l=v24Log(si,wi),w=v24Program(si).workouts[wi];l.finished=true;
workoutHistory.unshift({date:new Date().toLocaleDateString('pt-BR'),name:w.name,type:w.type,rpe:Number(l.rpe||5),pain:l.pain,painArea:l.painArea,done:100,note:l.note,loads:Object.values(l.load).filter(Boolean).join(' • ')});
go('v24StudentProgram')
}
// ===== V25: VÍDEOS NA BIBLIOTECA DE EXERCÍCIOS =====
let exerciseVideos={};
let v25ExerciseIndex=0,v25ReturnPage='library';
function v25VideoData(i){if(!exerciseVideos[i])exerciseVideos[i]={url:'',technical:'',attention:''};return exerciseVideos[i]}
function v25OpenVideoAdmin(i,back='library'){v25ExerciseIndex=i;v25ReturnPage=back;go('v25VideoAdmin')}
function v25OpenVideoStudentByName(name,back){
let i=exerciseDB.findIndex(x=>(x.name||'').toUpperCase()===String(name||'').toUpperCase());
if(i<0){alert('Este exercício ainda não possui vídeo cadastrado.');return}
v25ExerciseIndex=i;v25ReturnPage=back||page;go('v25VideoStudent')
}
function v25YoutubeEmbed(url){
let m=String(url||'').match(/(?:youtu\.be\/|youtube\.com\/(?:watch\?v=|shorts\/|embed\/))([^?&/]+)/i);
return m?'https://www.youtube.com/embed/'+m[1]:'';
}
function v25SaveVideo(){
let d=v25VideoData(v25ExerciseIndex);
let u=document.getElementById('v25url'); if(u)d.url=u.value.trim();
let t=document.getElementById('v25tech'); if(t)d.technical=t.value.trim();
let a=document.getElementById('v25att'); if(a)d.attention=a.value.trim();
alert('Vídeo e orientações salvos para este exercício.');go(v25ReturnPage)
}
function v25VideoButton(name,back){
let i=exerciseDB.findIndex(x=>(x.name||'').toUpperCase()===String(name||'').toUpperCase());
if(i<0)return '';
let d=v25VideoData(i);
return `${d.url?` VÍDEO`:` SEM VÍDEO`}`;
}
// ===== V26: PERSISTÊNCIA LOCAL DO PROTÓTIPO =====
const V26_STORAGE_KEY='renilce_dias_app_v26';
let v26SaveTimer=null;
function v26Snapshot(){
return {
version:26,savedAt:new Date().toISOString(),
students:typeof students!=='undefined'?students:[],
monthlyPrograms:typeof monthlyPrograms!=='undefined'?monthlyPrograms:[],
studentWarmups:typeof studentWarmups!=='undefined'?studentWarmups:{},
workoutHistory:typeof workoutHistory!=='undefined'?workoutHistory:[],
exerciseVideos:typeof exerciseVideos!=='undefined'?exerciseVideos:{},
v24IndividualPrograms:typeof v24IndividualPrograms!=='undefined'?v24IndividualPrograms:{},
v24Logs:typeof v24Logs!=='undefined'?v24Logs:{},
studentMonthlyLogs:typeof studentMonthlyLogs!=='undefined'?studentMonthlyLogs:{},
studentIndividualWorkouts:typeof studentIndividualWorkouts!=='undefined'?studentIndividualWorkouts:{},
v27Session:typeof v27Session!=='undefined'?v27Session:{}
};
}
function v26Save(silent=true){
try{
localStorage.setItem(V26_STORAGE_KEY,JSON.stringify(v26Snapshot()));
let b=document.getElementById('persistBadge');if(b){b.textContent='✓ DADOS SALVOS';b.classList.add('ok')}
if(!silent)alert('Dados salvos neste dispositivo.');
}catch(e){if(!silent)alert('Não foi possível salvar neste navegador.')}
}
function v26Restore(){
try{
let raw=localStorage.getItem(V26_STORAGE_KEY);if(!raw)return false;
let d=JSON.parse(raw);
if(d.students)students.splice(0,students.length,...d.students);
if(d.monthlyPrograms)monthlyPrograms.splice(0,monthlyPrograms.length,...d.monthlyPrograms);
if(d.studentWarmups)studentWarmups=d.studentWarmups;
if(d.workoutHistory)workoutHistory.splice(0,workoutHistory.length,...d.workoutHistory);
if(d.exerciseVideos)exerciseVideos=d.exerciseVideos;
if(d.v24IndividualPrograms)v24IndividualPrograms=d.v24IndividualPrograms;
if(d.v24Logs)v24Logs=d.v24Logs;
if(d.studentMonthlyLogs)studentMonthlyLogs=d.studentMonthlyLogs;
if(d.studentIndividualWorkouts)studentIndividualWorkouts=d.studentIndividualWorkouts;
if(d.v27Session)v27Session=d.v27Session;
return true;
}catch(e){return false}
}
function v26AutoSave(){
clearTimeout(v26SaveTimer);
v26SaveTimer=setTimeout(()=>v26Save(true),250);
}
function v26Export(){
let blob=new Blob([JSON.stringify(v26Snapshot(),null,2)],{type:'application/json'});
let a=document.createElement('a');a.href=URL.createObjectURL(blob);a.download='Renilce_Dias_Backup_'+new Date().toISOString().slice(0,10)+'.json';a.click();setTimeout(()=>URL.revokeObjectURL(a.href),500);
}
function v26Import(input){
let f=input.files&&input.files[0];if(!f)return;
let r=new FileReader();r.onload=()=>{try{localStorage.setItem(V26_STORAGE_KEY,r.result);v26Restore();alert('Backup restaurado com sucesso.');render()}catch(e){alert('Arquivo de backup inválido.')}};r.readAsText(f)
}
function v26Clear(){
if(confirm('Apagar os dados salvos neste dispositivo e voltar aos dados do protótipo?')){localStorage.removeItem(V26_STORAGE_KEY);location.reload()}
}
// ===== V27: CONTAS + ARQUITETURA DE BACKEND =====
let v27Session={role:'PROFESSIONAL',studentIndex:0,email:'renilce@demo.app'};
function v27LoginProfessional(){v27Session={role:'PROFESSIONAL',studentIndex:0,email:'renilce@demo.app'};v26AutoSave();go('admin')}
function v27LoginStudent(si){v27Session={role:'STUDENT',studentIndex:Number(si)||0,email:'aluno@demo.app'};studentDemoIndex=Number(si)||0;v26AutoSave();let st=students[studentDemoIndex]||students[0];go(st.service==='TREINO'?'studentMonthly':'v24StudentProgram')}
function v27Logout(){v27Session={role:'',studentIndex:0,email:''};go('v27Login')}
function v27OpenMyArea(){if(v27Session.role==='PROFESSIONAL')go('admin');else v27LoginStudent(v27Session.studentIndex)}
function render(){
if(page==='login') A.innerHTML=`
PONTOS PARA REVISÃO${alerts.length?alerts.map(x=>`
⚠️ ${x}
`).join(''):`
Nenhum alerta identificado pelas respostas preenchidas. A prescrição permanece sujeita à revisão profissional.
`}
DECISÃO DA RENILCE${['Liberar para treinamento','Liberar com adaptações','Solicitar mais informações','Orientar avaliação profissional quando indicado'].map(d=>``).join('')}
Frequência, conclusão dos treinos, esforço percebido, cargas registradas e relatos de dor/desconforto.
`}
else if(page==='profile') A.innerHTML=`
Renilce Dias
TREINAMENTO FÍSICO & PERFORMANCE
Fundadora do DUO Centro de Treinamento Integrado
SOBRE MIM
Profissional de Educação Física, fundadora do DUO Centro de Treinamento Integrado, com atuação voltada ao treinamento físico, qualidade do movimento, força, condicionamento e performance.
FORMAÇÃO
Graduação em Educação Física.
Pós-graduação em Exercício Físico para Grupos Especiais.
Pós-graduação em Lesões Musculoesqueléticas e Traumáticas — Prevenção e Reabilitação.
Cursos de Treinamento Físico Funcional, do básico ao avançado, e Preparação Física.
${nav('profile')}`;
else A.innerHTML=`
RENILCE DIAS
${page==='evo'?'Minha evolução':'Avaliação'}
Módulo preparado para a próxima etapa da construção.