🧬 Seu Plano Científico Personalizado
Baseado em seu perfil e objetivo:${this.getGoalName(userProfile.goal)}
💓
FCmax
${scientificParams.fcMax}bpm
🎯
Zona Alvo
${scientificParams.zones.cardio.min}-${scientificParams.zones.cardio.max}bpm
📈
Volume/Semana
${scientificParams.weeklyVolumeMinutes}min
${scientificParams.dailyDeficit > 0 ? `
🔥
Déficit Diário
${scientificParams.dailyDeficit}kcal
`:''}
`;const existingHeaders=calendarContainer.parentElement.querySelectorAll('.scientific-plan-header');existingHeaders.forEach(header=> header.remove());calendarContainer.insertAdjacentHTML('beforebegin',planHeaderHTML);const fragment=document.createDocumentFragment();const completedDays=Object.keys(calendar30Day).length;for(let i=0;i < workoutPlan.length;i++){const dayPlan=workoutPlan[i];const dayCard=document.createElement('div');dayCard.className='day-card';dayCard.classList.add(`intensity-${dayPlan.intensity}`);if(calendar30Day[dayPlan.day]){dayCard.classList.add('completed');}if(completedDays===0 && dayPlan.day===1){dayCard.classList.add('today');}else if(completedDays > 0 && !calendar30Day[dayPlan.day]&& dayPlan.day===completedDays+1){dayCard.classList.add('today');}const intensityBadge=dayPlan.intensityPercent ? `
${dayPlan.intensityPercent}%
`:'';dayCard.innerHTML=`
${dayPlan.icon}
Dia ${dayPlan.day}
${dayPlan.focus}
${intensityBadge}
Semana ${dayPlan.weekNumber}
`;dayCard.dataset.dayIndex=i;dayCard.addEventListener('click',()=>{this.showScientificDayDetail(dayPlan,scientificParams);},{passive:true});fragment.appendChild(dayCard);}calendarContainer.appendChild(fragment);}getGoalName(goal){const names={'lose-weight':'Perder Peso','lose-weight-fast':'Perder Peso Rápido','maintain':'Manter Peso','gain-muscle':'Ganhar Massa Muscular','tone':'Tonificar','health':'Saúde Geral'};return names[goal]|| goal;}showScientificDayDetail(dayPlan,scientificParams){const modal=document.createElement('div');modal.className='day-detail-modal scientific-modal';const selectedExercises=this.selectIntelligentExercises(dayPlan);const scientificExplanation=`
${dayPlan.scientificReason}
Zona Alvo: ${scientificParams.zones[dayPlan.targetZone].name}(${scientificParams.zones[dayPlan.targetZone].min}-${scientificParams.zones[dayPlan.targetZone].max}bpm)
`;const progressionInfo=`
📈 Periodização
Semana: ${dayPlan.weekNumber}-${dayPlan.intensity}
Carga: ${dayPlan.intensityPercent}% da máxima
Volume: ${dayPlan.sets}séries × ${dayPlan.reps}
`;let exercisesHTML='';if(dayPlan.doubleWorkout && dayPlan.secondCategory){exercisesHTML='
⚡ TREINO DUPLO-Máxima Eficiência
';exercisesHTML+='
🔥 Treino 1-'+this.getCategoryName(dayPlan.category)+'
';}selectedExercises.slice(0,5).forEach(ex=>{exercisesHTML+=`
${ex.emoji}
${ex.name}
${dayPlan.sets}× ${dayPlan.reps}| ~${Math.round(ex.calories*dayPlan.sets)}kcal
`;});if(dayPlan.doubleWorkout && dayPlan.secondCategory){exercisesHTML+='
💪 Treino 2-'+this.getCategoryName(dayPlan.secondCategory)+'
';selectedExercises.slice(5,10).forEach(ex=>{exercisesHTML+=`
${ex.emoji}
${ex.name}
${dayPlan.sets}× ${dayPlan.reps}| ~${Math.round(ex.calories*dayPlan.sets)}kcal
`;});}modal.innerHTML=`
${scientificExplanation}${progressionInfo}
💪 Exercícios do Dia
${exercisesHTML}
`;document.body.appendChild(modal);modal.querySelector('#closeScientificModal').addEventListener('click',()=>{modal.remove();this.playCuteSound('tap');});modal.querySelector('#closeDayDetailBtn').addEventListener('click',()=>{modal.remove();this.playCuteSound('tap');});modal.querySelector('#startDayWorkoutBtn').addEventListener('click',()=>{modal.remove();this.startWorkout(selectedExercises);this.currentDayPlan=dayPlan;this.playCuteSound('success');});modal.addEventListener('click',(e)=>{if(e.target===modal){modal.remove();this.playCuteSound('tap');}});this.playCuteSound('tap');}selectIntelligentExercises(dayPlan){const useFullDatabase=typeof EXERCISES_DATABASE !=='undefined' && EXERCISES_DATABASE;if(useFullDatabase){return this.selectFromCompleteDatabase(dayPlan);}const exercises1=this.getExercisesByCategory(dayPlan.category);let selected=exercises1.slice(0,5);if(dayPlan.doubleWorkout && dayPlan.secondCategory){const exercises2=this.getExercisesByCategory(dayPlan.secondCategory);selected=[...selected,...exercises2.slice(0,5)];}return selected;}selectFromCompleteDatabase(dayPlan){const profile=this.userProfile ||{};const day=dayPlan.day;const selectionParams=this.calculateSelectionParameters(profile,dayPlan);const category1Exercises=EXERCISES_DATABASE[dayPlan.category]||[];const scored1=this.scoreExercises(category1Exercises,selectionParams,day);let selectedExercises=this.selectVariedExercises(scored1,5,day);if(dayPlan.doubleWorkout && dayPlan.secondCategory){const category2Exercises=EXERCISES_DATABASE[dayPlan.secondCategory]||[];const scored2=this.scoreExercises(category2Exercises,selectionParams,day+1000);const selected2=this.selectVariedExercises(scored2,5,day+1000);selectedExercises=[...selectedExercises,...selected2];}return selectedExercises;}calculateSelectionParameters(profile,dayPlan){const age=profile.age || 30;const weight=profile.weight || 70;const goal=profile.goal || 'lose-weight';const fitness=profile.fitness || 'intermediate';const goalPreferences={'lose-weight':{preferHighCalories:true,preferCardio:true,intensityMultiplier:1.2,minCalories:8,maxDuration:90},'lose-weight-fast':{preferHighCalories:true,preferCardio:true,intensityMultiplier:1.4,minCalories:10,maxDuration:80},'gain-muscle':{preferHighCalories:false,preferCardio:false,intensityMultiplier:0.9,minCalories:5,maxDuration:100,preferSets:true},'tone':{preferHighCalories:false,preferCardio:false,intensityMultiplier:1.0,minCalories:6,maxDuration:90},'health':{preferHighCalories:false,preferCardio:true,intensityMultiplier:0.8,minCalories:4,maxDuration:100}};const prefs=goalPreferences[goal]|| goalPreferences['lose-weight'];const fitnessAdjustments={'beginner':{intensityMultiplier:0.7,maxDuration:70},'intermediate':{intensityMultiplier:1.0,maxDuration:90},'advanced':{intensityMultiplier:1.3,maxDuration:120}};const fitnessAdj=fitnessAdjustments[fitness]|| fitnessAdjustments['intermediate'];const ageMultiplier=age < 25 ? 1.1:age < 40 ? 1.0:age < 55 ? 0.9:0.8;return{...prefs,intensityMultiplier:prefs.intensityMultiplier*fitnessAdj.intensityMultiplier*ageMultiplier,maxDuration:Math.min(prefs.maxDuration,fitnessAdj.maxDuration),age,weight,goal,fitness,dayIntensity:dayPlan.intensityPercent || 70};}scoreExercises(exercises,params,seed){return exercises.map((exercise,index)=>{let score=100;if(params.preferHighCalories){score+=(exercise.calories || 5)*2;}const duration=exercise.durationInSeconds || 40;if(duration >=30 && duration <=params.maxDuration){score+=20;}if((exercise.calories || 5)>=params.minCalories){score+=15*params.intensityMultiplier;}if(params.preferSets &&(exercise.sets || 3)>=3){score+=10;}const pseudoRandom=((seed+index)*9301+49297)% 233280/233280;score+=pseudoRandom*30;return{...exercise,score};}).sort((a,b)=> b.score-a.score);}selectVariedExercises(scoredExercises,count,seed){const selected=[];const usedNames=new Set();const topCandidates=scoredExercises.slice(0,Math.ceil(scoredExercises.length*0.3));const shuffled=topCandidates.sort((a,b)=>{const randomA=((seed+a.score)*9301)% 233280/233280;const randomB=((seed+b.score)*9301)% 233280/233280;return(b.score+randomA*10)-(a.score+randomB*10);});for(const exercise of shuffled){if(selected.length >=count)break;const simpleName=exercise.name.toLowerCase().substring(0,20);if(!usedNames.has(simpleName)){selected.push(exercise);usedNames.add(simpleName);}}if(selected.length < count){for(const exercise of scoredExercises){if(selected.length >=count)break;if(!selected.includes(exercise)){selected.push(exercise);}}}return selected;}getCategoryName(category){const names={'abs':'Abdômen','legs':'Pernas','glutes':'Glúteos','arms':'Braços','back':'Costas','cardio':'Cardio','fullbody':'Corpo Todo','yoga':'Yoga','waist':'Cintura','face':'Face','massage':'Massagem'};return names[category]|| category;}showProfilePrompt(){alert('Por favor,complete seu perfil primeiro para gerar um plano personalizado!');this.navigateTo('progress');}showDayDetail(dayPlan){const modal=document.createElement('div');modal.className='day-detail-modal';const exercises1=this.getExercisesByCategory(dayPlan.category);let selectedExercises=exercises1.slice(0,5);let exercisesHTML='';let doubleWorkoutInfo='';if(dayPlan.doubleWorkout && dayPlan.secondCategory){doubleWorkoutInfo='
⚡ DIA INTENSO:2 TREINOS PARA ACELERAR RESULTADOS!
';exercisesHTML+='
🔥 Treino 1
';selectedExercises.forEach(ex=>{exercisesHTML+=`
${ex.emoji}
${ex.name}
${ex.sets}séries × ${ex.reps}
`;});exercisesHTML+='
';const exercises2=this.getExercisesByCategory(dayPlan.secondCategory);const selectedExercises2=exercises2.slice(0,5);exercisesHTML+='
💪 Treino 2
';selectedExercises2.forEach(ex=>{exercisesHTML+=`
${ex.emoji}
${ex.name}
${ex.sets}séries × ${ex.reps}
`;});exercisesHTML+='
';selectedExercises=[...selectedExercises,...selectedExercises2];}else{selectedExercises.forEach(ex=>{exercisesHTML+=`
${ex.emoji}
${ex.name}
${ex.sets}séries × ${ex.reps}
`;});}const totalCalories=selectedExercises.reduce((sum,ex)=> sum+(ex.calories*ex.sets),0);const estimatedTime=selectedExercises.length*2;modal.innerHTML=`
${doubleWorkoutInfo}
${exercisesHTML}
`;document.body.appendChild(modal);modal.querySelector('#closeDayDetail').addEventListener('click',()=>{modal.remove();this.playCuteSound('tap');});modal.querySelector('#startDayWorkout').addEventListener('click',()=>{modal.remove();this.startWorkout(selectedExercises);this.playCuteSound('success');this.currentDayPlan=dayPlan;});modal.addEventListener('click',(e)=>{if(e.target===modal){modal.remove();this.playCuteSound('tap');}});this.playCuteSound('tap');}markDayComplete(dayNumber){const calendar30Day=this.loadCalendar30Day();calendar30Day[dayNumber]=new Date().toISOString();this.saveCalendar30Day(calendar30Day);if(this.currentView==='calendar'){this.generate30DayCalendar();}const daysCompleted=Object.keys(calendar30Day).length;if(daysCompleted===30){this.showToast('🎉 Parabéns! Você completou os 30 dias! 🎊','success',5000);this.sendNotification('🎉 30 Dias Completos!','Você é incrível! Completou todo o desafio!');}else{this.showToast(`✨ Dia ${dayNumber}concluído! ${30-daysCompleted}dias restantes!`,'success');}}goBack(){if(this.navigationHistory.length > 0){const previousView=this.navigationHistory.pop();this.navigateTo(previousView,false);}else{this.navigateTo('home',false);}}showCategoryExercises(category){this.currentCategory=category;const exercises=this.getExercisesByCategory(category);const categoryNames={personalized:'Treino Personalizado',abs:'Abdômen',face:'Massagem Facial',waist:'Cintura',legs:'Pernas',glutes:'Glúteos',back:'Postura e Mobilidade',arms:'Braços',cardio:'Cardio',fullbody:'Corpo Todo',yoga:'Yoga',massage:'Massagem Corporal'};document.getElementById('categoryTitle').textContent=categoryNames[category];const container=document.getElementById('exercisesList');container.innerHTML='';if(category==='personalized'){const sections={'🔥 Abdômen e Core':exercises.filter(ex=>['Prancha com Elevação de Perna','Prancha com Balanço Lateral','Prancha Lateral com Rotação','Elevações Alternadas de Perna','Tesoura(Scissor Kicks)'].includes(ex.name)),'🦵 Pernas e Glúteos':exercises.filter(ex=>['Agachamento com Rotação'].includes(ex.name)),'💪 Costas e Mobilidade':exercises.filter(ex=>['Flexão e Extensão do Tronco','Exercício de Escápula','Alongamento Dinâmico Lateral','Alongamento de Lado(Sentado)','Torção de Torso(Sentado)'].includes(ex.name)),'🏋️ Ombros e Mobilidade':exercises.filter(ex=>['Alongamento de Ombro','Circundução com Garrafa','Alcance Cruzado nas Costas','Alongamento de Peitoral','Alongamento de Tríceps'].includes(ex.name)),'😊 Facial':exercises.filter(ex=>['Exercício para Queixo Duplo','Rosto Esculpido','Rosto Afinado','Linhas de Sorriso'].includes(ex.name))};const fragment=document.createDocumentFragment();Object.entries(sections).forEach(([sectionName,sectionExercises])=>{if(sectionExercises.length > 0){const sectionHeader=document.createElement('div');sectionHeader.className='section-header';sectionHeader.innerHTML=`
${sectionName}
`;fragment.appendChild(sectionHeader);sectionExercises.forEach((exercise)=>{const card=document.createElement('div');card.className='exercise-card';if(this.wasCompletedIn24h(exercise.name)){card.classList.add('completed-24h');}card.innerHTML=`
${exercise.emoji}
${exercise.name}
${exercise.sets}× ${exercise.reps}
→
`;card.addEventListener('click',()=>{this.startWorkout(sectionExercises,sectionExercises.indexOf(exercise));});fragment.appendChild(card);});}});container.appendChild(fragment);this.navigateTo('exercisesList');return;}const fragment=document.createDocumentFragment();exercises.forEach((exercise,index)=>{const card=document.createElement('div');card.className='exercise-card';if(this.wasCompletedIn24h(exercise.name)){card.classList.add('completed-24h');}card.innerHTML=`
${exercise.emoji}
${exercise.name}
${exercise.sets}× ${exercise.reps}
→
`;card.addEventListener('click',()=>{const exerciseIndex=exercises.indexOf(exercise);this.startWorkout(exercises,exerciseIndex);});fragment.appendChild(card);});container.appendChild(fragment);this.navigateTo('exercisesList');}startWorkout(exercises,startIndex=0){this.currentWorkout=exercises.map(ex=>{if(ex.videoFile){return{...ex,video:this.VIDEO_BASE_URL+ex.videoFile,isLocalVideo:true};}else if(ex.youtubeId){return{...ex,youtubeId:ex.youtubeId};}return ex;});this.currentExerciseIndex=startIndex;this.currentSeries=0;this.workoutStartTime=Date.now();this.playSound('startYoga');setTimeout(()=>{this.playSound('backgroundYoga');},2000);this.navigateTo('workoutSession');this.displayCurrentExercise();this.startWorkoutTimer();}displayCurrentExercise(){const exercise=this.currentWorkout[this.currentExerciseIndex];document.getElementById('currentExerciseName').textContent=exercise.name;document.getElementById('exerciseCount').textContent=`Exercício ${this.currentExerciseIndex+1}de ${this.currentWorkout.length}`;const demoVideo=document.getElementById('demoVideo');const demoIcon=document.getElementById('demoIcon');const exerciseDemo=document.getElementById('exerciseDemo');if(demoVideo){demoVideo.onended=null;demoVideo.ontimeupdate=null;}if(exercise.youtubeId){const youtubeContainer=exerciseDemo.querySelector('.demo-placeholder');youtubeContainer.innerHTML='';const iframe=document.createElement('iframe');iframe.id='youtube-player';iframe.width='100%';iframe.height='100%';iframe.style.borderRadius='var(--radius-lg)';iframe.style.maxHeight='60vh';iframe.src=`https:iframe.allow='accelerometer;autoplay;clipboard-write;encrypted-media;gyroscope;picture-in-picture';iframe.allowFullscreen=true;youtubeContainer.appendChild(iframe);this.playCuteSound('tap');}else if(exercise.video){const skip4SecondsExercises=['Prancha com Balanço Lateral','Prancha com Elevação de Perna','Tesoura(Scissor Kicks)','Elevação Alternada de Pernas'];const startTime=skip4SecondsExercises.includes(exercise.name)? 4:3;demoVideo.setAttribute('playsinline','');demoVideo.setAttribute('muted','');demoVideo.muted=true;const videoSource=demoVideo.querySelector('source');let videoUrl=exercise.video;videoSource.src=videoUrl;videoSource.type='video/mp4';demoVideo.load();const handleVideoError=()=>{if(exercise.video.startsWith('videos/')){const videoFileName=exercise.video.replace('videos/','');const cdnUrl=this.VIDEO_BASE_URL_FALLBACK+videoFileName;videoSource.src=cdnUrl;demoVideo.load();const cdnLoadHandler=()=>{demoVideo.currentTime=startTime;demoVideo.play().catch(()=>{demoVideo.style.display='none';demoIcon.style.display='block';});};demoVideo.addEventListener('canplaythrough',cdnLoadHandler,{once:true});}else{demoVideo.style.display='none';demoIcon.style.display='block';}};demoVideo.onerror=handleVideoError;videoSource.onerror=handleVideoError;const loadedDataHandler=()=>{demoVideo.currentTime=startTime;demoVideo.style.display='block';demoIcon.style.display='none';const playPromise=demoVideo.play();if(playPromise !==undefined){playPromise.catch(()=>{const playButton=document.getElementById('videoPlayButton');if(playButton){playButton.style.display='block';const playHandler=()=>{demoVideo.currentTime=startTime;demoVideo.play().then(()=>{playButton.style.display='none';this.playCuteSound('tap');}).catch(()=>{});};playButton.addEventListener('click',playHandler,{once:true});demoVideo.addEventListener('click',playHandler,{once:true});}});}};if(this.activeVideoHandlers && this.activeVideoHandlers.loadHandler){demoVideo.removeEventListener('loadeddata',this.activeVideoHandlers.loadHandler);}demoVideo.addEventListener('loadeddata',loadedDataHandler,{once:true});this.activeVideoHandlers={video:demoVideo,loadHandler:loadedDataHandler,errorHandler:handleVideoError};demoVideo.dataset.startTime=startTime;demoVideo.onended=()=>{const skipTime=parseInt(demoVideo.dataset.startTime)|| 3;demoVideo.currentTime=skipTime;demoVideo.play().catch(()=>{});};let lastLoopCheck=0;demoVideo.ontimeupdate=()=>{const now=Date.now();if(now-lastLoopCheck < 100)return;lastLoopCheck=now;const skipTime=parseInt(demoVideo.dataset.startTime)|| 3;if(demoVideo.currentTime >=demoVideo.duration-0.5){demoVideo.currentTime=skipTime;}};}else{demoVideo.style.display='none';demoIcon.style.display='block';demoIcon.textContent=exercise.emoji || '💪';}document.getElementById('repsInfo').textContent=`${exercise.sets}séries × ${exercise.reps}`;document.getElementById('restInfo').textContent=`Descanso:${exercise.rest || 30}s entre séries`;this.updateSeriesTracker(exercise.sets);const progress=((this.currentExerciseIndex+(this.currentSeries/exercise.sets))/this.currentWorkout.length)*100;document.getElementById('workoutProgressBar').style.width=`${progress}%`;this.preloadNextVideo();}preloadNextVideo(){const nextIndex=this.currentExerciseIndex+1;if(nextIndex < this.currentWorkout.length){const nextExercise=this.currentWorkout[nextIndex];if(nextExercise.video){const link=document.createElement('link');link.rel='preload';link.as='video';link.href=nextExercise.video;document.head.appendChild(link);}}}updateSeriesTracker(totalSeries){const tracker=document.getElementById('seriesTracker');const fragment=document.createDocumentFragment();for(let i=0;i < totalSeries;i++){const dot=document.createElement('div');dot.className='series-dot';if(i < this.currentSeries){dot.classList.add('completed');}fragment.appendChild(dot);}tracker.innerHTML='';tracker.appendChild(fragment);}startWorkoutTimer(){if(this.workoutTimer){clearInterval(this.workoutTimer);this.workoutTimer=null;}this.workoutSeconds=0;this.workoutTimer=setInterval(()=>{this.workoutSeconds++;const mins=Math.floor(this.workoutSeconds/60);const secs=this.workoutSeconds % 60;const timerEl=document.getElementById('workoutTimer');if(timerEl){timerEl.textContent=`${String(mins).padStart(2,'0')}:${String(secs).padStart(2,'0')}`;}},1000);}completeCurrentExercise(){const exercise=this.currentWorkout[this.currentExerciseIndex];this.currentSeries++;this.playCuteSound('success');if(this.currentSeries >=exercise.sets){this.currentExerciseIndex++;this.currentSeries=0;if(this.currentExerciseIndex >=this.currentWorkout.length){this.completeWorkout();}else{this.displayCurrentExercise();this.playCuteSound('tap');}}else{this.updateSeriesTracker(exercise.sets);this.showRestPeriod(exercise.rest || 30);}}showRestPeriod(seconds){const btn=document.getElementById('completeExercise');const skipBtn=document.getElementById('skipExercise');const originalText=btn.textContent;const originalSkipText=skipBtn.textContent;let remaining=seconds;btn.textContent=`Descansando... ${remaining}s`;btn.disabled=true;skipBtn.textContent='Pular Descanso ⏭️';skipBtn.style.display='block';if(remaining > 5){this.playCuteSound('tap');}if(this.restInterval){clearInterval(this.restInterval);this.restInterval=null;}this.restInterval=setInterval(()=>{remaining--;btn.textContent=`Descansando... ${remaining}s`;if(remaining===10){this.playCuteSound('tap');}else if(remaining===5){this.playCuteSound('tap');}else if(remaining <=3 && remaining > 0){this.playSound('countdown');}else if(remaining===0){this.playCuteSound('success');}if(remaining <=0){clearInterval(this.restInterval);btn.textContent=originalText;btn.disabled=false;skipBtn.textContent=originalSkipText;this.restInterval=null;}},1000);this.currentRestInterval=this.restInterval;this.isResting=true;const skipRestHandler=()=>{if(this.isResting){clearInterval(this.currentRestInterval);btn.textContent=originalText;btn.disabled=false;skipBtn.textContent=originalSkipText;this.isResting=false;this.playCuteSound('tap');}};if(this.skipRestHandler){skipBtn.removeEventListener('click',this.skipRestHandler);}this.skipRestHandler=skipRestHandler;skipBtn.addEventListener('click',skipRestHandler);}skipExercise(){if(this.isResting){return;}this.currentExerciseIndex++;this.currentSeries=0;if(this.skipRestHandler){const skipBtn=document.getElementById('skipExercise');if(skipBtn){skipBtn.removeEventListener('click',this.skipRestHandler);}this.skipRestHandler=null;}if(this.currentExerciseIndex >=this.currentWorkout.length){this.completeWorkout();}else{this.displayCurrentExercise();this.playCuteSound('tap');}}completeWorkout(){if(this.isCompletingWorkout){return;}this.isCompletingWorkout=true;clearInterval(this.workoutTimer);this.workoutTimer=null;const durationInSeconds=this.workoutSeconds || Math.floor((Date.now()-this.workoutStartTime)/1000);const duration=Math.max(1,Math.floor(durationInSeconds/60));const calories=this.calculateCalories(duration,this.currentWorkout);if(this.currentDayPlan){this.markDayComplete(this.currentDayPlan.day);this.currentDayPlan=null;}this.progress.workoutsCompleted=(this.progress.workoutsCompleted || 0)+1;this.progress.totalMinutes=(this.progress.totalMinutes || 0)+duration;this.progress.totalCalories=(this.progress.totalCalories || 0)+calories;this.progress.lastWorkout=new Date().toISOString();if(!this.progress.longestWorkout || duration > this.progress.longestWorkout){this.progress.longestWorkout=duration;}if(!this.progress.workoutHistory){this.progress.workoutHistory=[];}this.progress.workoutHistory.push({date:new Date().toISOString(),duration:duration,calories:calories,category:this.currentCategory});if(!this.progress.completedExercises){this.progress.completedExercises=[];}this.currentWorkout.forEach(exercise=>{this.progress.completedExercises.push({name:exercise.name,completedAt:new Date().toISOString(),category:this.currentCategory});});if(this.progress.completedExercises.length > 50){this.progress.completedExercises=this.progress.completedExercises.slice(-50);}this.updateStreak();this.saveProgress();this.updateAllStats();this.stopSound('backgroundYoga');this.playCuteSound('complete');this.playSound('motivational');this.sendNotification('🎉 Treino Concluído!',`Você queimou ${calories}kcal em ${duration}minutos! Continue assim! 💪`);document.getElementById('summaryTime').textContent=`${duration}min`;document.getElementById('summaryCalories').textContent=`${calories}kcal`;document.getElementById('summaryExercises').textContent=`${this.currentWorkout.length}exercícios`;let detailsHTML='
📊 Detalhes do Treino:';this.currentWorkout.forEach((exercise,index)=>{const exerciseCalories=Math.round(this.getExerciseCaloriesPerMinute(exercise.name)*(duration/this.currentWorkout.length)*(exercise.sets/3));detailsHTML+=`
${index+1}. ${exercise.name}
${exercise.sets}séries × ${exercise.reps}repetições
~${exerciseCalories}kcal queimadas
`;});document.getElementById('workoutDetails').innerHTML=detailsHTML;document.getElementById('completionModal').classList.add('active');this.checkAchievements();this.updateWeightBasedOnCalories();this.updateUI();this.updateDetailedStats();this.isCompletingWorkout=false;}endWorkout(completed=false){clearInterval(this.workoutTimer);this.workoutSeconds=0;this.stopSound('backgroundYoga');this.stopSound('startYoga');if(this.currentCategory){this.goBack();}else{this.navigateTo('home');}}getExerciseCaloriesPerMinute(exerciseName){const name=exerciseName.toLowerCase();let caloriesPerMinute=8;if(name.includes('scissor')|| name.includes('tesoura')){caloriesPerMinute=12;}else if(name.includes('prancha')|| name.includes('plank')){caloriesPerMinute=10;}else if(name.includes('elevação')|| name.includes('leg lift')){caloriesPerMinute=9;}else if(name.includes('face')|| name.includes('rosto')|| name.includes('papada')|| name.includes('chin')|| name.includes('linha')|| name.includes('esculpida')|| name.includes('afinada')){caloriesPerMinute=3;}else if(name.includes('agachamento')|| name.includes('squat')|| name.includes('rotação')){caloriesPerMinute=11;}else if(name.includes('flexão')|| name.includes('push')|| name.includes('extensão')){caloriesPerMinute=10;}else if(name.includes('ponte')|| name.includes('bridge')){caloriesPerMinute=9;}else if(name.includes('burpee')|| name.includes('jump')){caloriesPerMinute=14;}else if(name.includes('polichinelo')|| name.includes('jack')){caloriesPerMinute=13;}else if(name.includes('alongamento')|| name.includes('stretch')){caloriesPerMinute=6;}else if(name.includes('torção')|| name.includes('twist')){caloriesPerMinute=7;}else if(name.includes('yoga')){caloriesPerMinute=5;}else if(name.includes('massagem')|| name.includes('massage')){caloriesPerMinute=2;}return caloriesPerMinute;}calculateCalories(minutes,workoutExercises=null){if(!workoutExercises || workoutExercises.length===0){return Math.round(minutes*8);}const userWeight=this.userProfile?.weight || 65;let totalCalories=0;const minutesPerExercise=minutes/workoutExercises.length;workoutExercises.forEach(exercise=>{const met=this.getExerciseMET(exercise.name);const timeInHours=minutesPerExercise/60;const caloriesFromMET=met*userWeight*timeInHours;const sets=exercise.sets || 3;let reps=15;if(typeof exercise.reps==='number'){reps=exercise.reps;}else if(typeof exercise.reps==='string'){const repsMatch=exercise.reps.match(/\d+/);if(repsMatch){reps=parseInt(repsMatch[0]);}}const intensityFactor=(sets*reps)/45;const caloriesForThisExercise=caloriesFromMET*intensityFactor;totalCalories+=caloriesForThisExercise;});return Math.round(totalCalories);}getExerciseMET(exerciseName){const metValues={'prancha com balanço lateral':8.5,'prancha com elevação de perna':9.0,'tesoura':8.0,'elevação alternada de pernas':7.5,'prancha lateral com rotação':8.5,'face esculpida':2.0,'face afinada':2.0,'redução de linhas':2.0,'redução de papada':2.5,'alongamento lateral dinâmico':3.5,'torção do tronco sentado':4.0,'flexão lateral em pé':3.5,'agachamento com rotação':9.0,'flexão e extensão do tronco':5.5,'prancha':8.0,'abdominal':8.0,'bicicleta':8.0,'mountain climber':8.0,'russian twist':7.0,'scissor':8.0,'agachamento':8.0,'afundo':8.0,'ponte':6.0,'leg lift':7.0,'elevação':7.5,'squat':8.0,'lunge':8.0,'glúteo':7.0,'ponte glúteos':6.0,'chute':7.0,'donkey kick':7.0,'flexão':8.0,'tríceps':7.0,'prancha lateral':8.0,'push-up':8.0,'burpee':12.0,'jumping jack':8.0,'pular':10.0,'corrida':10.0,'polichinelo':8.0,'yoga':3.0,'alongamento':2.5,'respiração':2.0,'torção':4.0,'twist':4.0,'massagem':2.0,'postura':2.5,'face':2.0,'facial':2.0,'papada':2.5,'chin':2.5,'linha':2.0,'esculpida':2.0,'afinada':2.0};const lowerName=exerciseName.toLowerCase();if(metValues[lowerName]){return metValues[lowerName];}for(const[key,met]of Object.entries(metValues)){if(lowerName.includes(key)){return met;}}return 6.0;}updateWeightBasedOnCalories(){if(!this.userProfile || !this.weightData || !this.weightData.history || this.weightData.history.length===0)return;const today=new Date().toDateString();const lastWeightEntry=this.weightData.history[this.weightData.history.length-1];const lastWeightDate=new Date(lastWeightEntry.date).toDateString();if(lastWeightDate===today)return;const caloriesIn=this.progress.dailyCaloriesConsumed || this.userProfile.targetCalories;const caloriesBurned=this.progress.totalCalories || 0;const tdee=this.userProfile.tdee || 2000;const dailyDeficit=(tdee+caloriesBurned)-caloriesIn;const weightChange=dailyDeficit/7700;const safeWeightChange=Math.max(-0.15,Math.min(0.15,weightChange));const currentWeight=lastWeightEntry.weight;const newWeight=Math.max(30,currentWeight-safeWeightChange);this.weightData.history.push({date:new Date().toISOString(),weight:parseFloat(newWeight.toFixed(1)),auto:true});this.weightData.current=newWeight;this.userProfile.weight=newWeight;this.saveWeightData();this.saveUserProfile();this.progress.dailyCaloriesConsumed=this.userProfile.targetCalories;this.saveProgress();,change:safeWeightChange.toFixed(3),deficit:dailyDeficit.toFixed(0)});}addCaloriesConsumed(calories){if(!this.progress.dailyCaloriesConsumed){this.progress.dailyCaloriesConsumed=0;}this.progress.dailyCaloriesConsumed+=calories;this.saveProgress();this.updateUI();}resetDailyCalories(){const today=new Date().toDateString();const lastReset=this.progress.lastCalorieReset || '';if(lastReset !==today){this.progress.dailyCaloriesConsumed=0;this.progress.lastCalorieReset=today;this.saveProgress();}}updateStreak(){const today=new Date().toDateString();const lastWorkout=this.progress.lastWorkout ? new Date(this.progress.lastWorkout).toDateString():null;if(!lastWorkout){this.progress.streak=1;}else{const yesterday=new Date();yesterday.setDate(yesterday.getDate()-1);if(lastWorkout===today){return;}else if(lastWorkout===yesterday.toDateString()){this.progress.streak=(this.progress.streak || 0)+1;}else{this.progress.streak=1;}}if(!this.progress.longestStreak || this.progress.streak > this.progress.longestStreak){this.progress.longestStreak=this.progress.streak;}}toggleWater(index){const glasses=document.querySelectorAll('.glass');const glass=glasses[index];if(glass.classList.contains('filled')){for(let i=index;i < glasses.length;i++){glasses[i].classList.remove('filled');}}else{for(let i=0;i <=index;i++){glasses[i].classList.add('filled');}this.playCuteSound('tap');}const filled=document.querySelectorAll('.glass.filled').length;document.getElementById('waterCount').textContent=filled;if(filled===8){this.playCuteSound('success');}const today=new Date().toISOString().split('T')[0];if(!this.progress.water)this.progress.water={};this.progress.water[today]=Array(filled).fill(1);this.saveProgress();this.updateDetailedStats();}startWellnessSession(type){const sessions=this.getWellnessSessions();const session=sessions[type];if(session){this.startWorkout(session.exercises,0);}}updateAllStats(){if(this.weightData && this.userProfile){if(this.weightData.current && this.weightData.current !==this.userProfile.weight){this.userProfile.weight=this.weightData.current;this.saveUserProfile();}if(this.weightData.goal && this.weightData.goal !==this.userProfile.goalWeight){this.userProfile.goalWeight=this.weightData.goal;this.saveUserProfile();}}this.updateUI();this.updateWeightDisplay();this.updateDetailedStats();}updateUI(){const hour=new Date().getHours();let greeting='Olá';if(hour < 12)greeting='Bom dia';else if(hour < 18)greeting='Boa tarde';else greeting='Boa noite';const name=this.userProfile ? this.userProfile.name.split(' ')[0]:'Guerreira';const greetingEl=document.getElementById('greeting');if(greetingEl)greetingEl.textContent=`${greeting},${name}!`;if(this.userProfile && this.userProfile.photo){const avatar=document.querySelector('.avatar');if(avatar){avatar.style.backgroundImage=`url(${this.userProfile.photo})`;avatar.style.backgroundSize='cover';avatar.style.backgroundPosition='center';avatar.textContent='';}}this.updatePlanSummary();const streakEl=document.getElementById('streakDays');if(streakEl)streakEl.textContent=this.progress.streak || 0;const todayProgress=this.calculateTodayProgress();const progressValueEl=document.getElementById('progressValue');const progressFillEl=document.getElementById('progressFill');if(progressValueEl)progressValueEl.textContent=todayProgress;if(progressFillEl)progressFillEl.style.setProperty('--progress',todayProgress);const caloriesBurnedEl=document.getElementById('caloriesBurned');const minutesActiveEl=document.getElementById('minutesActive');const workoutsCompletedEl=document.getElementById('workoutsCompleted');if(caloriesBurnedEl)caloriesBurnedEl.textContent=this.progress.totalCalories || 0;if(minutesActiveEl)minutesActiveEl.textContent=this.progress.totalMinutes || 0;if(workoutsCompletedEl)workoutsCompletedEl.textContent=this.progress.workoutsCompleted || 0;const totalWorkoutsEl=document.getElementById('totalWorkouts');const totalMinutesEl=document.getElementById('totalMinutes');const totalCaloriesEl=document.getElementById('totalCalories');const daysActiveEl=document.getElementById('daysActive');if(totalWorkoutsEl)totalWorkoutsEl.textContent=this.progress.workoutsCompleted || 0;if(totalMinutesEl)totalMinutesEl.textContent=this.progress.totalMinutes || 0;if(totalCaloriesEl)totalCaloriesEl.textContent=this.progress.totalCalories || 0;if(daysActiveEl)daysActiveEl.textContent=this.progress.daysActive || 0;const waterToday=this.getWaterToday();document.querySelectorAll('.glass').forEach((glass,index)=>{if(index < waterToday){glass.classList.add('filled');}else{glass.classList.remove('filled');}});document.getElementById('waterCount').textContent=waterToday;}calculateTodayProgress(){const workouts=this.progress.todayWorkouts || 0;const water=this.getWaterToday();const workoutProgress=Math.min((workouts/2)*100,50);const waterProgress=Math.min((water/8)*100,50);return Math.round(workoutProgress+waterProgress);}getWaterToday(){const today=new Date().toISOString().split('T')[0];const waterData=this.progress.water?.[today];if(Array.isArray(waterData)){return waterData.length;}return 0;}loadAchievements(){this.achievements=[{id:'first-workout',name:'Primeiro Passo',emoji:'👟',unlocked:(this.progress.workoutsCompleted || 0)>=1},{id:'five-workouts',name:'5 Treinos',emoji:'💪',unlocked:(this.progress.workoutsCompleted || 0)>=5},{id:'week-streak',name:'1 Semana',emoji:'🔥',unlocked:(this.progress.streak || 0)>=7},{id:'ten-workouts',name:'10 Treinos',emoji:'🏋️',unlocked:(this.progress.workoutsCompleted || 0)>=10},{id:'water-master',name:'Hidratada',emoji:'💧',unlocked:this.checkWaterStreak(5)},{id:'month-streak',name:'1 Mês',emoji:'🏆',unlocked:(this.progress.streak || 0)>=30},{id:'twenty-workouts',name:'20 Treinos',emoji:'💯',unlocked:(this.progress.workoutsCompleted || 0)>=20},{id:'fifty-workouts',name:'50 Treinos',emoji:'⭐',unlocked:(this.progress.workoutsCompleted || 0)>=50},{id:'weight-loss',name:'Peso Perdido',emoji:'📉',unlocked:this.checkWeightLoss()},{id:'hundred-workouts',name:'100 Treinos',emoji:'🎯',unlocked:(this.progress.workoutsCompleted || 0)>=100},{id:'yoga-master',name:'Mestre Yoga',emoji:'🧘♀️',unlocked:this.checkYogaWorkouts()},{id:'dedication',name:'Dedicação',emoji:'🌟',unlocked:(this.progress.daysActive || 0)>=30}];const container=document.getElementById('achievementsGrid');if(container){const fragment=document.createDocumentFragment();this.achievements.forEach(achievement=>{const card=document.createElement('div');card.className=`achievement-card ${achievement.unlocked ? '':'locked'}`;card.innerHTML=`
${achievement.unlocked ? achievement.emoji:'🔒'}
${achievement.name}
`;fragment.appendChild(card);});container.innerHTML='';container.appendChild(fragment);}}checkWeightLoss(){if(this.weightData.initial && this.weightData.current){return this.weightData.initial > this.weightData.current;}return false;}checkYogaWorkouts(){if(!this.progress.workoutHistory)return false;const yogaWorkouts=this.progress.workoutHistory.filter(w=> w.category==='yoga');return yogaWorkouts.length >=5;}checkAchievements(){this.loadAchievements();}checkWaterStreak(days){if(!this.progress.water)return false;let streak=0;const today=new Date();for(let i=0;i < 30;i++){const date=new Date(today);date.setDate(date.getDate()-i);const dateStr=date.toDateString();if(this.progress.water[dateStr]>=8){streak++;if(streak >=days)return true;}else{break;}}return false;}requestNotificationPermission(){if('Notification' in window && Notification.permission !=='granted'){Notification.requestPermission().then(permission=>{if(permission==='granted'){new Notification('Notificações Ativadas! 🔔',{body:'Você receberá lembretes motivacionais!',icon:'/icons/icon.svg'});}});}}playSound(){if(this.userData.soundEnabled !==false){const context=new(window.AudioContext || window.webkitAudioContext)();const oscillator=context.createOscillator();const gainNode=context.createGain();oscillator.connect(gainNode);gainNode.connect(context.destination);oscillator.frequency.value=800;oscillator.type='sine';gainNode.gain.setValueAtTime(0.3,context.currentTime);gainNode.gain.exponentialRampToValueAtTime(0.01,context.currentTime+0.1);oscillator.start(context.currentTime);oscillator.stop(context.currentTime+0.1);}}loadUserData(){try{const data=localStorage.getItem('userData');if(!data)return{};const parsed=JSON.parse(data);if(typeof parsed !=='object' || parsed===null){return{};}return parsed;}catch(e){console.error('⚠️ Failed to load userData,resetting:',e);localStorage.removeItem('userData');return{};}}loadProgress(){try{if(window.PerformanceUtils){const data=window.PerformanceUtils.safeLocalStorageGet('userProgress',null,true);if(!data){return this.getDefaultProgress();}if(typeof data !=='object' || data===null){return this.getDefaultProgress();}return{...this.getDefaultProgress(),...data};}else{const dataString=localStorage.getItem('userProgress');if(!dataString){return this.getDefaultProgress();}const parsed=JSON.parse(dataString);if(typeof parsed !=='object' || parsed===null){return this.getDefaultProgress();}return{...this.getDefaultProgress(),...parsed};}}catch(e){console.error('Error loading progress:',e);return this.getDefaultProgress();}}getDefaultProgress(){return{workoutsCompleted:0,totalMinutes:0,totalCalories:0,streak:0,daysActive:0,water:{},workoutHistory:[],todayWorkouts:0,todayMinutes:0,todayCalories:0,longestStreak:0,longestWorkout:0,memberSince:null};}saveProgress(){if(!this.saveProgressDebounced){if(window.PerformanceUtils){this.saveProgressDebounced=window.PerformanceUtils.debounce(()=>{this._doSaveProgress();},300);}else{this.saveProgressDebounced=this._doSaveProgress.bind(this);}}this.saveProgressDebounced();}_doSaveProgress(){try{if(window.PerformanceUtils){const shouldCompress=JSON.stringify(this.progress).length > 50000;window.PerformanceUtils.safeLocalStorageSet('userProgress',this.progress,shouldCompress);}else{localStorage.setItem('userProgress',JSON.stringify(this.progress));}}catch(e){console.error('Failed to save progress:',e);if(e.name==='QuotaExceededError'){this.compressProgress();}}}compressProgress(){if(this.progress.workoutHistory && this.progress.workoutHistory.length > 30){this.progress.workoutHistory=this.progress.workoutHistory.slice(-30);}if(this.progress.water){const thirtyDaysAgo=new Date();thirtyDaysAgo.setDate(thirtyDaysAgo.getDate()-30);const recentWater={};Object.keys(this.progress.water).forEach(key=>{const date=new Date(key);if(date >=thirtyDaysAgo){recentWater[key]=this.progress.water[key];}});this.progress.water=recentWater;}try{localStorage.setItem('userProgress',JSON.stringify(this.progress));}catch(e){console.error('Still failed after compression:',e);}}loadWeightData(){try{const data=localStorage.getItem('weightData');if(!data){return this.getDefaultWeightData();}const parsed=JSON.parse(data);if(typeof parsed !=='object' || parsed===null){return this.getDefaultWeightData();}if(!parsed.history || !Array.isArray(parsed.history)){localStorage.removeItem('weightData');return this.getDefaultWeightData();}return{...this.getDefaultWeightData(),...parsed};}catch(e){console.error('⚠️ Corrupted weight data,resetting:',e);localStorage.removeItem('weightData');return this.getDefaultWeightData();}}getDefaultWeightData(){return{current:null,initial:null,goal:null,history:[]};}saveWeightData(){if(!this.saveWeightDebounced){if(window.PerformanceUtils){this.saveWeightDebounced=window.PerformanceUtils.debounce(()=>{try{window.PerformanceUtils.safeLocalStorageSet('weightData',this.weightData);}catch(e){console.error('Failed to save weight data:',e);}},300);}else{this.saveWeightDebounced=()=>{try{localStorage.setItem('weightData',JSON.stringify(this.weightData));}catch(e){console.error('Failed to save weight data:',e);}};}}this.saveWeightDebounced();}showWeightModal(){const modal=document.getElementById('weightModal');const weightInput=document.getElementById('weightInput');const goalInput=document.getElementById('goalWeightInput');weightInput.value=this.weightData.current || '';goalInput.value=this.weightData.goal || '';modal.classList.add('active');this.playCuteSound('tap');}closeWeightModal(){const modal=document.getElementById('weightModal');modal.classList.remove('active');this.playCuteSound('tap');}saveWeight(){const weightInput=document.getElementById('weightInput');const goalInput=document.getElementById('goalWeightInput');if(!weightInput || !goalInput){console.error('Weight inputs not found');return;}const newWeight=this.sanitizeNumber(weightInput.value,30,300,null);const newGoal=this.sanitizeNumber(goalInput.value,30,300,null);if(newWeight===null || newWeight < 30 || newWeight > 300){alert('Por favor,insira um peso válido entre 30 e 300 kg');return;}if(newGoal===null || newGoal < 30 || newGoal > 300){alert('Por favor,insira uma meta válida entre 30 e 300 kg');return;}if(this.userProfile){this.userProfile.weight=newWeight;this.userProfile.goalWeight=newGoal;this.saveUserProfile();}if(this.weightData.initial===null){this.weightData.initial=newWeight;if(!this.progress.memberSince){this.progress.memberSince=new Date().toISOString();}}this.weightData.current=newWeight;this.weightData.goal=newGoal;const today=new Date().toISOString().split('T')[0];const existingIndex=this.weightData.history.findIndex(entry=> entry.date===today);if(existingIndex >=0){this.weightData.history[existingIndex].weight=newWeight;}else{this.weightData.history.push({date:today,weight:newWeight});}if(this.weightData.history.length > 30){this.weightData.history=this.weightData.history.slice(-30);}this.saveWeightData();this.saveProgress();this.updateAllStats();this.closeWeightModal();this.playCuteSound('success');}updateWeightDisplay(){const currentWeightEl=document.getElementById('currentWeight');const initialWeightEl=document.getElementById('initialWeight');const goalWeightEl=document.getElementById('goalWeight');const weightLostEl=document.getElementById('weightLost');const weightProgressFill=document.getElementById('weightProgressFill');const weightChartMini=document.getElementById('weightChartMini');if(currentWeightEl){if(this.weightData.current){currentWeightEl.textContent=`${this.weightData.current}kg`;}else{currentWeightEl.textContent='--';}}if(initialWeightEl){if(this.weightData.initial){initialWeightEl.textContent=`${this.weightData.initial}kg`;}else{initialWeightEl.textContent='--';}}if(goalWeightEl){if(this.weightData.goal){goalWeightEl.textContent=`${this.weightData.goal}kg`;}else{goalWeightEl.textContent='--';}}if(weightLostEl){if(this.weightData.initial && this.weightData.current){const lost=this.weightData.initial-this.weightData.current;weightLostEl.textContent=`${lost.toFixed(1)}kg`;}else{weightLostEl.textContent='0 kg';}}if(weightProgressFill){if(this.weightData.initial && this.weightData.current && this.weightData.goal){const totalToLose=this.weightData.initial-this.weightData.goal;const lost=this.weightData.initial-this.weightData.current;const percentage=Math.min(100,(lost/totalToLose)*100);weightProgressFill.style.width=`${Math.max(0,percentage)}%`;}else{weightProgressFill.style.width='0%';}}if(weightChartMini && this.weightData.history && this.weightData.history.length > 0){const maxWeight=Math.max(...this.weightData.history.map(e=> e.weight));const minWeight=Math.min(...this.weightData.history.map(e=> e.weight));const range=maxWeight-minWeight || 1;weightChartMini.innerHTML=this.weightData.history.slice(-10).map(entry=>{const height=((entry.weight-minWeight)/range)*80+20;return `
`;}).join('');}}wasCompletedIn24h(exerciseName){if(!this.progress.completedExercises){return false;}const now=new Date();const twentyFourHoursAgo=new Date(now.getTime()-(24*60*60*1000));this.progress.completedExercises=this.progress.completedExercises.filter(ex=>{const completedDate=new Date(ex.completedAt);return completedDate > twentyFourHoursAgo;});return this.progress.completedExercises.some(ex=>{const completedDate=new Date(ex.completedAt);return ex.name===exerciseName && completedDate > twentyFourHoursAgo;});}renderWeeklyActivity(){const container=document.getElementById('weeklyActivityGrid');if(!container)return;container.innerHTML='';const today=new Date();const weekDays=['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'];const fragment=document.createDocumentFragment();for(let i=6;i >=0;i--){const date=new Date(today);date.setDate(date.getDate()-i);const dayName=weekDays[date.getDay()];const dayNumber=date.getDate();const isToday=date.toDateString()===today.toDateString();const workoutsCount=this.progress.workoutHistory ? this.progress.workoutHistory.filter(w=>{const workoutDate=new Date(w.date);return workoutDate.toDateString()===date.toDateString();}).length:0;const dayElement=document.createElement('div');dayElement.className='weekly-day';if(workoutsCount > 0){dayElement.classList.add('active');}if(isToday){dayElement.classList.add('today');}dayElement.innerHTML=`
${dayName}
${dayNumber}
${workoutsCount > 0 ? `${workoutsCount}treino${workoutsCount > 1 ? 's':''}`:'-'}
`;fragment.appendChild(dayElement);}container.appendChild(fragment);}updateDetailedStats(){this.renderWeeklyActivity();document.getElementById('totalWorkouts').textContent=this.progress.workoutsCompleted || 0;document.getElementById('totalMinutes').textContent=this.progress.totalMinutes || 0;document.getElementById('totalCaloriesDetail').textContent=this.progress.totalCalories || 0;const uniqueDays=new Set();if(this.progress.workoutHistory){this.progress.workoutHistory.forEach(w=>{const date=new Date(w.date).toDateString();uniqueDays.add(date);});}this.progress.daysActive=uniqueDays.size;document.getElementById('daysActiveDetail').textContent=this.progress.daysActive || 0;document.getElementById('currentStreak').textContent=this.progress.streak || 0;if(this.userProfile){const bmi=this.userProfile.bmi || this.calculateBMI(this.userProfile.weight,this.userProfile.height);let bmiCategory='';let bmiColor='';if(bmi < 18.5){bmiCategory='Abaixo do Peso';bmiColor='#FFA726';}else if(bmi < 25){bmiCategory='Peso Normal';bmiColor='#4CAF50';}else if(bmi < 30){bmiCategory='Sobrepeso';bmiColor='#FF9800';}else{bmiCategory='Obesidade';bmiColor='#F44336';}let bmiCard=document.getElementById('bmiCard');if(!bmiCard){const statsGrid=document.querySelector('.stats-grid');if(statsGrid){bmiCard=document.createElement('div');bmiCard.id='bmiCard';bmiCard.className='stat-detail-card';statsGrid.insertBefore(bmiCard,statsGrid.firstChild);}}if(bmiCard){bmiCard.innerHTML=`
⚖️
${bmi}
IMC(Índice de Massa Corporal)
${bmiCategory}
`;}let avgCalCard=document.getElementById('avgCaloriesCard');if(!avgCalCard){const statsGrid=document.querySelector('.stats-grid');if(statsGrid){avgCalCard=document.createElement('div');avgCalCard.id='avgCaloriesCard';avgCalCard.className='stat-detail-card';statsGrid.appendChild(avgCalCard);}}if(avgCalCard){const avgCal=this.progress.workoutsCompleted > 0 ? Math.round(this.progress.totalCalories/this.progress.workoutsCompleted):0;avgCalCard.innerHTML=`
🔥
${avgCal}
Calorias Médias
por treino
`;}}const thisWeek=this.getThisWeekWorkouts();document.getElementById('thisWeekWorkouts').textContent=thisWeek;const avgMinutes=this.progress.workoutsCompleted > 0 ? Math.round(this.progress.totalMinutes/this.progress.workoutsCompleted):0;const avgCalories=this.progress.workoutsCompleted > 0 ? Math.round(this.progress.totalCalories/this.progress.workoutsCompleted):0;document.getElementById('avgMinutes').textContent=avgMinutes;document.getElementById('avgCalories').textContent=avgCalories;const totalWaterGlasses=Object.values(this.progress.water ||{}).reduce((sum,day)=>{return sum+(Array.isArray(day)? day.length:0);},0);const waterStreak=this.getWaterStreak();document.getElementById('totalWaterGlasses').textContent=totalWaterGlasses;document.getElementById('waterStreak').textContent=waterStreak;if(!this.achievements){this.loadAchievements();}const unlockedAchievements=this.achievements.filter(a=> a.unlocked).length;document.getElementById('achievementsUnlocked').textContent=unlockedAchievements;document.getElementById('totalAchievements').textContent=this.achievements.length;document.getElementById('longestStreak').textContent=`${this.progress.longestStreak || 0}dias`;document.getElementById('longestWorkout').textContent=`${this.progress.longestWorkout || 0}min`;const favoriteCategory=this.getFavoriteCategory();document.getElementById('favoriteCategory').textContent=favoriteCategory;if(this.progress.memberSince){const date=new Date(this.progress.memberSince);const formatted=date.toLocaleDateString('pt-BR');document.getElementById('memberSince').textContent=formatted;}else{document.getElementById('memberSince').textContent='--';}}getThisWeekWorkouts(){if(!this.progress.workoutHistory)return 0;const oneWeekAgo=new Date();oneWeekAgo.setDate(oneWeekAgo.getDate()-7);return this.progress.workoutHistory.filter(workout=>{const workoutDate=new Date(workout.date);return workoutDate >=oneWeekAgo;}).length;}getWaterStreak(){if(!this.progress.water)return 0;let streak=0;const today=new Date();for(let i=0;i < 365;i++){const date=new Date(today);date.setDate(date.getDate()-i);const dateKey=date.toISOString().split('T')[0];if(this.progress.water[dateKey]&& this.progress.water[dateKey].length >=8){streak++;}else{break;}}return streak;}getFavoriteCategory(){if(!this.progress.workoutHistory || this.progress.workoutHistory.length===0){return '--';}const categoryCount={};this.progress.workoutHistory.forEach(workout=>{categoryCount[workout.category]=(categoryCount[workout.category]|| 0)+1;});const favorite=Object.keys(categoryCount).reduce((a,b)=> categoryCount[a]> categoryCount[b]? a:b);const categoryNames={abs:'Abdômen',legs:'Pernas',glutes:'Glúteos',arms:'Braços',waist:'Cintura',back:'Costas',cardio:'Cardio',fullbody:'Corpo Todo',yoga:'Yoga',massage:'Massagem'};return categoryNames[favorite]|| favorite;}getExercisesByCategory(category){const exercises={personalized:[{name:'Prancha com Elevação de Perna',emoji:'🔥',videoFile:'Prancha com elevação de perna.mp4',sets:3,reps:'12 cada',rest:30,calories:12},{name:'Prancha com Balanço Lateral',emoji:'⚖️',videoFile:'Prancha com balanço lateral.mp4',sets:3,reps:'30s',rest:30,calories:11},{name:'Prancha Lateral com Rotação',emoji:'🔄',videoFile:'prancha lateral com rotação.mp4',sets:3,reps:'10 cada',rest:30,calories:13},{name:'Elevações Alternadas de Perna',emoji:'✂️',videoFile:'Alternating Leg Lifts.mp4',sets:3,reps:'20',rest:30,calories:10},{name:'Tesoura(Scissor Kicks)',emoji:'✂️',videoFile:'Scissor Kicks.mp4',sets:3,reps:'30s',rest:30,calories:11},{name:'Agachamento com Rotação',emoji:'🏋️♀️',videoFile:'agachamento rotação.mp4',sets:3,reps:'15',rest:35,calories:14},{name:'Flexão e Extensão do Tronco',emoji:'💪',videoFile:'flexao,extensão e hiperextenxao do tronco com baco estendido.mp4',sets:3,reps:'12',rest:30,calories:10},{name:'Exercício de Escápula',emoji:'🦋',videoFile:'Scapular winging exercise ou Elbow fly stretch.mp4',sets:3,reps:'15',rest:30,calories:9},{name:'Alongamento Dinâmico Lateral',emoji:'↔️',videoFile:'Dynamic Side Stretch].mp4',sets:2,reps:'10 cada',rest:25,calories:8},{name:'Alongamento de Lado(Sentado)',emoji:'🧘',videoFile:'Side Bend Stretch.mp4',sets:2,reps:'30s cada',rest:25,calories:6},{name:'Torção de Torso(Sentado)',emoji:'🔄',videoFile:'Seated Torso Twist.mp4',sets:3,reps:'15 cada',rest:25,calories:8},{name:'Alongamento de Ombro',emoji:'💆♀���',videoFile:'MobilidadeAlongamento de Ombro com Apoio(Garrafa ou Outro Objeto.mp4',sets:2,reps:'30s cada',rest:20,calories:7},{name:'Circundução com Garrafa',emoji:'🔄',videoFile:'Circundução órbita com a garrafa ao redor da nuca com reverso.mp4',sets:3,reps:'12',rest:30,calories:9},{name:'Alcance Cruzado nas Costas',emoji:'🤝',videoFile:'Alcance cruzado por trás das costas(pegada alternada).mp4',sets:2,reps:'10 cada',rest:25,calories:7},{name:'Alongamento de Peitoral',emoji:'💪',videoFile:'Alongamento de Peitoral com Mãos Entrelaçadas Atrás do Corpo.mp4',sets:2,reps:'30s',rest:20,calories:6},{name:'Alongamento de Tríceps',emoji:'💪',videoFile:'Overhead triceps stretch.mp4',sets:2,reps:'30s cada',rest:20,calories:6},{name:'Exercício para Queixo Duplo',emoji:'😊',videoFile:'Double chin.mp4',sets:2,reps:'15',rest:20,calories:4},{name:'Rosto Esculpido',emoji:'✨',videoFile:'Sculpted face.mp4',sets:2,reps:'12',rest:20,calories:4},{name:'Rosto Afinado',emoji:'😌',videoFile:'Slim face.mp4',sets:2,reps:'12',rest:20,calories:4},{name:'Linhas de Sorriso',emoji:'😄',videoFile:'Smile lines.mp4',sets:2,reps:'15',rest:20,calories:3}],abs:[{name:'Abdominal Águia em Pé',emoji:'🔥',youtubeId:'MkMB8Hdq2qU',sets:3,reps:'40s',rest:30,calories:11},{name:'Ponte com Elevação de Perna',emoji:'🌉',youtubeId:'JxnGOaye88w',sets:3,reps:'34s',rest:30,calories:9},{name:'Prancha Reversa',emoji:'🧘♀️',youtubeId:'mX_SX6I2DSI',sets:3,reps:'37s',rest:30,calories:10},{name:'Prancha Ajoelhado',emoji:'🧘♀️',youtubeId:'xNBL63AhZcc',sets:3,reps:'34s',rest:30,calories:9},{name:'Chutes Tesoura',emoji:'✂️',youtubeId:'9i0J_I4ASow',sets:3,reps:'12',rest:30,calories:6},{name:'Prancha com Mergulho de Quadril',emoji:'🧘♀️',youtubeId:'h1_Y3GBUd0M',sets:3,reps:'23s',rest:30,calories:6},{name:'Abdominal Oblíquo',emoji:'🔥',youtubeId:'Z9WtuN50f9s',sets:3,reps:'24s',rest:30,calories:6},{name:'Abdominal Estrela',emoji:'🔥',youtubeId:'HBB5tf2vndA',sets:3,reps:'28s',rest:30,calories:7},{name:'Abdominal Bicicleta Elevado',emoji:'🔥',youtubeId:'1xEZ1So_D-A',sets:3,reps:'12',rest:30,calories:5},{name:'Prancha Homem-Aranha',emoji:'🧘♀️',youtubeId:'G8-vocJfWEM',sets:3,reps:'12',rest:30,calories:6},{name:'Prancha com Rotação',emoji:'🧘♀️',youtubeId:'fu6-teFilJk',sets:3,reps:'24s',rest:30,calories:6},{name:'Abdominal Cruzado',emoji:'🔥',youtubeId:'LATqsI5q0hc',sets:3,reps:'24s',rest:30,calories:6}],face:[{name:'Rosto de Peixe Sorridente',emoji:'😊',youtubeId:'mLYm4ItAuro',sets:2,reps:'10',rest:20,calories:3},{name:'Firmador de Bochechas',emoji:'✨',youtubeId:'83Xu_F92j60',sets:2,reps:'12',rest:20,calories:3},{name:'Linha do Maxilar',emoji:'😄',youtubeId:'R2cqpjvaB3E',sets:2,reps:'10',rest:20,calories:2}],waist:[{name:'Meio Barco com Torção',emoji:'🔄',youtubeId:'PSZgJiFIrHQ',sets:3,reps:'31s',rest:30,calories:7},{name:'Inclinação Lateral Sentado',emoji:'⏳',youtubeId:'jKcHh78Y_JE',sets:3,reps:'12',rest:30,calories:5},{name:'Torção de Coluna Sentado',emoji:'🔄',youtubeId:'4YlCtaTdtgA',sets:3,reps:'26s',rest:30,calories:6},{name:'Torção de Tronco',emoji:'🔄',youtubeId:'HMKbmG1L7vc',sets:3,reps:'12',rest:30,calories:4},{name:'Inclinação Lateral em Pé',emoji:'⏳',youtubeId:'RfuiraEgKcY',sets:3,reps:'24s',rest:30,calories:6},{name:'V-Ups Oblíquo',emoji:'⏳',youtubeId:'iFaZ095MMGg',sets:3,reps:'25s',rest:30,calories:6},{name:'Torção Oblíqua Reclinada',emoji:'🔄',youtubeId:'XKW5jru5pGo',sets:3,reps:'25s',rest:30,calories:6},{name:'V-Up Oblíquo',emoji:'⏳',youtubeId:'dZGajX67rdQ',sets:3,reps:'29s',rest:30,calories:7}],back:[{name:'Puxada de Costas',emoji:'💆♀️',youtubeId:'GvyCtKvmaVE',sets:3,reps:'12',rest:30,calories:4},{name:'Remada Curvado',emoji:'💆♀️',youtubeId:'t2DUqP_13x8',sets:3,reps:'25s',rest:30,calories:5},{name:'Remada Alta',emoji:'💆♀️',youtubeId:'8ywEQiJuBNg',sets:3,reps:'28s',rest:30,calories:6},{name:'Alongamento de Peito',emoji:'💆♀️',youtubeId:'JoxGFxbgJ2Y',sets:3,reps:'12',rest:30,calories:4},{name:'Remada Deltóide Posterior',emoji:'💆♀️',youtubeId:'65gMtswVB1c',sets:3,reps:'30s',rest:30,calories:6},{name:'Remada Alternada',emoji:'💆♀️',youtubeId:'KvoHxslZun0',sets:3,reps:'23s',rest:30,calories:5},{name:'Elevação Lateral',emoji:'💆♀️',youtubeId:'6L19uhg2otQ',sets:3,reps:'23s',rest:30,calories:5},{name:'Puxada de Rombóide',emoji:'💆♀️',youtubeId:'DEyDbzSudEU',sets:3,reps:'26s',rest:30,calories:5},{name:'Super-Homem',emoji:'🦸♀️',youtubeId:'pGeaBXLwDtw',sets:3,reps:'12',rest:30,calories:4},{name:'Nadador e Super-Homem',emoji:'💆♀️',youtubeId:'XydDDn_Rngw',sets:3,reps:'25s',rest:30,calories:5}],legs:[{name:'Agachamento Sumo na Parede',emoji:'🏋️♀️',youtubeId:'oR90gl2vj7c',sets:3,reps:'40s',rest:30,calories:13},{name:'Afundo Baixo Crescente',emoji:'🦵',youtubeId:'93kUVEAqiv8',sets:3,reps:'43s',rest:30,calories:14},{name:'Afundo com Torção',emoji:'🔄',youtubeId:'E-_LxciEon4',sets:3,reps:'41s',rest:30,calories:14},{name:'Afundo com Braço Elevado',emoji:'🦵',youtubeId:'VQwrouNIlXw',sets:3,reps:'36s',rest:30,calories:12},{name:'Afundo Baixo',emoji:'🦵',youtubeId:'dXREtCBZnV4',sets:3,reps:'36s',rest:30,calories:12},{name:'Barco com Pernas Alternadas',emoji:'🦵',youtubeId:'ii245b_MNxI',sets:3,reps:'35s',rest:30,calories:12},{name:'Alongamento Posterior de Pernas',emoji:'🦵',youtubeId:'tShKvg4h12k',sets:3,reps:'32s',rest:30,calories:11},{name:'Alongamento Ajoelhado',emoji:'🦵',youtubeId:'lWi7rZWJ2cY',sets:3,reps:'30s',rest:30,calories:10},{name:'Afundo do Corredor',emoji:'🦵',youtubeId:'6ikwduxu0JU',sets:3,reps:'32s',rest:30,calories:11},{name:'Abertura de Pernas',emoji:'🦵',youtubeId:'aZRDySUyC1I',sets:3,reps:'12',rest:30,calories:6},{name:'Agachamento com Saltos',emoji:'🏋️♀️',youtubeId:'tcgvAxhEhvQ',sets:3,reps:'12',rest:30,calories:7},{name:'Joelho ao Peito em Pé',emoji:'🦵',youtubeId:'uC7dzhqN47M',sets:3,reps:'26s',rest:30,calories:9}],glutes:[{name:'Postura da Borboleta',emoji:'🦋',youtubeId:'seRyFNh7boQ',sets:3,reps:'33s',rest:30,calories:10},{name:'Alongamento Borboleta',emoji:'🦋',youtubeId:'QehQaZvvquA',sets:3,reps:'24s',rest:30,calories:7},{name:'Ponte de Glúteo',emoji:'🌉',youtubeId:'6gGzYaD9Cb4',sets:3,reps:'24s',rest:30,calories:7},{name:'Ponte Borboleta',emoji:'🌉',youtubeId:'sJC_fMOVZVw',sets:3,reps:'24s',rest:30,calories:7},{name:'Coice de Glúteo',emoji:'🍑',youtubeId:'3ao9J4vvEXA',sets:3,reps:'26s',rest:30,calories:8},{name:'Chute de Burro',emoji:'🦵',youtubeId:'pd3KyzQS5nc',sets:3,reps:'24s',rest:30,calories:7},{name:'Coice de Tríceps',emoji:'🍑',youtubeId:'zfnWQVmDspU',sets:3,reps:'24s',rest:30,calories:7},{name:'Hidrante com Pulso',emoji:'🔥',youtubeId:'uILAw7D7fxE',sets:3,reps:'12',rest:30,calories:7},{name:'Chute com Pulso',emoji:'🦵',youtubeId:'QaTh15GsgHk',sets:3,reps:'25s',rest:30,calories:7},{name:'Coice de Glúteo com Pulso',emoji:'🍑',youtubeId:'Lxdu7Nlp6KE',sets:3,reps:'26s',rest:30,calories:8},{name:'Alongamento de Glúteo',emoji:'🍑',youtubeId:'vSKSU8KDc38',sets:3,reps:'12',rest:30,calories:6},{name:'Coice de Glúteo na Parede',emoji:'🍑',youtubeId:'qzqDHSDTc0U',sets:3,reps:'23s',rest:30,calories:7}],arms:[{name:'Flexão Isométrica',emoji:'💪',youtubeId:'16-WWEQNiK0',sets:3,reps:'34s',rest:30,calories:8},{name:'Flexão com Remada',emoji:'💪',youtubeId:'DpsHmYX3Ifg',sets:3,reps:'25s',rest:30,calories:6},{name:'Extensão de Tríceps Sentado',emoji:'💪',youtubeId:'-9Uup5bhPBI',sets:3,reps:'12',rest:30,calories:5},{name:'Extensão de Tríceps Deitado',emoji:'💪',youtubeId:'FyBXas1QUWo',sets:3,reps:'24s',rest:30,calories:5},{name:'Rosca Bíceps Alternada',emoji:'💪',youtubeId:'sQbtGNsAcl4',sets:3,reps:'26s',rest:30,calories:6},{name:'Rosca Bíceps Aberta',emoji:'💪',youtubeId:'pB4Iic8p6Ag',sets:3,reps:'26s',rest:30,calories:6},{name:'Extensão de Tríceps',emoji:'💪',youtubeId:'a1Uanj_vaYA',sets:3,reps:'26s',rest:30,calories:6},{name:'Remada Renegada',emoji:'💪',youtubeId:'m0KEk-Y4iII',sets:3,reps:'12',rest:30,calories:5},{name:'Rosca para Press',emoji:'💪',youtubeId:'9C5EtvkK6k4',sets:3,reps:'29s',rest:30,calories:7},{name:'Círculos com os Braços',emoji:'💪',youtubeId:'wZVO6ZnARIE',sets:3,reps:'12',rest:30,calories:5},{name:'Flexões Desalinhadas',emoji:'💪',youtubeId:'32yYCbAQo5A',sets:3,reps:'12',rest:30,calories:5},{name:'Balanço de Braços Lateral',emoji:'💪',youtubeId:'tLEkdDgTDbM',sets:3,reps:'12',rest:30,calories:5}],cardio:[{name:'Saltos Estrela',emoji:'⭐',youtubeId:'VVEO_J1tIXU',sets:3,reps:'12',rest:20,calories:6},{name:'Alpinista Cruzado',emoji:'⛰️',youtubeId:'tIEkB8S42j8',sets:3,reps:'12',rest:20,calories:8},{name:'Burpees em X',emoji:'💥',youtubeId:'uD5BUL79CvY',sets:3,reps:'28s',rest:20,calories:11},{name:'Alpinista Lento',emoji:'⛰️',youtubeId:'24gpL7t4iPY',sets:3,reps:'12',rest:20,calories:9},{name:'Corrida na Parede',emoji:'🤸♀️',youtubeId:'Vvuj9R-w6a4',sets:3,reps:'12',rest:20,calories:6},{name:'Corte de Lenha',emoji:'🤸♀️',youtubeId:'Ax_94gEavYo',sets:3,reps:'12',rest:20,calories:8},{name:'Polichinelos Laterais',emoji:'🤸♀️',youtubeId:'p75NmUtH9so',sets:3,reps:'12',rest:20,calories:8},{name:'Rotação de Tronco',emoji:'🤸♀️',youtubeId:'YBgjuQMviCE',sets:3,reps:'12',rest:20,calories:8},{name:'Salto do Patinador',emoji:'⛸️',youtubeId:'5gtLC5BgN7Q',sets:3,reps:'12',rest:20,calories:9},{name:'Burpees Modificados',emoji:'💥',youtubeId:'8PbnMQISmZQ',sets:3,reps:'23s',rest:20,calories:9},{name:'Saltos no Lugar',emoji:'🤸♀️',youtubeId:'ImamH6J566s',sets:3,reps:'12',rest:20,calories:6},{name:'Salto Lateral',emoji:'🤸♀️',youtubeId:'nYmUEJIBj3c',sets:3,reps:'12',rest:20,calories:7},{name:'Burpees',emoji:'💥',youtubeId:'818SkLAPyKY',sets:3,reps:'12',rest:20,calories:9},{name:'Alpinista',emoji:'⛰️',youtubeId:'wQq3ybaLZeA',sets:3,reps:'12',rest:20,calories:9},{name:'Polichinelos',emoji:'🤸♀️',youtubeId:'2W4ZNSwoW_4',sets:3,reps:'12',rest:20,calories:8}],fullbody:[{name:'Burpees',emoji:'💥',youtubeId:'818SkLAPyKY',sets:3,reps:'10',rest:40,calories:15},{name:'Agachamento Sumo na Parede',emoji:'🏋️♀️',youtubeId:'oR90gl2vj7c',sets:3,reps:'40s',rest:30,calories:13},{name:'Flexão Isométrica',emoji:'💪',youtubeId:'16-WWEQNiK0',sets:3,reps:'34s',rest:30,calories:8},{name:'Prancha Reversa',emoji:'🧘♀️',youtubeId:'mX_SX6I2DSI',sets:3,reps:'37s',rest:30,calories:10},{name:'Alpinista',emoji:'⛰️',youtubeId:'wQq3ybaLZeA',sets:3,reps:'30s',rest:30,calories:13},{name:'Polichinelos',emoji:'🤸♀️',youtubeId:'2W4ZNSwoW_4',sets:3,reps:'30',rest:20,calories:12},{name:'Afundo Baixo Crescente',emoji:'🦵',youtubeId:'93kUVEAqiv8',sets:3,reps:'43s',rest:30,calories:14},{name:'Burpees em X',emoji:'💥',youtubeId:'uD5BUL79CvY',sets:3,reps:'28s',rest:20,calories:11},{name:'Abdominal Águia em Pé',emoji:'🔥',youtubeId:'MkMB8Hdq2qU',sets:3,reps:'40s',rest:30,calories:11},{name:'Salto do Patinador',emoji:'⛸️',youtubeId:'5gtLC5BgN7Q',sets:3,reps:'12',rest:20,calories:9},{name:'Ponte com Elevação de Perna',emoji:'🌉',youtubeId:'JxnGOaye88w',sets:3,reps:'34s',rest:30,calories:9}],yoga:[{name:'Postura da Meia Lua',emoji:'🌙',youtubeId:'TznRHywkPwU',sets:2,reps:'36s',rest:15,calories:5},{name:'Guerreiro III',emoji:'⚔️',youtubeId:'ySy_k5R3lHg',sets:2,reps:'35s',rest:15,calories:5},{name:'Guerreiro Reverso',emoji:'⚔️',youtubeId:'8LmWu5XnEWc',sets:2,reps:'52s',rest:15,calories:7},{name:'Guerreiro II',emoji:'⚔️',youtubeId:'YSjBJDkA6zg',sets:2,reps:'40s',rest:15,calories:5},{name:'Guerreiro Humilde',emoji:'⚔️',youtubeId:'a6ANkE4emF8',sets:2,reps:'51s',rest:15,calories:7},{name:'Triângulo com Torção',emoji:'🔄',youtubeId:'Tbz3FVAjVtI',sets:2,reps:'38s',rest:15,calories:5},{name:'Postura da Esfinge',emoji:'🧘♀️',youtubeId:'7a_WhOoegHE',sets:2,reps:'31s',rest:15,calories:4},{name:'Postura do Bebê Feliz',emoji:'👶',youtubeId:'z-BjiGQZe4s',sets:2,reps:'32s',rest:15,calories:4},{name:'Passeio do Cachorro',emoji:'🐕',youtubeId:'PCgS48SiR2k',sets:2,reps:'32s',rest:15,calories:4},{name:'Postura da Guirlanda',emoji:'🧘♀️',youtubeId:'_xJPi7yuelw',sets:2,reps:'35s',rest:15,calories:5},{name:'Cadeira com Torção',emoji:'🔄',youtubeId:'pQOK2-E-5sM',sets:2,reps:'35s',rest:15,calories:5},{name:'Postura da Deusa',emoji:'🧘♀️',youtubeId:'AhX3PujoRgo',sets:2,reps:'36s',rest:15,calories:5},{name:'Cachorro Olhando para Cima',emoji:'🐕',youtubeId:'OJ9j9D0lNBg',sets:2,reps:'35s',rest:15,calories:5}],massage:[{name:'Rosto de Peixe Sorridente',emoji:'😊',youtubeId:'mLYm4ItAuro',sets:1,reps:'1min',rest:10,calories:3},{name:'Firmador de Bochechas',emoji:'😌',youtubeId:'83Xu_F92j60',sets:1,reps:'1min',rest:10,calories:3},{name:'Linha do Maxilar',emoji:'💫',youtubeId:'R2cqpjvaB3E',sets:1,reps:'1min',rest:10,calories:2}]};return exercises[category]||[];}showToast(message,type='info',duration=3000){const existingToast=document.querySelector('.toast');if(existingToast){existingToast.remove();}const toast=document.createElement('div');toast.className=`toast ${type}`;toast.textContent=message;document.body.appendChild(toast);requestAnimationFrame(()=>{requestAnimationFrame(()=>{toast.classList.add('show');});});setTimeout(()=>{toast.classList.remove('show');setTimeout(()=>{toast.remove();},400);},duration);}getWellnessSessions(){return{'face-massage':{exercises:[{name:'Massagem na Testa',emoji:'💆♀️',sets:1,reps:'30s',rest:10},{name:'Contorno dos Olhos',emoji:'👁️',sets:1,reps:'30s',rest:10},{name:'Bochechas',emoji:'😊',sets:1,reps:'30s',rest:10},{name:'Mandíbula',emoji:'💫',sets:1,reps:'30s',rest:10}]},'body-massage':{exercises:[{name:'Pescoço e Ombros',emoji:'💆♀️',sets:1,reps:'1min',rest:20},{name:'Braços',emoji:'💪',sets:1,reps:'30s cada',rest:10},{name:'Pernas',emoji:'🦵',sets:1,reps:'1min cada',rest:20},{name:'Pés',emoji:'👣',sets:1,reps:'30s cada',rest:10}]},'posture':{exercises:[{name:'Alongamento Cervical',emoji:'🧍♀️',sets:2,reps:'20s',rest:10},{name:'Abertura de Peito',emoji:'💫',sets:2,reps:'30s',rest:10},{name:'Gato-Vaca',emoji:'🐱',sets:2,reps:'10',rest:10},{name:'Postura na Parede',emoji:'🧱',sets:1,reps:'1min',rest:0}]},'stretching':{exercises:[{name:'Alongamento de Pernas',emoji:'🦵',sets:2,reps:'30s cada',rest:10},{name:'Alongamento de Braços',emoji:'💪',sets:2,reps:'20s cada',rest:10},{name:'Torção Espinal',emoji:'🔄',sets:2,reps:'20s cada',rest:10},{name:'Alongamento Total',emoji:'🤸♀️',sets:1,reps:'30s',rest:0}]},'breathing':{exercises:[{name:'Respiração Profunda',emoji:'🌬️',sets:3,reps:'10',rest:20},{name:'Respiração Alternada',emoji:'👃',sets:2,reps:'5 cada',rest:20},{name:'Respiração 4-7-8',emoji:'💫',sets:3,reps:'4',rest:10}]},'meditation':{exercises:[{name:'Meditação Guiada',emoji:'🧘♀️',sets:1,reps:'5min',rest:0},{name:'Visualização',emoji:'✨',sets:1,reps:'3min',rest:0},{name:'Gratidão',emoji:'🙏',sets:1,reps:'2min',rest:0}]}};}}document.addEventListener('DOMContentLoaded',()=>{window.app=new FitnessApp();if('serviceWorker' in navigator){navigator.serviceWorker.register('/sw.js').then(reg=>{reg.update().catch(err=>);reg.addEventListener('updatefound',()=>{const newWorker=reg.installing;newWorker.addEventListener('statechange',()=>{if(newWorker.state==='activated' && !navigator.serviceWorker.controller){');}else if(newWorker.state==='activated'){window.app.updateUI();}});});if(window.swUpdateInterval){clearInterval(window.swUpdateInterval);}window.swUpdateInterval=setInterval(()=>{reg.update();},60000);document.addEventListener('visibilitychange',()=>{if(!document.hidden && reg){reg.update().catch(err=>);}});window.addEventListener('focus',()=>{if(reg){reg.update().catch(err=>);}});}).catch(err=> console.error('❌ Service Worker registration failed:',err));navigator.serviceWorker.addEventListener('message',(event)=>{if(event.data && event.data.type==='SW_UPDATED'){if(event.data.autoRefresh){document.body.style.opacity='0';setTimeout(()=> location.reload(),300);}else if(window.app){window.app.updateUI();window.app.showToast('🎉 App atualizado para a versão '+event.data.version);}}});navigator.serviceWorker.addEventListener('controllerchange',()=>{if(window.app && typeof window.app.showToast==='function'){window.app.showToast('✨ App atualizado!');}});}});const style=document.createElement('style');style.textContent=` @keyframes fadeOut{from{opacity:1;}to{opacity:0;}}`;document.head.appendChild(style);
\ No newline at end of file
+class FitnessApp{constructor(){this.currentView='home';this.currentCategory=null;this.currentWorkout=null;this.workoutTimer=null;this.workoutStartTime=null;this.workoutSeconds=0;this.currentExerciseIndex=0;this.currentSeries=0;this.navigationHistory=[];this.calendar30DayCache=null;this.calendar30DaySaveDebounce=null;const urlParams=new URLSearchParams(window.location.search);const isPWA=window.matchMedia('(display-mode:standalone)').matches || window.navigator.standalone===true || urlParams.get('source')==='pwa';const isLocalDev=window.location.hostname==='localhost' || window.location.hostname==='127.0.0.1';this.VIDEO_BASE_URL='videos/';this.AUDIO_BASE_URL='songs/';this.VIDEO_BASE_URL_FALLBACK='https:this.AUDIO_BASE_URL_FALLBACK='https:this.HF_DOWNLOAD_PARAM='';this.userProfile=this.loadUserProfile();this.userData=this.loadUserData();this.progress=this.loadProgress();this.weightData=this.loadWeightData();this.personalPlan=null;this.soundEnabled=localStorage.getItem('soundEnabled')!=='false';this.audioContext=new(window.AudioContext || window.webkitAudioContext)();this.sounds={backgroundYoga:this.createAudioWithFallback('background_yoga.mp3'),startYoga:this.createAudioWithFallback('start_yoga.mp3'),countdown:this.createAudioWithFallback('td_countdown.mp3'),motivational:this.createAudioWithFallback('td_di_2.ogg')};this.setupAudio();this.init();}createAudioWithFallback(filename){const audio=new Audio(this.AUDIO_BASE_URL+filename);audio.addEventListener('error',()=>{if(audio.src.includes(this.AUDIO_BASE_URL)){audio.src=this.AUDIO_BASE_URL_FALLBACK+filename;}},{once:true});return audio;}setupAudio(){this.sounds.backgroundYoga.loop=true;this.sounds.backgroundYoga.volume=0.3;this.audioLoaded=false;}ensureAudioLoaded(){if(this.audioLoaded)return;Object.values(this.sounds).forEach(sound=>{sound.load();});this.audioLoaded=true;}playCuteSound(type){if(!this.soundEnabled)return;try{const ctx=this.audioContext;const oscillator=ctx.createOscillator();const gainNode=ctx.createGain();oscillator.connect(gainNode);gainNode.connect(ctx.destination);switch(type){case 'tap':oscillator.frequency.setValueAtTime(800,ctx.currentTime);oscillator.frequency.exponentialRampToValueAtTime(400,ctx.currentTime+0.1);gainNode.gain.setValueAtTime(0.3,ctx.currentTime);gainNode.gain.exponentialRampToValueAtTime(0.01,ctx.currentTime+0.1);oscillator.type='sine';oscillator.start(ctx.currentTime);oscillator.stop(ctx.currentTime+0.1);break;case 'success':oscillator.frequency.setValueAtTime(523.25,ctx.currentTime);oscillator.frequency.setValueAtTime(659.25,ctx.currentTime+0.1);oscillator.frequency.setValueAtTime(783.99,ctx.currentTime+0.2);gainNode.gain.setValueAtTime(0.3,ctx.currentTime);gainNode.gain.exponentialRampToValueAtTime(0.01,ctx.currentTime+0.4);oscillator.type='sine';oscillator.start(ctx.currentTime);oscillator.stop(ctx.currentTime+0.4);break;case 'complete':const osc1=ctx.createOscillator();const osc2=ctx.createOscillator();const gain1=ctx.createGain();const gain2=ctx.createGain();osc1.connect(gain1);osc2.connect(gain2);gain1.connect(ctx.destination);gain2.connect(ctx.destination);osc1.frequency.setValueAtTime(523.25,ctx.currentTime);osc2.frequency.setValueAtTime(659.25,ctx.currentTime);gain1.gain.setValueAtTime(0.2,ctx.currentTime);gain2.gain.setValueAtTime(0.2,ctx.currentTime);gain1.gain.exponentialRampToValueAtTime(0.01,ctx.currentTime+0.5);gain2.gain.exponentialRampToValueAtTime(0.01,ctx.currentTime+0.5);osc1.start(ctx.currentTime);osc2.start(ctx.currentTime);osc1.stop(ctx.currentTime+0.5);osc2.stop(ctx.currentTime+0.5);break;case 'click':oscillator.frequency.setValueAtTime(600,ctx.currentTime);gainNode.gain.setValueAtTime(0.2,ctx.currentTime);gainNode.gain.exponentialRampToValueAtTime(0.01,ctx.currentTime+0.05);oscillator.type='sine';oscillator.start(ctx.currentTime);oscillator.stop(ctx.currentTime+0.05);break;}}catch(e){console.log('Audio error:',e);}}playSound(soundName){if(!this.soundEnabled)return;this.ensureAudioLoaded();const sound=this.sounds[soundName];if(sound){sound.currentTime=0;sound.play().catch(e=>{if(e.name !=='NotAllowedError'){console.log('Audio play failed:',e);}});}}stopSound(soundName){const sound=this.sounds[soundName];if(sound){sound.pause();sound.currentTime=0;}}toggleSound(){this.soundEnabled=!this.soundEnabled;localStorage.setItem('soundEnabled',this.soundEnabled);const icon=document.getElementById('soundIcon');icon.textContent=this.soundEnabled ? '🔊':'🔇';if(!this.soundEnabled){this.stopSound('backgroundYoga');}this.playCuteSound('click');}init(){if(!this.userProfile || !this.userProfile.name){this.showProfileSetup();return;}if(this.userProfile && this.weightData){let needsSave=false;if(this.userProfile.weight && !this.weightData.current){this.weightData.current=this.userProfile.weight;this.weightData.initial=this.userProfile.weight;needsSave=true;}else if(this.weightData.current && this.userProfile.weight !==this.weightData.current){this.userProfile.weight=this.weightData.current;this.saveUserProfile();}if(this.userProfile.goalWeight && !this.weightData.goal){this.weightData.goal=this.userProfile.goalWeight;needsSave=true;}else if(this.weightData.goal && this.userProfile.goalWeight !==this.weightData.goal){this.userProfile.goalWeight=this.weightData.goal;this.saveUserProfile();}if(needsSave){this.saveWeightData();}}const isFirstTime=!localStorage.getItem('appVisited');if(isFirstTime){this.showWelcome();}else{this.hideWelcome();}this.generatePersonalPlan();this.setupEventListeners();this.resetDailyCalories();this.updateAllStats();this.loadAchievements();this.setupPWA();}sanitizeHTML(str){if(!str)return '';const temp=document.createElement('div');temp.textContent=str;return temp.innerHTML;}sanitizeNumber(value,min,max,defaultValue=0){const num=parseFloat(value);if(isNaN(num)|| !Number.isFinite(num))return defaultValue;return Math.max(min,Math.min(max,num));}sanitizeString(str,maxLength=100){if(!str || typeof str !=='string')return '';return this.sanitizeHTML(str.trim().slice(0,maxLength));}loadUserProfile(){try{const data=localStorage.getItem('userProfile');if(!data)return null;const profile=JSON.parse(data);if(profile){profile.name=this.sanitizeString(profile.name,50);profile.weight=this.sanitizeNumber(profile.weight,30,300,65);profile.height=this.sanitizeNumber(profile.height,100,250,165);profile.age=this.sanitizeNumber(profile.age,10,120,25);profile.goalWeight=this.sanitizeNumber(profile.goalWeight,30,300,60);}return profile;}catch(e){console.error('Error loading profile:',e);return null;}}saveUserProfile(){try{const profileData=JSON.stringify(this.userProfile);if(profileData.length > 500000){console.error('Profile data too large');alert('Dados do perfil muito grandes. Por favor,reduza o tamanho da foto.');return false;}localStorage.setItem('userProfile',profileData);return true;}catch(e){if(e.name==='QuotaExceededError'){console.error('localStorage quota exceeded');alert('Espaço de armazenamento cheio. Por favor,limpe alguns dados.');}else{console.error('Error saving profile:',e);}return false;}}showProfileSetup(){const setupHTML=`
🎯 Vamos Criar Seu Perfil
Para criar um plano personalizado perfeito para você!