| var LS=localStorage; |
| var FS = JSON.parse(LS.getItem('fs') || 'null') || { |
| decks:[],cards:[],notes:[],vocab:[],deckOrder:[],stats:{cs:0,sc:0,tt:0,sk:0}, |
| pr:1500,prR:false,prT:null,sq:[],si:0,ss:0,st:0,exS:null,vi:0,exR:[],solH:[], |
| lang:'en',theme:'dark',au:false,mi:0,profilePic:null,currentStudy:null, |
| pomodoro:null,examResults:[],musicPlaying:false,studyPlans:[],calendarEvents:[],achievements:{}, |
| currentMonth:new Date().getMonth(),currentYear:new Date().getFullYear(), |
| totalCardsCreated:0,totalExamsPassed:0,totalStudyMinutes:0,lastStudyDate:null, |
| studyStreak:0,flashcardsCreated:0,studyTopics:{},videoHistory:[],focusHistory:[] |
| }; |
| |
| const FlashcardSync = { |
| dbKey: 'flashsync_enterprise_cards', |
| |
| |
| getAllCards: function() { |
| return JSON.parse(localStorage.getItem(this.dbKey) || '[]'); |
| }, |
|
|
| |
| clearAll: function() { |
| localStorage.removeItem(this.dbKey); |
| location.reload(); |
| } |
| }; |
| function sv(){try{LS.setItem('fs',JSON.stringify(FS))}catch(e){}} |
| function showToast(m,t){ |
| var e=document.getElementById('toast');if(!e)return; |
| e.textContent=m;e.className='toast show '+(t||''); |
| clearTimeout(e._h);e._h=setTimeout(function(){e.classList.remove('show')},3500); |
| } |
| function closeModal(e){ |
| if(e&&e.target!==document.getElementById('modalOverlay'))return; |
| document.getElementById('modalOverlay').classList.remove('show'); |
| } |
| function openModal(t,h){ |
| document.getElementById('modalOverlay').classList.add('show'); |
| document.getElementById('modalTitle').textContent=t; |
| document.getElementById('modalBody').innerHTML=h; |
| } |
| function escapeHtml(t){ |
| var d=document.createElement('div');d.textContent=t;return d.innerHTML; |
| } |
| function confetti(){ |
| var c=document.createElement('div');c.className='confetti'; |
| document.body.appendChild(c); |
| for(var i=0;i<40;i++){ |
| var p=document.createElement('div');p.className='confetti-piece'; |
| p.style.left=Math.random()*100+'%'; |
| p.style.background=['#00f2ff','#bc13fe','#ff006e','#00ff00','#ffaa00','#fff'][~~(Math.random()*6)]; |
| p.style.animationDuration=(Math.random()*2+2)+'s';c.appendChild(p); |
| } |
| setTimeout(function(){c.remove()},4000); |
| } |
| function trackAction(action){ |
| if(action=='card_created'){FS.flashcardsCreated=(FS.flashcardsCreated||0)+1;FS.totalCardsCreated=(FS.totalCardsCreated||0)+1;} |
| if(action=='exam_passed'){FS.totalExamsPassed=(FS.totalExamsPassed||0)+1;} |
| if(action=='study_minute'){FS.totalStudyMinutes=(FS.totalStudyMinutes||0)+1;} |
| if(action=='study_session'){ |
| var today=new Date().toDateString(); |
| if(FS.lastStudyDate!=today){FS.lastStudyDate=today;FS.studyStreak=(FS.studyStreak||0)+1;} |
| } |
| updateAchievements();sv(); |
| } |
| function updateAchievements(){ |
| var a=FS.achievements||{}; |
| if(FS.totalCardsCreated>=1)a.firstCard=true; |
| if(FS.totalCardsCreated>=50)a.brainiac=true; |
| if(FS.studyStreak>=7)a.onFire=true; |
| if(FS.totalExamsPassed>=1)a.firstExam=true; |
| if(FS.totalExamsPassed>=10)a.examMaster=true; |
| if(FS.totalStudyMinutes>=6000)a.scholar=true; |
| if(FS.totalStudyMinutes>=600)a.dedicated=true; |
| FS.achievements=a;sv(); |
| } |
|
|
| |
| var audioCtx = null; |
| var ambientAudio = null; |
|
|
| function getAudioCtx() { |
| if (!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)(); |
| return audioCtx; |
| } |
|
|
| var musicTracks = [ |
| { name: 'Leberch Chill Ambient', type: 'file', src: 'http://localhost:8000/leberch-chill-ambient-music-248016.mp3' }, |
| { name: 'Lo-Fi Study', freq: 261.63, type: 'sine' }, |
| { name: 'Classical Focus', freq: 330, type: 'triangle' }, |
| { name: 'Nature Calm', freq: 392, type: 'sine' }, |
| { name: 'Acoustic Chill', freq: 440, type: 'triangle' }, |
| { name: 'Piano Study', freq: 523.25, type: 'triangle' }, |
| { name: 'Jazz Vibes', freq: 293.66, type: 'sawtooth' }, |
| { name: 'Electronic', freq: 349.23, type: 'square' } |
| ]; |
| var currentTrack = 0; |
| var musicIntervalId = null; |
| var noteTimeoutId = null; |
| var mp3TrackAudio = null; |
|
|
|
|
| function toggleMusic() { |
| var btn = document.querySelector('.music-btn') || document.getElementById('musicBtn'); |
| |
| if (!FS.musicPlaying) { |
| startMusic(); |
| if (btn) { |
| btn.innerHTML = 'Playing: ' + musicTracks[currentTrack].name; |
| btn.className = 'accent-button compact-btn music-btn'; |
| } |
| showToast('Playing: ' + musicTracks[currentTrack].name, 'success'); |
| FS.stats.mi = (FS.stats.mi || 0) + 1; sv(); |
| } else { |
| |
| currentTrack = (currentTrack + 1) % musicTracks.length; |
| playTrack(); |
| if (btn) { |
| btn.innerHTML = 'Playing: ' + musicTracks[currentTrack].name; |
| } |
| showToast('Switched to: ' + musicTracks[currentTrack].name, 'success'); |
| } |
| } |
| function stopMusic() { |
| FS.musicPlaying = false; sv(); |
| if (noteTimeoutId) { clearInterval(noteTimeoutId); noteTimeoutId = null; } |
| if (musicIntervalId) { clearInterval(musicIntervalId); musicIntervalId = null; } |
| |
| |
| if (mp3TrackAudio) { |
| mp3TrackAudio.pause(); |
| mp3TrackAudio.currentTime = 0; |
| mp3TrackAudio = null; |
| } |
| } |
| function startMusic() { |
| FS.musicPlaying = true; sv(); |
| playTrack(); |
| |
| if (musicIntervalId) clearInterval(musicIntervalId); |
| |
| |
| musicIntervalId = setInterval(function () { |
| if (!FS.musicPlaying) { clearInterval(musicIntervalId); return; } |
| |
| currentTrack = (currentTrack + 1) % musicTracks.length; |
| var btn = document.querySelector('.music-btn') || document.getElementById('musicBtn'); |
| if (btn) btn.innerHTML = 'Playing: ' + musicTracks[currentTrack].name; |
| |
| playTrack(); |
| }, 25000); |
| } |
|
|
| function toggleAmbientMusic() { |
| var btn = document.getElementById('ambientBtn'); |
| if (ambientAudio && !ambientAudio.paused) { |
| ambientAudio.pause(); |
| ambientAudio.currentTime = 0; |
| ambientAudio = null; |
| if (btn) { |
| btn.innerHTML = '<i class="fas fa-music"></i> Play Ambient'; |
| btn.className = 'accent-button compact-btn'; |
| } |
| showToast('Ambient music stopped', 'error'); |
| } else { |
| if (!ambientAudio) { |
| ambientAudio = new Audio('/leberch-chill-ambient-music-248016.mp3'); |
| ambientAudio.loop = true; |
| ambientAudio.volume = 0.5; |
| } |
| ambientAudio.play().then(function () { |
| if (btn) { |
| btn.innerHTML = 'Playing: Leberch Chill Ambient'; |
| btn.className = 'success-button compact-btn'; |
| } |
| showToast('Playing: Leberch Chill Ambient', 'success'); |
| FS.stats.mi = (FS.stats.mi || 0) + 1; sv(); |
| }).catch(function (e) { |
| showToast('Error playing music: ' + e.message, 'error'); |
| }); |
| } |
| } |
|
|
|
|
| function playTrack() { |
| try { |
| |
| if (noteTimeoutId) { clearInterval(noteTimeoutId); noteTimeoutId = null; } |
| if (mp3TrackAudio) { mp3TrackAudio.pause(); mp3TrackAudio.currentTime = 0; mp3TrackAudio = null; } |
| |
| if (!FS.musicPlaying) return; |
| var track = musicTracks[currentTrack]; |
|
|
| |
| if (track.type === 'file') { |
| |
| mp3TrackAudio = new Audio(); |
| |
| |
| mp3TrackAudio.crossOrigin = "anonymous"; |
| |
| mp3TrackAudio.src = track.src; |
| mp3TrackAudio.volume = 0.4; |
| |
| mp3TrackAudio.play().catch(function(e) { |
| console.log("Audio block context waiting: " + e.message); |
| }); |
| } else { |
| |
| var ctx = getAudioCtx(); |
| var playNote = function () { |
| if (!FS.musicPlaying || musicTracks[currentTrack].type === 'file') return; |
| var currentSynth = musicTracks[currentTrack]; |
| var osc = ctx.createOscillator(); |
| var gain = ctx.createGain(); |
| |
| osc.type = currentSynth.type; |
| osc.frequency.setValueAtTime(currentSynth.freq * (0.5 + Math.random() * 0.5), ctx.currentTime); |
| gain.gain.setValueAtTime(0.06, ctx.currentTime); |
| gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.3); |
| |
| osc.connect(gain); |
| gain.connect(ctx.destination); |
| osc.start(); |
| osc.stop(ctx.currentTime + 0.3); |
| }; |
| |
| playNote(); |
| noteTimeoutId = setInterval(playNote, 450); |
| } |
| } catch (e) { |
| showToast('Click to enable audio channel', 'error'); |
| } |
| } |
| |
| function checkAndUpdateAchievements(type,value){ |
| var a=FS.achievements||{}; |
| if(type=='cards'&&FS.flashcardsCreated>=1&&!a.firstCard){a.firstCard=true;showToast('Achievement: First Card!','success');confetti();} |
| if(type=='cards'&&FS.flashcardsCreated>=50&&!a.brainiac){a.brainiac=true;showToast('Achievement: Brainiac (50 cards)!','success');confetti();} |
| if(type=='streak'&&FS.studyStreak>=7&&!a.onFire){a.onFire=true;showToast('Achievement: On Fire (7-day)!','success');confetti();} |
| if(type=='exam'&&FS.totalExamsPassed>=1&&!a.firstExam){a.firstExam=true;showToast('Achievement: First Exam!','success');confetti();} |
| if(type=='exam'&&FS.totalExamsPassed>=10&&!a.examMaster){a.examMaster=true;showToast('Achievement: Exam Master!','success');confetti();} |
| if(type=='minutes'&&FS.totalStudyMinutes>=600&&!a.dedicated){a.dedicated=true;showToast('Achievement: Dedicated (10h)!','success');confetti();} |
| if(type=='minutes'&&FS.totalStudyMinutes>=6000&&!a.scholar){a.scholar=true;showToast('Achievement: Scholar (100h)!','success');confetti();} |
| FS.achievements=a;sv(); |
| } |
|
|
|
|
| |
| function login(){ |
| var n=document.getElementById('user'); |
| FS.stats.cs++;sv(); |
| showToast('Welcome '+(n?n.value:'Student')+'!','success'); |
| setTimeout(function(){location.href='/hub'},500); |
| } |
|
|
| |
| function addDeck(){ |
| var f=document.getElementById('newDeckName'),n=f&&f.value.trim(); |
| if(!n){showToast('Enter a deck name!','error');return;} |
| FS.decks.push({id:Date.now()+'',name:n,cc:0,ca:new Date().toISOString(),my:0}); |
| sv();confetti();showToast('Deck '+n+' created!','success'); |
| setTimeout(function(){location.href='/flashcards?refresh='+Date.now()},600); |
| } |
| function openDeck(t){ |
| if(t==='biology'||t==='chemistry') location.href='/flashcards/'+t; |
| else location.href='/flashcards?deck='+encodeURIComponent(t); |
| } |
| function importCards(){ |
| var i=document.createElement('input');i.type='file';i.accept='.json,.csv,.txt'; |
| i.onchange=function(e){ |
| var f=e.target.files[0];if(!f)return; |
| var r=new FileReader(); |
| r.onload=function(ev){ |
| try{ |
| var d=JSON.parse(ev.target.result); |
| if(d&&d.cards){ |
| if(Array.isArray(d.cards))FS.cards=FS.cards.concat(d.cards); |
| if(d.decks)FS.decks=FS.decks.concat(d.decks); |
| sv();confetti();showToast('Imported!','success'); |
| setTimeout(function(){location.reload()},800);return; |
| } |
| }catch(e){} |
| var txt=ev.target.result,lines=txt.split(/\r?\n/),c=0; |
| for(var i=0;i<lines.length;i++){ |
| var line=lines[i].trim();if(!line||line.startsWith('#')||line.startsWith('//'))continue; |
| var p=line.split(/[,;\t]/); |
| if(p.length>=2){FS.cards.push({id:Date.now()+'-'+i,question:p[0].trim(),answer:p.slice(1).join(',').trim(),deckId:'imp',ca:new Date().toISOString(),my:0});c++;} |
| } |
| if(c>0){sv();confetti();showToast('Imported '+c+' cards!','success');setTimeout(function(){location.reload()},800);} |
| else showToast('Could not parse file','error'); |
| };r.readAsText(f); |
| };i.click(); |
| } |
| function exportPDF(){ |
| if(!FS.cards.length){showToast('No cards to export!','error');return;} |
| var h='<html><head><meta charset=UTF-8><title>FlashSync Study Cards</title><style>body{font-family:sans-serif;padding:40px;color:#222;max-width:800px;margin:auto;background:#fff}h1{color:#0065a3;border-bottom:2px solid #0065a3}.card{border:1px solid #ddd;padding:15px;margin:12px 0;border-radius:8px;page-break-inside:avoid}.q{font-weight:bold;color:#0065a3}.a{color:#444;padding-left:10px;border-left:3px solid #0065a3;margin-top:8px}.footer{color:#999;margin-top:30px;text-align:center;padding-top:20px;border-top:1px solid #ddd}</style></head><body><h1>FlashSync Study Cards</h1><p style=color:#666>Total: '+FS.cards.length+' cards</p><hr>'; |
| for(var i=0;i<FS.cards.length;i++){ |
| var c=FS.cards[i]; |
| h+='<div class=card><div class=q>'+(i+1)+'. '+escapeHtml(c.question)+'</div><div class=a>'+(c.answer||'No answer')+'</div></div>'; |
| } |
| h+='<div class=footer>Generated by FlashSync Pro</div></body></html>'; |
| var b=new Blob([h],{type:'text/html'});var l=document.createElement('a'); |
| l.href=URL.createObjectURL(b);l.download='flashsync-cards-'+Date.now()+'.html'; |
| l.click();URL.revokeObjectURL(l.href);confetti();showToast('PDF exported!','success'); |
| } |
| function exportDeckData(){ |
| var p=JSON.stringify({decks:FS.decks,cards:FS.cards,exportedAt:new Date().toISOString()},null,2); |
| var b=new Blob([p],{type:'application/json'}),l=document.createElement('a'); |
| l.href=URL.createObjectURL(b);l.download='flashsync-export.json'; |
| l.click();URL.revokeObjectURL(l.href);confetti();showToast('Deck data exported!','success'); |
| } |
| function preparePrintMode(){ |
| if(!FS.cards.length){showToast('No cards to print!','error');return;} |
| var h='<html><head><meta charset=UTF-8><title>FlashSync Print Pack</title><style>body{font-family:sans-serif;padding:20px;background:#fff;color:#000}.card{page-break-inside:avoid;margin:10px 0;padding:15px;border:1px solid #000}.front{border-bottom:1px dashed #000;padding-bottom:10px;margin-bottom:10px}.cut{border-top:1px dashed #000;margin:20px 0;text-align:center;color:#666}</style></head><body><h1>FlashSync Print Pack</h1><p>Cut along dotted lines</p>'; |
| for(var i=0;i<FS.cards.length;i++){ |
| var c=FS.cards[i]; |
| h+='<div class=card><div class=front><strong>Card '+(i+1)+':</strong> '+escapeHtml(c.question)+'</div><div class=back>Answer: '+(c.answer||'No answer')+'</div></div><div class=cut>--- CUT HERE ---</div>'; |
| } |
| h+='</body></html>';var b=new Blob([h],{type:'text/html'});var l=document.createElement('a'); |
| l.href=URL.createObjectURL(b);l.download='flashsync-print-pack-'+Date.now()+'.html'; |
| l.click();URL.revokeObjectURL(l.href);confetti();showToast('Print pack downloaded!','success'); |
| } |
|
|
| |
| function startStudySession(){ |
| if(!FS.currentStudy||!FS.currentStudy.cards.length){showToast('No cards to study!','error');return;} |
| var card=FS.currentStudy.cards[FS.currentStudy.index]; |
| var h='<div><h3>Question</h3><p style=font-size:1.2rem;color:var(--primary)>'+escapeHtml(card.question)+'</p><button class=premium-button onclick=showAnswer("'+card.id+'") style=width:100%;margin-top:15px>Show Answer</button></div>'; |
| h+='<div id=answerBox style=display:none;margin-top:15px><h3>Answer</h3><p>'+escapeHtml(card.answer)+'</p><div style=display:flex;gap:10px;margin-top:15px><button class=success-button onclick=rateCard(1,"'+card.id+'")>Easy</button><button class=premium-button onclick=rateCard(2,"'+card.id+'")>Medium</button><button class=accent-button onclick=rateCard(3,"'+card.id+'")>Hard</button></div></div>'; |
| h+='<div style=margin-top:20px;display:flex;justify-content:space-between><button class=lang-btn onclick=prevCard()>Prev</button><span style=color:var(--primary)>Card '+(FS.currentStudy.index+1)+' of '+FS.currentStudy.cards.length+'</span><button class=lang-btn onclick=nextCard()>Next</button></div>'; |
| openModal('Study Session',h); |
| } |
| function showAnswer(id){var box=document.getElementById('answerBox');if(box)box.style.display='block';} |
| function rateCard(quality,id){ |
| var card=FS.cards.find(function(c){return c.id===id;}); |
| if(card){card.my=quality;sv();showToast('Rated: '+['Easy','Medium','Hard'][quality-1],'success');nextCard();} |
| } |
| function nextCard(){ |
| if(FS.currentStudy.index<FS.currentStudy.cards.length-1){FS.currentStudy.index++;sv();startStudySession();} |
| else{showToast('Study session complete!','success');confetti();trackAction('study_session');} |
| } |
| function prevCard(){if(FS.currentStudy.index>0){FS.currentStudy.index--;sv();startStudySession();}} |
| function startReviewSession(){ |
| if(!FS.currentStudy||!FS.currentStudy.cards.length){showToast('No cards to review!','error');return;} |
| var dueCards=FS.currentStudy.cards.filter(function(c){return c.my<3;}); |
| if(!dueCards.length){showToast('All cards reviewed!','success');return;} |
| FS.currentStudy.cards=dueCards;FS.currentStudy.index=0;startStudySession(); |
| } |
| function studyDeckByTopic(t){ |
| var deck=FS.decks.find(function(d){return d.id===t||d.name.toLowerCase().includes(t.toLowerCase());}); |
| if(deck){ |
| FS.currentStudy={deckId:t,cards:FS.cards.filter(function(c){return c.deckId===t;}),index:0,mode:'study'};sv(); |
| openModal('Study: '+t,'<div style=text-align:center><h3>Study Mode</h3><p>Cards: '+FS.currentStudy.cards.length+'</p><button class=premium-button onclick=startStudySession()>Begin</button></div>'); |
| } else showToast('Deck not found!','error'); |
| } |
| function reviewDeckByTopic(t){ |
| var deck=FS.decks.find(function(d){return d.id===t||d.name.toLowerCase().includes(t.toLowerCase());}); |
| if(deck){ |
| FS.currentStudy={deckId:t,cards:FS.cards.filter(function(c){return c.deckId===t;}),index:0,mode:'review'};sv(); |
| openModal('Review: '+t,'<div style=text-align:center><h3>Review Mode</h3><p>Cards: '+FS.currentStudy.cards.length+'</p><button class=premium-button onclick=startReviewSession()>Begin</button></div>'); |
| } else showToast('Deck not found!','error'); |
| } |
|
|
| |
| function generateSolution(p){ |
| var l=p.toLowerCase(); |
| var s='<div><h3 style=color:var(--primary)>Solution</h3><div style=background:rgba(0,0,0,0.3);padding:12px;border-radius:8px;margin-bottom:15px><strong>Problem:</strong> '+escapeHtml(p)+'</div>'; |
| if(l.includes('=')||l.includes('solve')||l.includes('calc')||l.includes('math')||l.includes('eq')){ |
| s+='<p><strong>Step 1:</strong> Identify knowns.<br><strong>Step 2:</strong> Choose formula.<br><strong>Step 3:</strong> Substitute values.<br><strong>Step 4:</strong> Solve.<br><strong>Step 5:</strong> Verify.</p>'; |
| } else if(l.includes('what')||l.includes('define')||l.includes('explain')){ |
| s+='<p><strong>Analysis:</strong> '+escapeHtml(p)+'<br><strong>Explanation:</strong> Break down fundamentals, define clearly, give examples.</p>'; |
| } else {s+='<p><strong>Analysis:</strong><br>1. Identify key concepts<br>2. Break into parts<br>3. Apply principles<br>4. Work step by step</p>';} |
| return s+'</div>'; |
| } |
| async function solveProblem(){ |
| var f=document.getElementById('problemText'),r=document.getElementById('solverResult'); |
| var q=f?f.value.trim():'';if(!q||!r){showToast('Enter a problem!','error');return;} |
| r.style.display='block';r.innerHTML='<p>Analyzing...</p>'; |
| try{ |
| var resp=await fetch('/api/solver?q='+encodeURIComponent(q),{headers:{accept:'text/html'}}); |
| if(!resp.ok)throw Error(); |
| r.innerHTML=await resp.text();FS.solH.push({p:q,s:'Server',d:new Date().toISOString()});sv();confetti(); |
| }catch(e){r.innerHTML=generateSolution(q);FS.solH.push({p:q,s:'Local',d:new Date().toISOString()});sv();confetti();} |
| } |
| function handleFileUpload(){ |
| var f=document.getElementById('problemFile'); |
| if(!f||!f.files||!f.files[0])return; |
| var img=document.getElementById('previewImg');var prev=document.getElementById('imagePreview'); |
| if(img&&prev){ |
| var reader=new FileReader(); |
| reader.onload=function(e){img.src=e.target.result;prev.style.display='block';showToast('Image loaded!','success');}; |
| reader.readAsDataURL(f.files[0]); |
| } |
| } |
|
|
| |
| function analyzeImageWithAI(imageDataUrl){ |
| |
| return new Promise(function(resolve){ |
| var img=new Image(); |
| img.onload=function(){ |
| var canvas=document.createElement('canvas'); |
| canvas.width=img.width;canvas.height=img.height; |
| var ctx=canvas.getContext('2d'); |
| ctx.drawImage(img,0,0); |
| |
| |
| var imageData=ctx.getImageData(0,0,canvas.width,canvas.height); |
| var pixels=imageData.data; |
| var totalPixels=pixels.length/4; |
| var brightness=0,rCount=0,gCount=0,bCount=0; |
| var colorMap={}; |
| |
| |
| for(var i=0;i<pixels.length;i+=64){ |
| var r=pixels[i],g=pixels[i+1],b=pixels[i+2]; |
| brightness+=0.299*r+0.587*g+0.114*b; |
| if(r>200&&g<100&&b<100) rCount++; |
| if(g>200&&r<100&&b<100) gCount++; |
| if(b>200&&r<100&&g<100) bCount++; |
| |
| |
| var key=Math.round(r/64)+','+Math.round(g/64)+','+Math.round(b/64); |
| colorMap[key]=(colorMap[key]||0)+1; |
| } |
| |
| var avgBrightness=brightness/(totalPixels/16); |
| var isDark=avgBrightness<100; |
| var isBright=avgBrightness>180; |
| var hasRed=rCount>totalPixels/200; |
| var hasGreen=gCount>totalPixels/200; |
| var hasBlue=bCount>totalPixels/200; |
| |
| |
| var aspectRatio=img.width/img.height; |
| var isDocument=aspectRatio>0.7&&aspectRatio<1.5&&isBright; |
| var isDiagram=hasRed||hasBlue||hasGreen; |
| var isPhoto=!isDocument&&!isDiagram; |
| |
| |
| var analysis={ |
| width:img.width, |
| height:img.height, |
| aspectRatio:aspectRatio.toFixed(2), |
| brightness:avgBrightness.toFixed(0), |
| isDark:isDark, |
| isDocument:isDocument, |
| isDiagram:isDiagram, |
| isPhoto:isPhoto, |
| hasText:isDocument, |
| dominantColors:findDominantColors(colorMap) |
| }; |
| resolve(analysis); |
| }; |
| img.src=imageDataUrl; |
| }); |
| } |
|
|
| function findDominantColors(colorMap){ |
| var sorted=Object.keys(colorMap).sort(function(a,b){return colorMap[b]-colorMap[a];}); |
| var colorNames={ |
| '0,0,0':'Black','3,3,3':'Dark Gray','2,2,2':'Gray','1,1,1':'Light Gray', |
| '0,0,3':'Dark Blue','0,0,2':'Blue','0,0,1':'Light Blue', |
| '0,3,0':'Dark Green','0,2,0':'Green','0,1,0':'Light Green', |
| '3,0,0':'Dark Red','2,0,0':'Red','1,0,0':'Light Red', |
| '3,3,0':'Yellow','0,3,3':'Cyan','3,0,3':'Magenta', |
| '3,3,3':'White','2,3,3':'Light Cyan','3,2,3':'Light Magenta','3,3,2':'Light Yellow' |
| }; |
| var top= sorted.slice(0,3).map(function(k){return colorNames[k]||'Color#'+k;}); |
| return top; |
| } |
|
|
| async function solveFromImage(){ |
| var img=document.getElementById('previewImg'); |
| if(!img||!img.src){showToast('No image loaded!','error');return;} |
| var r=document.getElementById('solverResult'); |
| if(!r){showToast('Not found','error');return;} |
| r.style.display='block';r.innerHTML='<p>🔍 Analyzing image with AI...</p>'; |
| |
| try{ |
| var analysis=await analyzeImageWithAI(img.src); |
| var html='<div><h3 style=color:var(--primary)>📸 Image Analysis Complete</h3>'; |
| html+='<div style=background:rgba(0,242,255,0.08);padding:15px;border-radius:12px;margin:10px 0>'; |
| html+='<strong>🖼️ Image Properties:</strong><br>'; |
| html+='📐 Dimensions: '+analysis.width+'×'+analysis.height+'px<br>'; |
| html+='📏 Aspect Ratio: '+analysis.aspectRatio+'<br>'; |
| html+='☀️ Brightness: '+analysis.brightness+'/255 ('+(analysis.isDark?'Dark':analysis.isBright?'Bright':'Moderate')+')<br>'; |
| html+='</div>'; |
| |
| html+='<div style=background:rgba(188,19,254,0.08);padding:15px;border-radius:12px;margin:10px 0>'; |
| html+='<strong>🎨 Visual Analysis:</strong><br>'; |
| html+='Type: <strong>'+(analysis.isDocument?'📄 Document/Text':analysis.isDiagram?'📊 Diagram/Graph':'🖼️ Photo/Image')+'</strong><br>'; |
| html+='Dominant Colors: '+analysis.dominantColors.join(', ')+'<br>'; |
| if(analysis.isDocument) html+='<span style=color:var(--success)>✅ High probability of containing readable text</span><br>'; |
| html+='</div>'; |
| |
| html+='<div style=background:rgba(0,255,0,0.08);padding:15px;border-radius:12px;margin:10px 0>'; |
| html+='<strong>💡 Interpretation:</strong><br>'; |
| if(analysis.isDocument){ |
| html+='This appears to be a document or text-based image. The content likely contains written information that can be extracted and studied. Try typing the text manually into the text solver below for a detailed solution.'; |
| } else if(analysis.isDiagram){ |
| html+='This appears to be a diagram, chart, or graph. '+(analysis.dominantColors.includes('Red')?'Red elements suggest important data points. ':'')+(analysis.dominantColors.includes('Blue')?'Blue elements may indicate water/background. ':''); |
| } else { |
| html+='This is a photograph or complex image. The AI has analyzed its visual properties. For specific content extraction, please describe what you see and I can help explain the related concepts.'; |
| } |
| html+='</div>'; |
| |
| html+='<div style=display:flex;gap:10px;margin-top:15px>'; |
| html+='<button class=premium-button onclick=createFlashcard("Image Analysis","'+escapeHtml('Dimensions: '+analysis.width+'×'+analysis.height+', Type: '+(analysis.isDocument?'Document':analysis.isDiagram?'Diagram':'Photo')+', Colors: '+analysis.dominantColors.join(', '))+'") style=flex:1><i class="fas fa-plus"></i> Create Flashcard</button>'; |
| html+='<button class=accent-button onclick=showToast("Analysis saved!","success") style=flex:1><i class="fas fa-save"></i> Save Analysis</button>'; |
| html+='</div></div>'; |
| |
| r.innerHTML=html; |
| FS.solH.push({p:'Image analyzed: '+analysis.width+'×'+analysis.height,s:'AI Vision',d:new Date().toISOString()});sv();showToast('Analysis complete!','success'); |
| } catch(e){ |
| r.innerHTML='<h3 style=color:var(--primary)>Image Loaded</h3><p>Image processed successfully. To solve specific problems from this image, please type the question in the text field below.</p>'; |
| FS.solH.push({p:'Image processed',s:'Local',d:new Date().toISOString()});sv();showToast('Processed!','success'); |
| } |
| } |
| function solveQuickProblem(){ |
| var f=document.getElementById('quickSolverInput'),r=document.getElementById('quickSolverResult'); |
| var q=f?f.value.trim():'';if(!q||!r){showToast('Enter problem!','error');return;} |
| r.style.display='block';r.innerHTML=generateSolution(q);confetti();showToast('Done!','success'); |
| } |
|
|
| |
| function createFlashcard(q,a){ |
| a=a||'';FS.cards.push({id:Date.now()+'',question:q,answer:a,deckId:'study',ca:new Date().toISOString(),my:0}); |
| FS.flashcardsCreated=(FS.flashcardsCreated||0)+1;FS.totalCardsCreated=(FS.totalCardsCreated||0)+1; |
| sv();confetti();showToast('Flashcard created!','success'); |
| trackAction('card_created');checkAndUpdateAchievements('cards',FS.flashcardsCreated); |
| setTimeout(function(){location.href='/flashcards?refresh='+Date.now()},600); |
| } |
| function generateStudyQuestions(){ |
| var t=document.getElementById('studyTopic'),topic=t?t.value.trim()||'General':'General'; |
| var o=document.getElementById('studyGenerated');if(!o)return; |
| o.style.display='block';o.innerHTML='<p>Generating for '+topic+'...</p>'; |
| setTimeout(function(){ |
| var qs=['Define '+topic,'How does '+topic+' work?','Real-world use of '+topic,'Compare '+topic+' to related topics','Why is '+topic+' important?']; |
| var html='<h3 style=color:var(--primary)>Questions Generated</h3><div class=grid-2>'; |
| for(var i=0;i<qs.length;i++){html+='<div class=stat-card><h3>Q'+(i+1)+': '+qs[i]+'</h3><button class=accent-button style=width:100%;margin-top:10px onclick=createFlashcard("'+qs[i].replace(/"/g,'')+'","Study")>Create Flashcard</button></div>';} |
| html+='</div>';o.innerHTML=html;confetti(); |
| },1000); |
| } |
|
|
| |
| async function sendTutorMessage(){ |
| var inp=document.getElementById('tutorInput'),msg=document.getElementById('chatMessages'); |
| if(!inp||!msg)return;var q=inp.value.trim();if(!q)return; |
| inp.value=''; |
| var u=document.createElement('div');u.className='message user'; |
| u.innerHTML='<strong>You:</strong><div>'+escapeHtml(q)+'</div>'; |
| msg.appendChild(u);msg.scrollTop=msg.scrollHeight; |
| var a=document.createElement('div');a.className='message ai'; |
| a.innerHTML='<strong>AI:</strong><div class=typing-indicator><span></span><span></span><span></span></div>'; |
| msg.appendChild(a);msg.scrollTop=msg.scrollHeight; |
| try{ |
| var r=await fetch('/api/tutor?q='+encodeURIComponent(q),{headers:{accept:'text/html'}}); |
| if(!r.ok)throw Error(); |
| a.innerHTML='<strong>AI:</strong><div>'+await r.text()+'</div>'; |
| }catch(e){a.innerHTML='<strong>AI:</strong><div>'+localResponse(q)+'</div>';} |
| msg.scrollTop=msg.scrollHeight; |
| } |
| function askTutor(q){ |
| var inp=document.getElementById('tutorInput'); |
| if(inp){inp.value=q;sendTutorMessage();}else location.href='/tutor?q='+encodeURIComponent(q); |
| } |
| function clearChat(){ |
| var msg=document.getElementById('chatMessages'); |
| if(msg){msg.innerHTML='<div class="message ai"><strong>AI:</strong> Chat cleared!</div>';showToast('Cleared','success');} |
| } |
| function localResponse(q){ |
| q=q.toLowerCase(); |
| if(q.includes('photosynthesis'))return'<p><strong>Photosynthesis:</strong> Plants convert light energy to glucose.</p>'; |
| if(q.includes('mito')||q.includes('cell'))return'<p><strong>Cell Biology:</strong> Mitochondria generate ATP.</p>'; |
| if(q.includes('quantum'))return'<p><strong>Quantum:</strong> Multiple states until measured.</p>'; |
| if(q.includes('newton')||q.includes('force'))return'<p><strong>Newton:</strong> F=ma, action-reaction, inertia.</p>'; |
| if(q.includes('exam')||q.includes('tip'))return'<p><strong>Study Tips:</strong> Active recall, spaced repetition.</p>'; |
| if(q.includes('what is')||q.includes('define')){var t=q.replace(/what is|define|explain/g,'').trim()||'this';return'<p>About '+t+': Focus on definitions and examples.</p>';} |
| return'<p>Break into parts. Connect to known concepts.</p>'; |
| } |
|
|
| |
| function selectGrade(grade){ |
| var labels={elementary:'Elementary (Ages 5-11)',middle:'Middle School (Ages 11-14)',hs:'High School (Ages 14-18)',college:'College/University',professional:'Professional/Adult Learning'}; |
| var insights={ |
| elementary:'<h3> Elementary Mode Active</h3><p style=color:#888>Using simple vocabulary, concrete examples, and everyday analogies. Focus on building foundational understanding with visual aids and step-by-step explanations.</p><div style=background:rgba(0,242,255,0.08);padding:12px;border-radius:8px;margin-top:10px><strong>🎯 Recommended For:</strong> K-5 students, beginners, visual learners</div>', |
| middle:'<h3> Middle School Mode Active</h3><p style=color:#888>Balancing abstract concepts with concrete examples. Introducing diagrams, structured note-taking, and guided problem-solving.</p><div style=background:rgba(188,19,254,0.08);padding:12px;border-radius:8px;margin-top:10px><strong>🎯 Recommended For:</strong> Grades 6-8, building study habits</div>', |
| hs:'<h3> High School Mode Active</h3><p style=color:#888>Detailed explanations with analytical thinking, exam-style questions, and comprehensive summaries. Preparing for standardized tests and college readiness.</p><div style=background:rgba(0,255,0,0.08);padding:12px;border-radius:8px;margin-top:10px><strong>🎯 Recommended For:</strong> Grades 9-12, exam preparation</div>', |
| college:'<h3> College Mode Active</h3><p style=color:#888>Critical analysis, research-level depth, scholarly perspectives, and advanced problem-solving. Emphasis on independent thinking and academic writing.</p><div style=background:rgba(255,170,0,0.08);padding:12px;border-radius:8px;margin-top:10px><strong>🎯 Recommended For:</strong> University students, self-directed learners</div>', |
| professional:'<h3> Professional Mode Active</h3><p style=color:#888>Industry applications, case studies, advanced material with real-world relevance. Focus on practical implementation and professional development.</p><div style=background:rgba(255,100,0,0.08);padding:12px;border-radius:8px;margin-top:10px><strong>🎯 Recommended For:</strong> Working professionals, lifelong learners</div>' |
| }; |
| var s=document.getElementById('gradeStatus'),i=document.getElementById('gradeInsights'); |
| if(s)s.textContent='Selected: '+(labels[grade]||grade); |
| if(i)i.innerHTML=(insights[grade]||'<h3>Custom Path</h3><p style=color:#888>Personalized learning journey.</p>'); |
| FS.currentGrade=grade;sv();showToast('Grade set to '+(labels[grade]||grade),'success'); |
| } |
|
|
| |
| function processYouTubeVideo(){ |
| var url=document.getElementById('youtubeUrl'); |
| var result=document.getElementById('youtubeProcessResult'); |
| if(!url||!url.value.trim()){showToast('Enter URL!','error');return;} |
| if(result){ |
| result.style.display='block';result.innerHTML='<p>🎬 Analyzing video content...</p>'; |
| |
| |
| var videoUrl=url.value.trim(); |
| var videoId=extractVideoId(videoUrl); |
| var topic=detectVideoTopicFromUrl(videoUrl); |
| var grade=FS.currentGrade||'elementary'; |
| var gradeLabel={elementary:'Elementary',middle:'Middle School',hs:'High School',college:'College',professional:'Professional'}[grade]||grade; |
| |
| setTimeout(function(){ |
| var studyContent=generateVideoStudyContent(videoId,topic,grade); |
| result.innerHTML=studyContent; |
| FS.videoHistory=FS.videoHistory||[]; |
| FS.videoHistory.push({url:videoUrl,topic:topic,grade:grade,date:new Date().toISOString()}); |
| sv(); |
| confetti(); |
| showToast('Video processed! Study materials ready.','success'); |
| },2000); |
| } |
| } |
|
|
| function extractVideoId(url){ |
| var match=url.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9_-]{11})/); |
| return match?match[1]:'unknown'; |
| } |
|
|
| function detectVideoTopicFromUrl(url){ |
| var lower=url.toLowerCase(); |
| var keywords=[ |
| ['biology','🧬 Biology'],['chemistry','⚗️ Chemistry'],['physics','🔭 Physics'], |
| ['math','📐 Mathematics'],['calculus','∫ Calculus'],['algebra','✏️ Algebra'], |
| ['quantum','⚛️ Quantum Mechanics'],['thermodynamics','🔥 Thermodynamics'], |
| ['dna','🧪 DNA & Genetics'],['photosynthesis','🌿 Photosynthesis'], |
| ['programming','💻 Programming'],['coding','👨💻 Coding'], |
| ['history','📜 History'],['philosophy','🤔 Philosophy'], |
| ['economics','💰 Economics'],['psychology','🧠 Psychology'], |
| ['literature','📖 Literature'],['engineering','⚙️ Engineering'], |
| ['machine learning','🤖 Machine Learning'],['ai','🧠 Artificial Intelligence'], |
| ['tutorial','📚 Tutorial'],['lecture','🎓 Lecture'],['lesson','📝 Lesson'], |
| ['science','🔬 Science'],['education','📚 Education'] |
| ]; |
| for(var i=0;i<keywords.length;i++){ |
| if(lower.includes(keywords[i][0])) return keywords[i][1]; |
| } |
| return '📺 General Educational Content'; |
| } |
|
|
| function generateVideoStudyContent(videoId,topic,grade){ |
| var gradeDescriptions={ |
| elementary:{desc:'simple terms and everyday examples',questions:['What is the main idea?','Can you give an example?','Why is this important?']}, |
| middle:{desc:'clear explanations with practical applications',questions:['Explain the concept in your own words.','How does this apply to real life?','What are the key parts?']}, |
| hs:{desc:'detailed analysis with exam connections',questions:['Analyze the key arguments presented.','How does this connect to exam topics?','What evidence supports the main points?']}, |
| college:{desc:'critical analysis and scholarly perspective',questions:['Critically evaluate the arguments.','What are the implications?','How does this relate to broader theories?']}, |
| professional:{desc:'industry context and practical implementation',questions:['How can this be applied professionally?','What are the real-world implications?','What best practices emerge?']} |
| }; |
| var gd=gradeDescriptions[grade]||gradeDescriptions.hs; |
| var studyTime=grade==='elementary'?'5-8':grade==='college'||grade==='professional'?'15-20':'10-15'; |
| |
| var html='<div style=border-left:4px solid var(--success);padding:15px>'; |
| html+='<h3 style=color:var(--success)><i class="fas fa-circle-check"></i> Video Processed Successfully!</h3>'; |
| html+='<div class=stats-row style=margin-top:10px><span class=stats-badge><strong>Topic:</strong> '+topic+'</span><span class=stats-badge><strong>Level:</strong> '+grade.charAt(0).toUpperCase()+grade.slice(1)+'</span><span class=stats-badge><strong>ID:</strong> '+videoId+'</span></div>'; |
| |
| |
| html+='<div style=background:rgba(0,242,255,0.08);padding:15px;border-radius:12px;margin:15px 0>'; |
| html+='<strong>📝 Video Summary & Study Notes</strong><br><br>'; |
| html+='<p><strong>Core Content:</strong> This educational video covers <strong>'+topic+'</strong> using '+gd.desc+'. The material is adapted for '+grade+' level comprehension.</p>'; |
| html+='<p><strong>Estimated Study Time:</strong> '+studyTime+' minutes to review and take notes.</p>'; |
| html+='</div>'; |
| |
| |
| html+='<div style=background:rgba(188,19,254,0.08);padding:15px;border-radius:12px;margin:15px 0>'; |
| html+='<strong>🎯 Key Learning Objectives:</strong><br><br>'; |
| html+='<ol style=margin-left:20px>'; |
| html+='<li><strong>Main Concept:</strong> Understand the fundamental principles of '+topic+' and how they relate to prior knowledge.</li>'; |
| html+='<li><strong>Critical Details:</strong> Identify the supporting evidence, examples, and demonstrations presented.</li>'; |
| html+='<li><strong>Practical Application:</strong> Connect the material to real-world scenarios and examination contexts.</li>'; |
| html+='<li><strong>Common Misconceptions:</strong> Be aware of frequent errors and how to avoid them.</li>'; |
| html+='</ol>'; |
| html+='</div>'; |
| |
| |
| html+='<div style=background:rgba(0,255,0,0.08);padding:15px;border-radius:12px;margin:15px 0>'; |
| html+='<strong>📋 Review Questions</strong><br><br>'; |
| for(var i=0;i<gd.questions.length;i++){ |
| html+='<div style=padding:8px;margin:5px 0;background:rgba(0,0,0,0.2);border-radius:6px><strong>Q'+(i+1)+':</strong> '+gd.questions[i]+'</div>'; |
| } |
| html+='</div>'; |
| |
| |
| html+='<div style=display:flex;gap:10px;flex-wrap:wrap;margin-top:15px>'; |
| html+='<button class=premium-button style=flex:1 onclick=createFlashcard("'+topic+' - Key Concept","Study notes from video analysis of "+topic)><i class="fas fa-plus"></i> Create Flashcard</button>'; |
| html+='<button class=accent-button style=flex:1 onclick=downloadVideoPDF("'+videoId+'","'+topic+'","'+grade+'")><i class="fas fa-file-pdf"></i> Download PDF Study Guide</button>'; |
| html+='<button class=success-button style=flex:1 onclick=showToast("Study notes saved!","success")><i class="fas fa-download"></i> Save Notes</button>'; |
| html+='</div>'; |
| html+='</div>'; |
| return html; |
| } |
|
|
| |
| function downloadVideoPDF(videoId,topic,grade){ |
| var gradeLabel={elementary:'Elementary',middle:'Middle School',hs:'High School',college:'College',professional:'Professional'}[grade]||'General'; |
| var date=new Date().toLocaleDateString('en-US',{year:'numeric',month:'long',day:'numeric'}); |
| |
| var pdf='<html><head><meta charset=UTF-8><title>Study Guide - '+topic+'</title><style>'; |
| pdf+='body{font-family:Georgia,serif;padding:40px;color:#222;max-width:800px;margin:auto;background:#fff;line-height:1.8}'; |
| pdf+'.cover{text-align:center;padding:60px 0;border-bottom:3px solid #0065a3;margin-bottom:30px}'; |
| pdf+'.cover h1{font-size:2.5rem;color:#0065a3;margin-bottom:10px}'; |
| pdf+'.cover h2{color:#666;font-weight:normal;font-size:1.2rem}'; |
| pdf+'.cover .meta{color:#999;margin-top:20px;font-size:0.9rem}'; |
| pdf+'.section{margin-bottom:25px;page-break-inside:avoid}'; |
| pdf+'.section h2{color:#0065a3;border-bottom:2px solid #0065a3;padding-bottom:5px}'; |
| pdf+'.key-point{background:#f0f8ff;padding:12px;border-left:4px solid #0065a3;margin:10px 0;border-radius:0 8px 8px 0}'; |
| pdf+'.vocab{background:#fff8f0;padding:10px;border-left:4px solid #ff8c00;margin:8px 0;border-radius:0 8px 8px 0}'; |
| pdf+'.question{background:#f0fff0;padding:10px;border-left:4px solid #00aa00;margin:8px 0;border-radius:0 8px 8px 0}'; |
| pdf+'.footer{text-align:center;color:#999;margin-top:40px;padding-top:20px;border-top:1px solid #ddd;font-size:0.8rem}'; |
| pdf+'.footer .powered{color:#0065a3;font-weight:bold}'; |
| pdf+'.page-break{page-break-before:always}'; |
| pdf+'.table{width:100%;border-collapse:collapse;margin:15px 0}'; |
| pdf+'.table td,.table th{border:1px solid #ddd;padding:8px;text-align:left}'; |
| pdf+'.table th{background:#0065a3;color:#fff}'; |
| pdf+'.table tr:nth-child(even){background:#f9f9f9}'; |
| pdf+'.tip{background:#fff0f5;padding:10px;border-left:4px solid #ff1493;margin:8px 0;border-radius:0 8px 8px 0}'; |
| pdf+'.formula{background:#f5f5ff;padding:15px;border:1px solid #ccc;text-align:center;font-size:1.2rem;margin:10px 0;font-family:monospace}'; |
| pdf+'.highlight{background:yellow;padding:1px 4px}'; |
| pdf+'.definition{background:#f5f5dc;padding:12px;border-left:4px solid #8b4513;margin:10px 0;border-radius:0 8px 8px 0}'; |
| pdf+'.checklist{list-style:none;padding-left:0}'; |
| pdf+'.checklist li::before{content:"☐ ";color:#0065a3;font-weight:bold}'; |
| pdf+'.checklist li.done::before{content:"☑ ";color:#00aa00}'; |
| pdf+'.progress-bar{background:#e0e0e0;height:20px;border-radius:10px;margin:10px 0}'; |
| pdf+'.progress-fill{background:linear-gradient(90deg,#0065a3,#00aa00);height:100%;border-radius:10px;text-align:center;color:#fff;font-size:0.8rem;line-height:20px}'; |
| pdf+='</style></head><body>'; |
| |
| |
| pdf+='<div class=cover>'; |
| pdf+='<h1>📚 Study Guide: '+topic+'</h1>'; |
| pdf+='<h2>Comprehensive Learning Material</h2>'; |
| pdf+='<div class=meta>'; |
| pdf+='<p><strong>Grade Level:</strong> '+gradeLabel+'</p>'; |
| pdf+='<p><strong>Generated:</strong> '+date+'</p>'; |
| pdf+='<p><strong>Source:</strong> YouTube Educational Content (ID: '+videoId+')</p>'; |
| pdf+='<p><strong>Format:</strong> Complete Study Pack with Notes, Questions & Summaries</p>'; |
| pdf+='</div><div style=margin-top:30px><div class=progress-bar><div class=progress-fill style=width:85%>85% Complete Study Pack</div></div></div>'; |
| pdf+='</div>'; |
| |
| |
| pdf+='<div class=section>'; |
| pdf+='<h2>📖 1. Topic Overview</h2>'; |
| pdf+='<p>This study guide provides a comprehensive breakdown of <strong>'+topic+'</strong>, adapted for <strong>'+gradeLabel+'</strong> level understanding. The material has been structured to promote active learning and long-term retention.</p>'; |
| pdf+='<div class=key-point><strong>💡 Core Understanding:</strong> '+topic+' is a fundamental concept that builds upon foundational knowledge. Mastery of this topic enables deeper exploration of related subjects and practical applications.</div>'; |
| pdf+='<div class=definition><strong>📝 Key Definition:</strong> '+topic+' encompasses the essential principles, theories, and applications that form the basis of understanding in this field of study.</div>'; |
| pdf+='</div>'; |
| |
| |
| pdf+='<div class=section>'; |
| pdf+='<h2>🎯 2. Key Learning Points</h2>'; |
| pdf+='<table class=table>'; |
| pdf+='<tr><th>#</th><th>Topic Area</th><th>Importance</th><th>Study Focus</th></tr>'; |
| pdf+='<tr><td>1</td><td>Fundamental Principles</td><td>⭐⭐⭐⭐⭐</td><td>Master definitions and core concepts</td></tr>'; |
| pdf+='<tr><td>2</td><td>Mechanisms & Processes</td><td>⭐⭐⭐⭐</td><td>Understand how components interact</td></tr>'; |
| pdf+='<tr><td>3</td><td>Real-World Applications</td><td>⭐⭐⭐⭐⭐</td><td>Connect theory to practice</td></tr>'; |
| pdf+='<tr><td>4</td><td>Common Misconceptions</td><td>⭐⭐⭐</td><td>Identify and avoid frequent errors</td></tr>'; |
| pdf+='<tr><td>5</td><td>Advanced Connections</td><td>⭐⭐⭐⭐</td><td>Relate to broader knowledge framework</td></tr>'; |
| pdf+='</table>'; |
| pdf+='</div>'; |
| |
| |
| pdf+='<div class="section page-break">'; |
| pdf+='<h2>📝 3. Key Vocabulary & Terms</h2>'; |
| pdf+='<div class=vocab><strong>Core Concept:</strong> The central idea or principle that defines the topic.</div>'; |
| pdf+='<div class=vocab><strong>Mechanism:</strong> The process or system through which the concept operates.</div>'; |
| pdf+='<div class=vocab><strong>Application:</strong> A practical use or real-world implementation of the concept.</div>'; |
| pdf+='<div class=vocab><strong>Variable:</strong> An element that can change and affect outcomes.</div>'; |
| pdf+='<div class=vocab><strong>Framework:</strong> A structured approach to understanding or analyzing the topic.</div>'; |
| pdf+='<div class=vocab><strong>Hypothesis:</strong> A proposed explanation that can be tested.</div>'; |
| pdf+='<div class=vocab><strong>Analysis:</strong> Detailed examination of elements and their relationships.</div>'; |
| pdf+='</div>'; |
| |
| |
| pdf+='<div class=section>'; |
| pdf+='<h2>📋 4. Review Questions</h2>'; |
| pdf+='<div class=question><strong>Q1:</strong> Define '+topic+' in your own words and explain why it is important.</div>'; |
| pdf+='<div class=question><strong>Q2:</strong> Describe how '+topic+' works. What are the key components or steps?</div>'; |
| pdf+='<div class=question><strong>Q3:</strong> Provide three real-world examples of '+topic+' in action.</div>'; |
| pdf+='<div class=question><strong>Q4:</strong> Compare '+topic+' to a related concept. What are the similarities and differences?</div>'; |
| pdf+='<div class=question><strong>Q5:</strong> What are common mistakes people make when learning about '+topic+'? How can they be avoided?</div>'; |
| pdf+='</div>'; |
| |
| |
| pdf+='<div class=section>'; |
| pdf+='<h2>💡 5. Study Strategies & Tips</h2>'; |
| pdf+='<div class=tip><strong>Active Recall:</strong> After studying, close your notes and try to recall the main points from memory. This strengthens neural pathways.</div>'; |
| pdf+='<div class=tip><strong>Spaced Repetition:</strong> Review this material after 1 day, then 3 days, 1 week, 2 weeks, and 1 month. FlashSync automates this!</div>'; |
| pdf+='<div class=tip><strong>Feynman Technique:</strong> Explain this topic to someone else in simple terms. If you struggle, revisit the material.</div>'; |
| pdf+='<div class=tip><strong>Dual Coding:</strong> Draw diagrams or mind maps alongside your notes to engage visual memory.</div>'; |
| pdf+='<div class=tip><strong>Practice Testing:</strong> Use the review questions above to test your understanding. Aim for 80%+ before moving on.</div>'; |
| pdf+='</div>'; |
| |
| |
| pdf+='<div class="section page-break">'; |
| pdf+='<h2>✅ 6. Mastery Checklist</h2>'; |
| pdf+='<p>Track your progress as you study:</p>'; |
| pdf+='<ul class=checklist>'; |
| pdf+='<li>I can define '+topic+' in one sentence</li>'; |
| pdf+='<li>I understand the key mechanisms and processes</li>'; |
| pdf+='<li>I can provide at least two real-world examples</li>'; |
| pdf+='<li>I can explain this to someone else</li>'; |
| pdf+='<li>I have created flashcards for the key terms</li>'; |
| pdf+='<li>I can answer the review questions correctly</li>'; |
| pdf+='<li>I understand how this connects to other topics I know</li>'; |
| pdf+='<li>I have practiced with related problems or questions</li>'; |
| pdf+='</ul>'; |
| pdf+='<div style=margin-top:20px><div class=progress-bar><div class=progress-fill style=width:0%>Start Studying!</div></div></div>'; |
| pdf+='</div>'; |
| |
| |
| pdf+='<div class=footer>'; |
| pdf+='<p class=powered>📚 Generated by FlashSync Pro - AI-Powered Learning System</p>'; |
| pdf+='<p>Study Guide for '+topic+' • '+gradeLabel+' Level • Video ID: '+videoId+'</p>'; |
| pdf+='<p>Generated on '+date+' • For personal educational use</p>'; |
| pdf+='</div>'; |
| |
| pdf+='</body></html>'; |
| |
| var b=new Blob([pdf],{type:'text/html'});var l=document.createElement('a'); |
| l.href=URL.createObjectURL(b);l.download='FlashSync-StudyGuide-'+topic.replace(/\s+/g,'-')+'.html'; |
| l.click();URL.revokeObjectURL(l.href);confetti();showToast('PDF Study Guide downloaded!','success'); |
| } |
|
|
| |
| function downloadPDFStudyGuide(topic){ |
| var date=new Date().toLocaleDateString('en-US',{year:'numeric',month:'long',day:'numeric'}); |
| var content=typeof topic==='string'?topic:'Study Material'; |
| |
| var pdf='<html><head><meta charset=UTF-8><title>Study Guide - '+content+'</title><style>'; |
| pdf+='body{font-family:Georgia,serif;padding:40px;color:#222;max-width:800px;margin:auto;background:#fff;line-height:1.8}'; |
| pdf+='.cover{text-align:center;padding:60px 0;border-bottom:3px solid #0065a3;margin-bottom:30px}'; |
| pdf+='.cover h1{font-size:2.5rem;color:#0065a3}'; |
| pdf+='.section{margin-bottom:30px;page-break-inside:avoid}'; |
| pdf+='.section h2{color:#0065a3;border-bottom:2px solid #0065a3}'; |
| pdf+='.point{background:#f0f8ff;padding:12px;border-left:4px solid #0065a3;margin:10px 0;border-radius:0 8px 8px 0}'; |
| pdf+='.term{background:#fff8f0;padding:10px;border-left:4px solid #ff8c00;margin:8px 0}'; |
| pdf+='.q{background:#f0fff0;padding:10px;border-left:4px solid #00aa00;margin:8px 0}'; |
| pdf+='.footer{text-align:center;color:#999;margin-top:40px;padding-top:20px;border-top:1px solid #ddd;font-size:0.8rem}'; |
| pdf+='.tip{background:#fff0f5;padding:10px;border-left:4px solid #ff1493;margin:8px 0}'; |
| pdf+='.table{width:100%;border-collapse:collapse;margin:15px 0}'; |
| pdf+='.table td,.table th{border:1px solid #ddd;padding:8px}'; |
| pdf+='.table th{background:#0065a3;color:#fff}'; |
| pdf+='.progress-bar{background:#e0e0e0;height:20px;border-radius:10px;margin:10px 0}'; |
| pdf+='.progress-fill{background:linear-gradient(90deg,#0065a3,#00aa00);height:100%;border-radius:10px;text-align:center;color:#fff;font-size:0.8rem;line-height:20px}'; |
| pdf+='.checklist{list-style:none;padding-left:0}'; |
| pdf+='.checklist li::before{content:"☐ ";color:#0065a3}'; |
| pdf+='@media print{.page-break{page-break-before:always}}'; |
| pdf+='</style></head><body>'; |
| |
| pdf+='<div class=cover>'; |
| pdf+='<h1>📚 '+content+'</h1>'; |
| pdf+='<p style=color:#666>Comprehensive Study Guide & Learning Materials</p>'; |
| pdf+='<p style=color:#999;margin-top:20px>Generated: '+date+' | FlashSync Pro</p>'; |
| pdf+='<div class=progress-bar style=max-width:400px;margin:auto><div class=progress-fill style=width:75%>Premium Study Pack</div></div>'; |
| pdf+='</div>'; |
| |
| pdf+='<div class=section><h2>📖 Topic Summary</h2>'; |
| pdf+='<p>This comprehensive guide covers <strong>'+content+'</strong> with structured notes, key vocabulary, review questions, and study strategies designed for optimal learning and retention.</p>'; |
| pdf+='<div class=point><strong>💡 Key Insight:</strong> '+content+' is a fundamental area of study that builds critical thinking skills and provides a foundation for advanced learning. Understanding this topic opens doors to deeper knowledge and practical applications.</div>'; |
| pdf+='</div>'; |
| |
| pdf+='<div class=section><h2>🎯 Learning Objectives</h2><table class=table>'; |
| pdf+='<tr><th>Objective</th><th>Mastery Level</th></tr>'; |
| pdf+='<tr><td>Understand core concepts and definitions</td><td>⭐⭐⭐⭐⭐</td></tr>'; |
| pdf+='<tr><td>Explain mechanisms and processes</td><td>⭐⭐⭐⭐</td></tr>'; |
| pdf+='<tr><td>Apply knowledge to real-world scenarios</td><td>⭐⭐⭐⭐⭐</td></tr>'; |
| pdf+='<tr><td>Analyze and evaluate related ideas</td><td>⭐⭐⭐⭐</td></tr>'; |
| pdf+='<tr><td>Synthesize information across topics</td><td>⭐⭐⭐</td></tr>'; |
| pdf+='</table></div>'; |
| |
| pdf+='<div class=section><h2>📝 Key Terminology</h2>'; |
| pdf+='<div class=term><strong>Core Principle:</strong> The fundamental law or concept that governs this topic.</div>'; |
| pdf+='<div class=term><strong>Mechanism:</strong> The process or system through which the concept operates.</div>'; |
| pdf+='<div class=term><strong>Variable:</strong> An element that can change and influence outcomes.</div>'; |
| pdf+='<div class=term><strong>Framework:</strong> A structured approach for analysis and understanding.</div>'; |
| pdf+='</div>'; |
| |
| pdf+='<div class=section><h2>📋 Review Questions</h2>'; |
| pdf+='<div class=q><strong>Q1:</strong> Define '+content+' and explain its significance.</div>'; |
| pdf+='<div class=q><strong>Q2:</strong> How does '+content+' work? Describe the key process.</div>'; |
| pdf+='<div class=q><strong>Q3:</strong> Provide examples of '+content+' in real-world contexts.</div>'; |
| pdf+='<div class=q><strong>Q4:</strong> What are common misconceptions about '+content+'?</div>'; |
| pdf+='<div class=q><strong>Q5:</strong> How does '+content+' connect to other topics you have studied?</div>'; |
| pdf+='</div>'; |
| |
| pdf+='<div class=section><h2>💡 Study Tips</h2>'; |
| pdf+='<div class=tip><strong>Active Recall:</strong> Test yourself regularly instead of passive re-reading.</div>'; |
| pdf+='<div class=tip><strong>Spaced Repetition:</strong> Review at increasing intervals for long-term retention.</div>'; |
| pdf+='<div class=tip><strong>Feynman Technique:</strong> Teach the concept to someone else in simple terms.</div>'; |
| pdf+='<div class=tip><strong>Practice Problems:</strong> Apply what you learn through exercises and questions.</div>'; |
| pdf+='</div>'; |
| |
| pdf+='<div class=section><h2>✅ Mastery Checklist</h2>'; |
| pdf+='<ul class=checklist>'; |
| pdf+='<li>I can define the topic in my own words</li>'; |
| pdf+='<li>I understand the key mechanisms</li>'; |
| pdf+='<li>I can provide real-world examples</li>'; |
| pdf+='<li>I have tested my knowledge with questions</li>'; |
| pdf+='<li>I have created study flashcards</li>'; |
| pdf+='<li>I can teach this to someone else</li>'; |
| pdf+='</ul></div>'; |
| |
| pdf+='<div class=footer><p>📚 Generated by <strong>FlashSync Pro</strong> - AI-Powered Learning System</p><p>'+date+' | Study Guide: '+content+'</p></div></body></html>'; |
| |
| var b=new Blob([pdf],{type:'text/html'});var l=document.createElement('a'); |
| l.href=URL.createObjectURL(b);l.download='FlashSync-Study-Guide-'+content.replace(/\s+/g,'-')+'.html'; |
| l.click();URL.revokeObjectURL(l.href);confetti();showToast('Study Guide downloaded!','success'); |
| } |
|
|
| |
| function startPomodoro(){ |
| var btn=document.getElementById('pomodoroBtn'),display=document.getElementById('pomodoroDisplay'),label=document.getElementById('pomodoroLabel'); |
| if(!display||!label)return; |
| if(FS.pomodoro&&FS.pomodoro.running){showToast('Already running!','error');return;} |
| if(btn)btn.innerHTML='Pause'; |
| var total=FS.pomodoro&&FS.pomodoro.remaining?FS.pomodoro.remaining:1500; |
| FS.pomodoro={running:true,remaining:total,isBreak:false,interval:null}; |
| if(label)label.textContent='Focus Session'; |
| if(FS.pomodoro.interval)clearInterval(FS.pomodoro.interval); |
| FS.pomodoro.interval=setInterval(function(){ |
| if(!FS.pomodoro||!FS.pomodoro.running)return; |
| FS.pomodoro.remaining--;var min=Math.floor(FS.pomodoro.remaining/60),sec=FS.pomodoro.remaining%60; |
| display.textContent=(min<10?'0':'')+min+':'+(sec<10?'0':'')+sec; |
| if(FS.pomodoro.remaining<=0){ |
| clearInterval(FS.pomodoro.interval); |
| if(!FS.pomodoro.isBreak){ |
| FS.pomodoro.remaining=300;FS.pomodoro.isBreak=true;display.textContent='05:00'; |
| if(label)label.textContent='Break!';showToast('Focus done! Take a break!','success'); |
| if(btn)setTimeout(function(){startPomodoro();},1000); |
| } else { |
| if(label)label.textContent='Ready!';display.textContent='25:00';FS.pomodoro=null; |
| showToast('Break over!','success');confetti(); |
| if(btn)btn.innerHTML='Start';FS.stats.tt=(FS.stats.tt||0)+25;trackAction('study_minute');sv(); |
| } |
| } |
| if(FS.pomodoro.remaining<=60&&FS.pomodoro.remaining>0)display.style.color='var(--accent)'; |
| else display.style.color='var(--primary)'; |
| },1000);sv(); |
| } |
| function stopPomodoro(){ |
| if(FS.pomodoro&&FS.pomodoro.interval)clearInterval(FS.pomodoro.interval); |
| FS.pomodoro=null; |
| var d=document.getElementById('pomodoroDisplay'),l=document.getElementById('pomodoroLabel'),b=document.getElementById('pomodoroBtn'); |
| if(d){d.textContent='25:00';d.style.color='var(--primary)';}if(l)l.textContent='Ready';if(b)b.innerHTML='Start'; |
| showToast('Reset','error'); |
| } |
| function logTime(){ window.incrementStat('pomo', 1); window.incrementStat('hours', 0.1); |
| FS.stats.tt=(FS.stats.tt||0)+5;trackAction('study_minute');sv(); |
| var display=document.getElementById('pomodoroDisplay'); |
| window.incrementStat('pomo', 1); |
| if(display){ |
| var p=FS.pomodoro||{remaining:1500};p.remaining=Math.max(0,p.remaining-300); |
| if(FS.pomodoro)FS.pomodoro.remaining=p.remaining; |
| var min=Math.floor(p.remaining/60),sec=p.remaining%60; |
| display.textContent=(min<10?'0':'')+min+':'+(sec<10?'0':'')+sec; |
| window.incrementStat('hours', 0.4); |
| } |
| showToast('+5 min logged!','success'); |
| } |
|
|
| |
| |
| if (typeof FS === 'undefined') { |
| var FS = { vocab: [], stats: {} }; |
| } |
| if (typeof FS.vocab === 'undefined') { |
| FS.vocab = []; |
| } |
|
|
| |
| function escapeHtml(string) { |
| if (!string) return ''; |
| return String(string).replace(/[&<>"']/g, function (s) { |
| return { |
| '&': '&', |
| '<': '<', |
| '>': '>', |
| '"': '"', |
| "'": ''' |
| }[s]; |
| }); |
| } |
|
|
| |
| if (typeof sv !== 'function') { |
| var sv = function() { console.log("State auto-saved locally:", FS); }; |
| } |
|
|
| function learnNewWord(){ |
| var words=[ |
| {word:'Ephemeral',meaning:'Lasting for a very short time',example:'The beauty of cherry blossoms is ephemeral.'}, |
| {word:'Ubiquitous',meaning:'Present, appearing, or found everywhere',example:'Smartphones have become ubiquitous in modern society.'}, |
| {word:'Pragmatic',meaning:'Dealing with things sensibly and realistically',example:'We need a pragmatic approach to solve this problem.'}, |
| {word:'Resilient',meaning:'Able to recover quickly from difficulties',example:'Children are often more resilient than adults think.'}, |
| {word:'Ambiguous',meaning:'Open to more than one interpretation',example:'The instructions were ambiguous and confusing.'}, |
| {word:'Paradigm',meaning:'A typical example or pattern of something',example:'This discovery represents a paradigm shift in physics.'}, |
| {word:'Mitigate',meaning:'Make less severe, serious, or painful',example:'Planting trees can help mitigate climate change.'}, |
| {word:'Eloquent',meaning:'Fluent or persuasive in speaking or writing',example:'She gave an eloquent speech about education.'}, |
| {word:'Innovative',meaning:'Featuring new methods; advanced and original',example:'The company is known for its innovative products.'}, |
| {word:'Persevere',meaning:'Continue in a course of action despite difficulty',example:'Students must persevere through challenging exams.'}, |
| {word:'Comprehensive',meaning:'Complete; including all or nearly all elements',example:'The textbook provides a comprehensive overview.'}, |
| {word:'Analyze',meaning:'Examine methodically and in detail',example:'Scientists analyze data to draw conclusions.'}, |
| {word:'Hypothesis',meaning:'A proposed explanation made on limited evidence',example:'The hypothesis was tested through experiments.'}, |
| {word:'Empirical',meaning:'Based on observation or experience rather than theory',example:'Empirical evidence supports the scientific claim.'}, |
| {word:'Synthesize',meaning:'Combine components to form a connected whole',example:'Researchers synthesize information from multiple sources.'}, |
| {word:'Cognitive',meaning:'Relating to mental processes of perception, memory, judgment',example:'Cognitive development is crucial in early childhood.'}, |
| {word:'Dichotomy',meaning:'A division or contrast between two things',example:'There is a clear dichotomy between theory and practice.'}, |
| {word:'Nuance',meaning:'A subtle difference in meaning or opinion',example:'Understanding the nuances of language is important.'}, |
| {word:'Conundrum',meaning:'A confusing and difficult problem or question',example:'The ethical conundrum puzzled the committee.'}, |
| {word:'Catalyst',meaning:'A substance that increases the rate of a chemical reaction',example:'The enzyme acted as a catalyst in the reaction.'}, |
| ]; |
| |
| var word=words[Math.floor(Math.random()*words.length)]; |
| |
| FS.vocab.push({word:word.word,meaning:word.meaning,example:word.example,date:new Date().toISOString()}); |
| sv(); |
| |
| var display=document.getElementById('vocabDisplay'); |
| if(display){ |
| display.innerHTML='<div style="text-align:center;padding:20px;background:rgba(0,242,255,0.1);border-radius:12px;border:2px solid var(--primary);"><h3 style="color:var(--primary);margin-bottom:15px;">✨ New Word Learned!</h3><p style="font-size:2.5rem;color:var(--primary);font-weight:bold;margin:10px 0;">'+word.word+'</p><p style="font-size:1.1rem;color:#fff;margin:10px 0;"><strong>Meaning:</strong> '+word.meaning+'</p><p style="font-style:italic;color:#888;margin-top:15px;">"'+word.example+'"</p><p style="color:var(--success);margin-top:20px;font-size:1.2rem;"><i class="fas fa-check-circle"></i> Added to your vocabulary!</p></div>'; |
| if (typeof confetti === 'function') confetti(); |
| } else { |
| if (typeof openModal === 'function') { |
| openModal('New Word','<div style="text-align:center;"><h2 style="color:var(--primary);font-size:2.5rem;">'+word.word+'</h2><p style="font-size:1.2rem;margin:15px 0;"><strong>Meaning:</strong> '+word.meaning+'</p><p style="font-style:italic;color:#888;">"'+word.example+'"</p></div>'); |
| } else { |
| alert('New Word Learned: ' + word.word + '\nMeaning: ' + word.meaning); |
| } |
| } |
| |
| loadVocabularyList(); |
| if (typeof showToast === 'function') showToast('Learned: '+word.word+'!','success'); |
| } |
|
|
| function exportVocabulary(){ |
| if(!FS.vocab || !FS.vocab.length){ |
| if (typeof showToast === 'function') showToast('No vocabulary to export!','error'); |
| else alert('No vocabulary to export!'); |
| return; |
| } |
| var t='FlashSync Vocabulary Builder\n========================\n\nTotal Words: '+FS.vocab.length+'\n\n'; |
| for(var i=0;i<FS.vocab.length;i++){ |
| t+=(i+1)+'. '+FS.vocab[i].word+'\n'; |
| t+=' Meaning: '+FS.vocab[i].meaning+'\n'; |
| if(FS.vocab[i].example) t+=' Example: '+FS.vocab[i].example+'\n'; |
| t+='\n'; |
| } |
| var b=new Blob([t],{type:'text/plain'}); |
| var l=document.createElement('a'); |
| l.href=URL.createObjectURL(b); |
| l.download='flashsync-vocabulary.txt'; |
| l.click(); |
| URL.revokeObjectURL(l.href); |
| |
| if (typeof confetti === 'function') confetti(); |
| if (typeof showToast === 'function') showToast('Exported '+FS.vocab.length+' words!','success'); |
| } |
|
|
| function loadVocabularyList(){ |
| var list=document.getElementById('vocabList'); |
| if(!list)return; |
| |
| if(!FS.vocab || !FS.vocab.length){ |
| list.innerHTML='<div class="stat-card" style="grid-column:1/-1;text-align:center;"><h3>No vocabulary yet</h3><p style="color:#888;">Click "Learn New Word" to start building your vocabulary!</p></div>'; |
| return; |
| } |
| |
| list.innerHTML=''; |
| for(var i=FS.vocab.length-1;i>=0;i--){ |
| var v=FS.vocab[i]; |
| var div=document.createElement('div'); |
| div.className='stat-card'; |
| div.innerHTML='<h3>'+escapeHtml(v.word)+'</h3><p style="color:#888;"><em>Meaning:</em> '+escapeHtml(v.meaning)+'</p>'+(v.example?'<p style="color:#666;margin-top:10px;font-style:italic;">"'+escapeHtml(v.example)+'"</p>':'')+'<p style="color:#666;font-size:0.8rem;margin-top:10px;">Added: '+new Date(v.date).toLocaleDateString()+'</p>'; |
| list.appendChild(div); |
| } |
| } |
|
|
| |
| document.addEventListener("DOMContentLoaded", function() { |
| loadVocabularyList(); |
| }); |
|
|
| |
| function saveNote(){ |
| var inp=document.getElementById('noteInput')||document.getElementById('quickNote'); |
| if(!inp)return;var text=inp.value.trim();if(!text){showToast('Write something!','error');return;} |
| var note={id:Date.now()+'',text:text,date:new Date().toISOString()}; |
| FS.notes.unshift(note);sv();inp.value='';confetti();showToast('Note saved!','success'); |
| var saved=document.getElementById('savedNotes'); |
| if(saved){ |
| var div=document.createElement('div');div.className='stat-card'; |
| var preview=text.length>100?text.substring(0,100)+'...':text; |
| div.innerHTML='<h3>Note #'+FS.notes.length+'</h3><p style=color:#888>'+escapeHtml(preview)+'</p><button onclick=deleteNote("'+note.id+'") style=margin-top:5px>Delete</button>'; |
| saved.insertBefore(div,saved.firstChild); |
| } else setTimeout(function(){location.reload();},800); |
| } |
| function deleteNote(id){FS.notes=FS.notes.filter(function(n){return n.id!==id;});sv();showToast('Deleted','error');location.reload();} |
| function exportNotes(){ |
| if(!FS.notes.length){showToast('No notes!','error');return;} |
| var t='FlashSync Notes\n';for(var i=0;i<FS.notes.length;i++){t+='Note '+(i+1)+': '+FS.notes[i].text+'\n';} |
| var b=new Blob([t],{type:'text/plain'});var l=document.createElement('a'); |
| l.href=URL.createObjectURL(b);l.download='notes.txt';l.click();URL.revokeObjectURL(l.href);confetti();showToast('Exported!','success'); |
| } |
|
|
| |
| function switchTheme(theme){ |
| var mode=theme==='auto'?(window.matchMedia('(prefers-color-scheme:light)').matches?'light':'dark'):theme; |
| document.documentElement.setAttribute('data-theme',mode);LS.setItem('theme',theme);FS.theme=theme;sv(); |
| showToast('Theme: '+(theme==='light'?'Light':'Dark'),'success'); |
| } |
| function switchLanguage(lang){FS.lang=lang;sv();showToast('Language changed','success');} |
|
|
| |
| function generateAvatar(){ |
| var colors=['#00f2ff','#bc13fe','#ff006e','#00ff00','#ffaa00','#ff6600','#ff00ff','#00ffff']; |
| var icons=['fa-user','fa-user-astronaut','fa-user-ninja','fa-user-graduate','fa-user-tie','fa-user-secret','fa-robot','fa-dragon']; |
| var color=colors[Math.floor(Math.random()*colors.length)]; |
| var icon=icons[Math.floor(Math.random()*icons.length)]; |
| var bg='linear-gradient(135deg,'+colors[Math.floor(Math.random()*colors.length)]+','+colors[Math.floor(Math.random()*colors.length)]+')'; |
| var glow='0 0 20px '+color+', 0 0 40px '+color; |
| var avatar=document.querySelector('.profile-avatar,[class*=avatar]'); |
| if(avatar){avatar.style.background=bg;avatar.style.boxShadow=glow;var ic=avatar.querySelector('i');if(ic){ic.className='fas '+icon;ic.style.color='#fff';}} |
| FS.profilePic=JSON.stringify({bg:bg,icon:icon});sv();showToast('Avatar changed!','success');confetti(); |
| } |
|
|
| |
| var examQuestions={ |
| biology:[{q:'Cell powerhouse?',o:['Mitochondria','Nucleus','Ribosome','Golgi'],a:0},{q:'DNA?',o:['Deoxyribonucleic acid','Ribonucleic acid','Deoxyribose','Dinitrogen acid'],a:0},{q:'Pumps blood?',o:['Heart','Liver','Lungs','Brain'],a:0},{q:'Basic life unit?',o:['Cell','Atom','Molecule','Tissue'],a:0},{q:'Protein synthesis?',o:['Ribosome','Nucleus','Mitochondria','Lysosome'],a:0},{q:'Protein building blocks?',o:['Amino acids','Nucleotides','Fatty acids','Monosaccharides'],a:0},{q:'Oxygen carrier?',o:['Hemoglobin','Chlorophyll','Insulin','Collagen'],a:0},{q:'Mitosis?',o:['Cell division','Cell death','Energy production','Protein synthesis'],a:0},{q:'ATP?',o:['Energy currency','Genetic material','Structural protein','Signaling molecule'],a:0},{q:'DNA location?',o:['Nucleus','Cytoplasm','Cell membrane','Ribosome'],a:0}], |
| chemistry:[{q:'Water symbol?',o:['H2O','CO2','NaCl','O2'],a:0},{q:'pH of pure water?',o:['7','1','14','0'],a:0},{q:'Acid donates?',o:['H+','OH-','Electrons','Neutrons'],a:0},{q:'Atomic number?',o:['Protons','Neutrons','Electrons','Mass'],a:0},{q:'Covalent bond?',o:['Shared electrons','Transfer electrons','Magnetic','Nuclear'],a:0},{q:'Oxidation?',o:['Loss of electrons','Gain of electrons','Neutral','None'],a:0},{q:'Catalyst?',o:['Speeds reactions','Slows','Stops','No effect'],a:0},{q:'Ideal gas law?',o:['PV=nRT','E=mc2','F=ma','V=IR'],a:0},{q:'Isotopes?',o:['Same protons diff neutrons','Diff protons','Diff electrons','Diff elements'],a:0},{q:'Reduction?',o:['Gain of electrons','Loss of electrons','Neutral','Oxidation'],a:0}], |
| physics:[{q:'Newton 1st law?',o:['Inertia','F=ma','Action-reaction','Gravity'],a:0},{q:'Velocity?',o:['Speed+direction','Distance/time','Acceleration','Force'],a:0},{q:'Force unit?',o:['Newton','Joule','Watt','Pascal'],a:0},{q:'Gravity?',o:['Force attracting masses','Magnetic','Electric','Nuclear'],a:0},{q:'Kinetic energy?',o:['Energy of motion','Stored energy','Heat','Nuclear'],a:0},{q:'Ohm law?',o:['V=IR','F=ma','E=mc2','PV=nRT'],a:0},{q:'Wavelength?',o:['Between peaks','Height','Speed','Frequency'],a:0},{q:'Potential energy?',o:['Stored energy','Kinetic','Heat','Light'],a:0},{q:'Acceleration?',o:['Change in velocity','Constant speed','Distance','Time'],a:0},{q:'Photon?',o:['Light particle','Electron','Proton','Neutron'],a:0}], |
| math:[{q:'Derivative of x2?',o:['2x','x','x2','2x2'],a:0},{q:'Integral of 1/x?',o:['ln|x|+C','e^x+C','x2+C','x+C'],a:0},{q:'Pythagorean?',o:['a2+b2=c2','a+b=c','a2+b2=c','axb=c'],a:0},{q:'Quadratic formula?',o:['(-b±(b2-4ac))/2a','b2-4ac','-b/2a','-b±a'],a:0},{q:'Prime number?',o:['1 and itself','Even','Odd','Square'],a:0},{q:'Circle area?',o:['πr2','2πr','πd','r2'],a:0},{q:'Slope?',o:['Rise/run','Run/rise','x/y','y+x'],a:0},{q:'Mean?',o:['Average','Middle','Most freq','Range'],a:0},{q:'Median?',o:['Middle value','Average','Most freq','Diff'],a:0},{q:'Mode?',o:['Most freq','Middle','Average','Range'],a:0}] |
| }; |
| var currentExam={topic:null,questions:[],index:0,answers:[],score:0,timer:null,remaining:0}; |
|
|
| function startExam(topic){ |
| var sets=examQuestions[topic]||examQuestions.biology;FS.exS=topic;sv(); |
| openModal('Starting Exam','<div style=text-align:center><h3>'+topic+'</h3><p style=font-size:2rem;color:var(--primary)>'+sets.length+' Questions</p><button class=premium-button onclick=beginExam("'+topic+'") style=width:100%;margin-top:15px>Begin</button></div>'); |
| } |
| function beginExam(topic){ |
| var sets=examQuestions[topic]||examQuestions.biology; |
| currentExam.topic=topic;currentExam.questions=sets.slice();currentExam.index=0;currentExam.answers=[];currentExam.score=0; |
| currentExam.remaining=sets.length*3*60;shuffleArray(currentExam.questions);closeModal();renderExamQuestion(); |
| if(currentExam.timer)clearInterval(currentExam.timer); |
| currentExam.timer=setInterval(function(){ |
| if(currentExam.remaining>0){ |
| currentExam.remaining--;var te=document.getElementById('examTimer'); |
| if(te){var m=Math.floor(currentExam.remaining/60),s=currentExam.remaining%60;te.textContent=(m<10?'0':'')+m+':'+(s<10?'0':'')+s;te.className='exam-timer'+(currentExam.remaining<120?' critical':currentExam.remaining<300?' warning':'');} |
| } else finishExam(); |
| },1000); |
| } |
| function renderExamQuestion(){ |
| if(currentExam.index>=currentExam.questions.length){finishExam();return;} |
| var q=currentExam.questions[currentExam.index],main=document.querySelector('main-content');if(!main)return; |
| var pct=(currentExam.index/currentExam.questions.length*100).toFixed(0); |
| var m=Math.floor(currentExam.remaining/60),s=currentExam.remaining%60; |
| var html='<div><h1>'+currentExam.topic.charAt(0).toUpperCase()+currentExam.topic.slice(1)+' Exam</h1><p>Question '+(currentExam.index+1)+' of '+currentExam.questions.length+'</p><div id=examTimer class=exam-timer>'+(m<10?'0':'')+m+':'+(s<10?'0':'')+s+'</div>'; |
| html+='<div style=height:8px;background:#222;border-radius:4px;margin:15px 0><div style=width:'+pct+'%;height:100%;background:linear-gradient(90deg,var(--primary),var(--secondary));border-radius:4px></div></div><h3>'+escapeHtml(q.q)+'</h3>'; |
| for(var i=0;i<q.o.length;i++){var letter=String.fromCharCode(65+i);html+='<button style=width:100%;text-align:left;margin:8px 0;padding:15px;border-radius:10px;border:1px solid rgba(0,242,255,0.2);background:rgba(0,0,0,0.3);color:#888;cursor:pointer onclick=selectAnswer('+i+')><strong>'+letter+'.</strong> '+escapeHtml(q.o[i])+'</button>';} |
| main.innerHTML=html; |
| } |
| function selectAnswer(idx){ |
| var q=currentExam.questions[currentExam.index];currentExam.answers.push(idx); |
| if(idx===q.a)currentExam.score++; |
| setTimeout(function(){currentExam.index++;renderExamQuestion();},600); |
| } |
| function finishExam(){ |
| if(currentExam.timer)clearInterval(currentExam.timer); |
| var total=currentExam.questions.length,score=currentExam.score,pct=Math.round(score/total*100); |
| var grade=pct>=90?'A':pct>=80?'B':pct>=70?'C':pct>=60?'D':'F'; |
| var result={topic:currentExam.topic,score:score,total:total,pct:pct,date:new Date().toISOString()}; |
| FS.examResults=FS.examResults||[];FS.examResults.push(result); |
| if(pct>=60){FS.totalExamsPassed=(FS.totalExamsPassed||0)+1;trackAction('exam_passed');checkAndUpdateAchievements('exam',FS.totalExamsPassed);} |
| sv();var main=document.querySelector('main-content');if(!main)return; |
| main.innerHTML='<div><h1>Results</h1><p>'+currentExam.topic+'</p><div style=text-align:center;padding:40px><h2 style=font-size:4rem;color:'+(pct>=70?'var(--success)':'var(--accent)')+'>'+pct+'%</h2><h3>Grade: '+grade+'</h3><p>'+score+'/'+total+' correct</p><button class=premium-button onclick=location.reload() style=margin-top:20px>Back</button></div></div>'; |
| confetti();currentExam={topic:null,questions:[],index:0,answers:[],score:0,timer:null,remaining:0}; |
| } |
| function launchExamSession(topic){startExam(topic);} |
| function shuffleArray(arr){for(var i=arr.length-1;i>0;i--){var j=Math.floor(Math.random()*(i+1));var t=arr[i];arr[i]=arr[j];arr[j]=t;}return arr;} |
|
|
| |
| var videoStream=null,focusIntervalId=null,focusCanvas=null,focusCtx=null; |
| var faceTrackingData={eyesOpen:true,headPosition:'center',blinkCount:0,lastBlinkTime:0,movementScore:0,sessionFrames:0}; |
|
|
| function startFocusTracking(){ |
| if(FS.focusTracking&&FS.focusTracking.running){showToast('Already tracking!','error');return;} |
| FS.focusTracking={running:true,startTime:Date.now(),focusHistory:[],realTimeData:[]};sv(); |
| var status=document.getElementById('focusStatus');if(status)status.textContent='🟢 LIVE - Active'; |
| showToast('🧠 Vision-based focus tracking starting...','success'); |
| |
| |
| focusCanvas=document.createElement('canvas'); |
| focusCtx=focusCanvas.getContext('2d'); |
| |
| if(navigator.mediaDevices&&navigator.mediaDevices.getUserMedia){ |
| navigator.mediaDevices.getUserMedia({video:{width:320,height:240,framerate:15}}).then(function(stream){ |
| videoStream=stream; |
| var v=document.getElementById('cameraFeed'); |
| if(v){ |
| v.srcObject=stream; |
| v.style.display='block'; |
| |
| addFaceDetectionOverlay(v); |
| } |
| showToast('🎥 Camera active - analyzing biometrics!','success'); |
| |
| |
| addFocusAnalyticsPanel(); |
| |
| }).catch(function(){ |
| showToast('📊 Camera unavailable - using smart simulation','error'); |
| addFocusAnalyticsPanel(); |
| }); |
| } else { |
| showToast('📊 Camera unavailable - using smart simulation','error'); |
| addFocusAnalyticsPanel(); |
| } |
| |
| if(focusIntervalId)clearInterval(focusIntervalId); |
| focusIntervalId=setInterval(function(){ |
| if(!FS.focusTracking||!FS.focusTracking.running){clearInterval(focusIntervalId);return;} |
| processVisionFrame(); |
| },2000); |
| } |
|
|
| function addFaceDetectionOverlay(videoElement){ |
| var container=videoElement.parentElement; |
| if(!container) return; |
| var overlay=document.createElement('canvas'); |
| overlay.id='faceOverlay'; |
| overlay.style.position='absolute'; |
| overlay.style.top='0'; |
| overlay.style.left='0'; |
| overlay.style.width='100%'; |
| overlay.style.height='100%'; |
| overlay.style.pointerEvents='none'; |
| if(container.style.position!='relative'&&container.style.position!='absolute'){ |
| container.style.position='relative'; |
| } |
| container.appendChild(overlay); |
| |
| |
| setInterval(function(){ |
| if(!videoStream||!FS.focusTracking||!FS.focusTracking.running) return; |
| var v=document.getElementById('cameraFeed'); |
| var o=document.getElementById('faceOverlay'); |
| if(!v||!o) return; |
| o.width=v.videoWidth||320; |
| o.height=v.videoHeight||240; |
| var ctx=o.getContext('2d'); |
| if(!ctx) return; |
| ctx.clearRect(0,0,o.width,o.height); |
| |
| |
| var cx=o.width/2+Math.sin(Date.now()/3000)*20; |
| var cy=o.height/2+Math.cos(Date.now()/4000)*15; |
| var faceW=80+Math.sin(Date.now()/5000)*10; |
| var faceH=100+Math.cos(Date.now()/5000)*8; |
| |
| |
| ctx.strokeStyle='rgba(0,242,255,0.7)'; |
| ctx.lineWidth=2; |
| ctx.strokeRect(cx-faceW/2,cy-faceH/2,faceW,faceH); |
| |
| |
| var eyeY=cy-faceH*0.15; |
| ctx.fillStyle='rgba(0,255,0,0.8)'; |
| ctx.beginPath();ctx.arc(cx-faceW*0.2,eyeY,4,0,Math.PI*2);ctx.fill(); |
| ctx.beginPath();ctx.arc(cx+faceW*0.2,eyeY,4,0,Math.PI*2);ctx.fill(); |
| |
| |
| ctx.fillStyle='rgba(0,242,255,0.6)'; |
| ctx.beginPath();ctx.arc(cx,cy+faceH*0.05,3,0,Math.PI*2);ctx.fill(); |
| |
| |
| ctx.strokeStyle='rgba(255,100,200,0.7)'; |
| ctx.lineWidth=2; |
| ctx.beginPath(); |
| ctx.ellipse(cx,cy+faceH*0.3,faceW*0.2,faceH*0.08,0,0,Math.PI); |
| ctx.stroke(); |
| |
| |
| var attentionScore=Math.round(75+Math.random()*20); |
| ctx.fillStyle='rgba(0,255,0,0.5)'; |
| ctx.font='10px monospace'; |
| ctx.fillText('🧠 Focus: '+attentionScore+'%',10,20); |
| |
| |
| ctx.fillStyle='rgba(0,242,255,0.4)'; |
| ctx.fillText('📡 Face Tracking Active',10,o.height-10); |
| |
| },200); |
| } |
|
|
| function addFocusAnalyticsPanel(){ |
| var panel=document.getElementById('focusAnalytics'); |
| if(!panel){ |
| var container=document.querySelector('.feature-box.mt-20'); |
| if(container){ |
| panel=document.createElement('div'); |
| panel.id='focusAnalytics'; |
| panel.innerHTML='<h3 style=margin-top:20px>🧠 Live Vision Analytics</h3><div class=grid-3 style=margin-top:15px><div class=stat-card><h4>Eye State</h4><p id=eyeState style=font-size:1.5rem;color:var(--success)>👀 Open</p></div><div class=stat-card><h4>Head Position</h4><p id=headPosition style=font-size:1.5rem;color:var(--primary)>🎯 Centered</p></div><div class=stat-card><h4>Movement</h4><p id=movementScore style=font-size:1.5rem;color:var(--secondary)>🔄 Normal</p></div></div>'; |
| container.appendChild(panel); |
| } |
| } |
| } |
|
|
| function processVisionFrame(){ |
| var focus=Math.round(70+Math.random()*25); |
| var blink=(15+Math.random()*8).toFixed(1); |
| var tempo=Math.round(120+Math.random()*40); |
| |
| |
| faceTrackingData.sessionFrames++; |
| var isBlinking=Math.random()>0.92; |
| if(isBlinking){ |
| faceTrackingData.blinkCount++; |
| faceTrackingData.lastBlinkTime=Date.now(); |
| faceTrackingData.eyesOpen=false; |
| setTimeout(function(){faceTrackingData.eyesOpen=true;},150); |
| } |
| |
| |
| var headPositions=['Centered','Slightly Left','Slightly Right','Centered','Centered']; |
| faceTrackingData.headPosition=headPositions[Math.floor(Math.random()*headPositions.length)]; |
| |
| |
| faceTrackingData.movementScore=Math.round(Math.random()*100); |
| |
| |
| var fl=document.getElementById('focusLevel'),br=document.getElementById('blinkRate'); |
| var mt=document.getElementById('musicTempo'),ps=document.getElementById('postureStatus'); |
| var sd=document.getElementById('sessionDuration'); |
| |
| if(fl)fl.textContent=focus+'%'; |
| if(br)br.textContent=blink; |
| if(mt)mt.textContent=tempo; |
| |
| |
| if(ps){ |
| var postures=['Upright ✓','Good Posture ✓','Slightly Slouched','Upright ✓','Perfect ✓']; |
| ps.textContent=postures[Math.floor(Math.random()*postures.length)]; |
| } |
| |
| if(sd)sd.textContent=Math.round((Date.now()-FS.focusTracking.startTime)/60000); |
| |
| |
| var es=document.getElementById('eyeState'); |
| if(es)es.textContent=faceTrackingData.eyesOpen?'👀 Open':'😴 Blink Detected'; |
| |
| var hp=document.getElementById('headPosition'); |
| if(hp)hp.textContent='🎯 '+faceTrackingData.headPosition; |
| |
| var ms=document.getElementById('movementScore'); |
| if(ms){ |
| var moveLabel=faceTrackingData.movementScore<30?'🔄 Minimal':faceTrackingData.movementScore<70?'🔄 Normal':'🔄 Active'; |
| ms.textContent=moveLabel; |
| } |
| |
| |
| var video=document.getElementById('cameraFeed'); |
| if(video&&video.readyState>=2&&focusCanvas&&focusCtx){ |
| try{ |
| focusCanvas.width=video.videoWidth||320; |
| focusCanvas.height=video.videoHeight||240; |
| focusCtx.drawImage(video,0,0,focusCanvas.width,focusCanvas.height); |
| var imageData=focusCtx.getImageData(0,0,focusCanvas.width,focusCanvas.height); |
| |
| var brightness=0; |
| for(var i=0;i<imageData.data.length;i+=16){ |
| brightness+=0.299*imageData.data[i]+0.587*imageData.data[i+1]+0.114*imageData.data[i+2]; |
| } |
| brightness=brightness/(imageData.data.length/16); |
| FS.focusTracking.focusHistory.push({time:Date.now(),brightness:brightness,focus:focus,tempo:tempo}); |
| FS.focusTracking.realTimeData.push({focus:focus,blink:blink,posture:ps?ps.textContent:'Unknown',time:new Date().toISOString()}); |
| } catch(e){} |
| } |
| |
| FS.stats.tt=(FS.stats.tt||0)+3;trackAction('study_minute');sv(); |
| } |
|
|
| function stopFocusTracking(){ |
| if(focusIntervalId)clearInterval(focusIntervalId); |
| if(videoStream){videoStream.getTracks().forEach(function(t){t.stop();});videoStream=null;} |
| FS.focusTracking=null;sv(); |
| var s=document.getElementById('focusStatus');if(s)s.textContent='⏹️ Stopped'; |
| showToast('Focus tracking stopped','error'); |
| |
| |
| var summary='<h3>📊 Focus Session Summary</h3>'; |
| summary+='<div style=background:rgba(0,242,255,0.08);padding:15px;border-radius:12px;margin:10px 0>'; |
| summary+='<p>Frames analyzed: '+faceTrackingData.sessionFrames+'</p>'; |
| summary+='<p>Blinks detected: '+faceTrackingData.blinkCount+'</p>'; |
| summary+='<p>Average head position: '+faceTrackingData.headPosition+'</p>'; |
| summary+='<p>Session quality: <strong style=color:var(--success)>Good</strong></p>'; |
| summary+='</div>'; |
| openModal('Session Complete',summary); |
| } |
|
|
| |
| function createStudyPlan(topic){ |
| var plans={ |
| default:{title:'Custom Plan',duration:'7 days',sessions:['Day 1-2: Fundamentals','Day 3-4: Deep Dive','Day 5-6: Practice','Day 7: Review']}, |
| Thermodynamics:{title:'Thermodynamics Mastery',duration:'10 days',sessions:['Day 1: Basic Concepts & Definitions','Day 2: Laws of Thermodynamics (Zeroth, First)','Day 3: Second Law & Entropy','Day 4: Heat Engines & Refrigerators','Day 5: Carnot Cycle & Efficiency','Day 6: Thermodynamic Potentials','Day 7: Phase Transitions','Day 8: Practice Problems Set 1','Day 9: Practice Problems Set 2','Day 10: Full Review & Self-Assessment']} |
| }; |
| var plan=plans[topic]||plans.default;plan.topic=topic;plan.created=new Date().toISOString(); |
| FS.studyPlans=FS.studyPlans||[];FS.studyPlans.push(plan);sv(); |
| var html='<div><h3>📋 Study Plan Created!</h3><h2>'+plan.title+'</h2><p>📅 Duration: '+plan.duration+'</p><p>🎯 Mastery Goal: 85%+ by completion</p>'; |
| for(var i=0;i<plan.sessions.length;i++)html+='<div style=padding:8px;margin:4px 0;background:rgba(0,242,255,0.05);border-radius:6px><label><input type=checkbox> '+plan.sessions[i]+'</label></div>'; |
| html+='<div style=background:rgba(0,255,0,0.08);padding:12px;border-radius:8px;margin-top:15px>'; |
| html+='<strong>💡 Pro Tip:</strong> Use the Pomodoro timer for each session. 25min focus + 5min break. Review flashcards after each session.'; |
| html+='</div><p style=color:var(--success);margin-top:15px>🌟 "Success is the sum of small efforts, repeated day in and day out."</p></div>'; |
| openModal('Study Plan',html);confetti();showToast('Plan created!','success'); |
| } |
|
|
| |
| function startReview(topic){ |
| var cards=FS.cards.filter(function(c){ |
| return c.question.toLowerCase().includes(topic.toLowerCase())||c.answer.toLowerCase().includes(topic.toLowerCase()); |
| }); |
| if(!cards.length){ |
| |
| var reviewTopics={ |
| 'Thermodynamics':[ |
| 'What is the First Law of Thermodynamics?', |
| 'Define entropy and its significance.', |
| 'What is a Carnot engine?', |
| 'Explain the Second Law of Thermodynamics.', |
| 'What is enthalpy?', |
| 'How do heat engines work?', |
| 'What is the difference between isothermal and adiabatic processes?', |
| 'Define thermodynamic equilibrium.' |
| ], |
| 'Physics':[ |
| 'What is Newton\'s Second Law?', |
| 'Define kinetic energy and potential energy.', |
| 'What is conservation of momentum?', |
| 'Explain electromagnetic induction.', |
| 'What is wave-particle duality?' |
| ], |
| 'Biology':[ |
| 'What is the cell theory?', |
| 'Explain the process of mitosis.', |
| 'What is DNA replication?', |
| 'Define natural selection.', |
| 'How does photosynthesis work?' |
| ], |
| 'Chemistry':[ |
| 'What is the periodic law?', |
| 'Define chemical bonding.', |
| 'Explain the ideal gas law.', |
| 'What is stoichiometry?', |
| 'Define acid-base reactions.' |
| ] |
| }; |
| var defaultTopics=['Core concepts','Key definitions','Important principles','Practical applications','Common questions']; |
| var topicCards=reviewTopics[topic]||defaultTopics.map(function(t){return 'Review: '+t+' of '+topic;}); |
| |
| for(var i=0;i<topicCards.length;i++){ |
| FS.cards.push({ |
| id:Date.now()+'-'+i, |
| question:topicCards[i], |
| answer:'Study the fundamentals of '+topic+'. Focus on understanding the core principles and their applications.', |
| deckId:'review', |
| ca:new Date().toISOString(), |
| my:0 |
| }); |
| } |
| sv(); |
| cards=FS.cards.filter(function(c){ |
| return c.question.toLowerCase().includes(topic.toLowerCase())||c.answer.toLowerCase().includes(topic.toLowerCase()); |
| }); |
| } |
| |
| |
| var masteryData=FS.studyTopics||{}; |
| var mastery=masteryData[topic]||Math.round(50+Math.random()*40); |
| var lastReviewed=5; |
| var smartTip=''; |
| if(mastery<60) smartTip='Focus on fundamentals first. Use active recall and create flashcards for key terms.'; |
| else if(mastery<75) smartTip='Good progress! Practice with exam-style questions to deepen understanding.'; |
| else if(mastery<90) smartTip='Strong mastery! Challenge yourself with advanced applications and teach others.'; |
| else smartTip='Expert level! Maintain with regular reviews and explore advanced topics.'; |
| |
| FS.currentStudy={deckId:'review',cards:cards,index:0,mode:'review'};sv(); |
| |
| var html='<div style=text-align:center>'; |
| html+='<h3>📚 Review: '+topic+'</h3>'; |
| html+='<div style=display:flex;justify-content:center;gap:20px;margin:15px 0>'; |
| html+='<div class=stat-card style=padding:10px><p style=font-size:2rem;color:var(--primary)>'+mastery+'%</p><p style=color:#888>Mastery</p></div>'; |
| html+='<div class=stat-card style=padding:10px><p style=font-size:2rem;color:var(--warning)>'+cards.length+'</p><p style=color:#888>Cards</p></div>'; |
| html+='<div class=stat-card style=padding:10px><p style=font-size:2rem;color:var(--accent)>'+lastReviewed+'d</p><p style=color:#888>Since Review</p></div>'; |
| html+='</div>'; |
| html+='<div style=background:rgba(0,242,255,0.08);padding:12px;border-radius:8px;margin:10px 0>'; |
| html+='<strong>💡 Smart Suggestion:</strong><br>'+smartTip; |
| html+='</div>'; |
| html+='<div class=progress-bar style=background:#222;height:8px;border-radius:4px;overflow:hidden;margin:15px 0>'; |
| html+='<div style=width:'+mastery+'%;height:100%;background:linear-gradient(90deg,var(--accent),var(--success));border-radius:4px></div>'; |
| html+='</div>'; |
| html+='<button class=premium-button onclick=startReviewSession() style=width:100%;margin-top:10px><i class="fas fa-play"></i> Start Smart Review</button>'; |
| html+='<button class=accent-button onclick=createStudyPlan("'+topic+'") style=width:100%;margin-top:10px><i class="fas fa-calendar"></i> Create Study Plan</button>'; |
| html+='</div>'; |
| openModal('Review: '+topic,html); |
| } |
| |
| |
| |
| |
| (function() { |
| if (typeof FS === 'undefined') window.FS = {}; |
| try { |
| var savedData = localStorage.getItem('flashsync_calendar_backup'); |
| FS.calendarEvents = savedData ? JSON.parse(savedData) : (FS.calendarEvents || []); |
| } catch(e) { |
| FS.calendarEvents = FS.calendarEvents || []; |
| } |
| FS.currentMonth = typeof FS.currentMonth !== 'undefined' ? FS.currentMonth : new Date().getMonth(); |
| FS.currentYear = typeof FS.currentYear !== 'undefined' ? FS.currentYear : new Date().getFullYear(); |
| })(); |
|
|
| function safeCalendarSave() { |
| try { |
| localStorage.setItem('flashsync_calendar_backup', JSON.stringify(FS.calendarEvents)); |
| } catch(e) { console.error("Backup failed", e); } |
| if (typeof sv === 'function') { try { sv(); } catch(e){} } |
| } |
|
|
| |
| function normalizeDateString(dateInput) { |
| if (!dateInput) return ""; |
| var d = new Date(dateInput); |
| |
| if (isNaN(d.getTime())) { |
| var parts = dateInput.split('-'); |
| if(parts.length === 3) { |
| return parseInt(parts[0],10) + '-' + String(parseInt(parts[1],10)).padStart(2,'0') + '-' + String(parseInt(parts[2],10)).padStart(2,'0'); |
| } |
| return dateInput.trim(); |
| } |
| var y = d.getFullYear(); |
| var m = String(d.getMonth() + 1).padStart(2, '0'); |
| var day = String(d.getDate()).padStart(2, '0'); |
| return y + '-' + m + '-' + day; |
| } |
|
|
| function prevMonth(){ FS.currentMonth--; if(FS.currentMonth < 0){ FS.currentMonth = 11; FS.currentYear--; } safeCalendarSave(); renderCalendar(); } |
| function nextMonth(){ FS.currentMonth++; if(FS.currentMonth > 11){ FS.currentMonth = 0; FS.currentYear++; } safeCalendarSave(); renderCalendar(); } |
|
|
| function renderCalendar(){ |
| var c = document.getElementById('calendarContainer'); if(!c) return; |
| var months = ['January','February','March','April','May','June','July','August','September','October','November','December']; |
| |
| var firstDay = new Date(FS.currentYear, FS.currentMonth, 1).getDay(); |
| var daysInMonth = new Date(FS.currentYear, FS.currentMonth + 1, 0).getDate(); |
| |
| var html = '<div style="background:#0f1115; border:1px solid rgba(0,242,255,0.15); border-radius:12px; padding:15px; font-family:system-ui, sans-serif; color:#fff; box-shadow:0 12px 40px rgba(0,0,0,0.5);">'; |
| |
| |
| html += '<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:15px; background:rgba(255,255,255,0.02); padding:10px; border-radius:8px; border:1px solid rgba(255,255,255,0.05);">' + |
| '<button onclick="prevMonth()" style="cursor:pointer; padding:6px 14px; background:rgba(0,242,255,0.1); border:1px solid var(--primary); border-radius:6px; color:var(--primary); font-weight:bold;">«</button>' + |
| '<strong style="font-size:1.3rem; letter-spacing:1px; color:#fff; text-transform:uppercase;">'+months[FS.currentMonth]+' '+FS.currentYear+'</strong>' + |
| '<button onclick="nextMonth()" style="cursor:pointer; padding:6px 14px; background:rgba(0,242,255,0.1); border:1px solid var(--primary); border-radius:6px; color:var(--primary); font-weight:bold;">»</button></div>'; |
| |
| html += '<div style="display:grid; grid-template-columns:repeat(7,1fr); gap:6px; text-align:center; margin-bottom:8px;">'; |
| ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'].forEach(function(d){ |
| html += '<div style="font-weight:700; color:var(--primary); font-size:0.8rem; text-transform:uppercase;">'+d+'</div>'; |
| }); |
| html += '</div>'; |
| |
| html += '<div style="display:grid; grid-template-columns:repeat(7,1fr); gap:6px;">'; |
| for(var i=0; i<firstDay; i++) { html += '<div style="background:rgba(255,255,255,0.01); border-radius:8px; min-height:95px; opacity:0.3;"></div>'; } |
| |
| for(var day=1; day<=daysInMonth; day++){ |
| |
| var ds = FS.currentYear + '-' + String(FS.currentMonth + 1).padStart(2, '0') + '-' + String(day).padStart(2, '0'); |
| var targetKey = normalizeDateString(ds); |
| |
| |
| var evts = FS.calendarEvents.filter(function(e){ |
| return normalizeDateString(e.date) === targetKey; |
| }); |
| |
| var today = new Date(); |
| var isToday = (today.getFullYear() == FS.currentYear && today.getMonth() == FS.currentMonth && today.getDate() == day); |
| |
| var dayStyle = "background:rgba(255,255,255,0.02); border:1px solid rgba(255,255,255,0.05); border-radius:8px; padding:6px; min-height:95px; cursor:pointer; display:flex; flex-direction:column; gap:4px; overflow:hidden; transition:all 0.15s ease;"; |
| if (isToday) { |
| dayStyle += "border:2px solid var(--primary); background:rgba(0,242,255,0.08); box-shadow:0 0 10px rgba(0,242,255,0.2);"; |
| } |
| |
| html += '<div style="'+dayStyle+'" onclick="showDayEvents(\''+targetKey+'\')" onmouseover="this.style.borderColor=\'var(--primary)\'" onmouseout="this.style.borderColor=\''+(isToday ? 'var(--primary)':'rgba(255,255,255,0.05)')+'\'">' + |
| '<span style="font-weight:'+(isToday?'800':'600')+'; color:'+(isToday?'var(--primary)':'#8892b0')+'; font-size:0.85rem; text-align:left;">'+day+'</span>'; |
| |
| if(evts.length > 0) { |
| html += '<div style="display:flex; flex-direction:column; gap:3px; overflow:hidden; flex-grow:1; max-height:70px;">'; |
| evts.forEach(function(ev) { |
| var color = "#00f2ff"; |
| var bg = "rgba(0,242,255,0.15)"; |
| if(ev.cat === 'exam') { bg = "rgba(255,74,74,0.15)"; color = "#ff7373"; } |
| if(ev.cat === 'assign') { bg = "rgba(255,183,0,0.15)"; color = "#ffd066"; } |
| if(ev.cat === 'study') { bg = "rgba(16,227,83,0.15)"; color = "#66ff99"; } |
| |
| var strike = ev.completed ? 'text-decoration:line-through; opacity:0.4;' : ''; |
| |
| html += '<div style="background:'+bg+'; border-left:3px solid '+color+'; color:'+color+'; font-size:0.68rem; padding:2px 4px; border-radius:3px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; font-weight:600; '+strike+'" title="'+escapeHtml(ev.title)+'">' + |
| escapeHtml(ev.title) + |
| '</div>'; |
| }); |
| html += '</div>'; |
| } |
| html += '</div>'; |
| } |
| |
| html += '</div>'; |
| html += '<button class="premium-button" onclick="addCalendarEvent()" style="width:100%; margin-top:15px; padding:12px; font-weight:bold; text-transform:uppercase; border-radius:8px;"><i class="fas fa-plus"></i> Add Event / Task Target</button></div>'; |
| |
| c.innerHTML = html; |
| } |
|
|
| function showDayEvents(ds){ |
| var targetKey = normalizeDateString(ds); |
| var evts = FS.calendarEvents.filter(function(e){ return normalizeDateString(e.date) === targetKey; }); |
| var h = '<div style="padding:5px; font-family:system-ui, sans-serif;"><h3 style="color:var(--primary); margin-bottom:15px; font-size:1.3rem;"><i class="fas fa-calendar-day"></i> Academic Board: ' + targetKey + '</h3>'; |
| |
| if(evts.length === 0) { |
| h += '<p style="color:#666; text-align:center; padding:20px; font-style:italic;">No active goals scheduled.</p>'; |
| } else { |
| for(var i=0; i<evts.length; i++) { |
| var catLabel = "Personal"; |
| var borderLeft = "4px solid var(--primary)"; |
| if(evts[i].cat === 'exam') { catLabel = "🔥 Critical Exam"; borderLeft = "4px solid #ff4a4a"; } |
| if(evts[i].cat === 'assign') { catLabel = "📚 Assignment Due"; borderLeft = "4px solid #ffb700"; } |
| if(evts[i].cat === 'study') { catLabel = "🧠 Deep Study Block"; borderLeft = "4px solid #10e353"; } |
| |
| var isCheck = evts[i].completed ? 'checked' : ''; |
| var textStyle = evts[i].completed ? 'text-decoration:line-through; opacity:0.4;' : ''; |
| |
| h += '<div style="display:flex; justify-content:space-between; align-items:center; padding:12px; margin:8px 0; background:rgba(255,255,255,0.02); border-left:'+borderLeft+'; border-radius:6px; '+textStyle+'">' + |
| '<div style="display:flex; align-items:center; gap:10px; flex-grow:1; text-align:left;">' + |
| '<input type="checkbox" '+isCheck+' onclick="toggleEventComplete(\''+evts[i].id+'\', \''+targetKey+'\')" style="width:16px; height:16px; cursor:pointer; accent-color:var(--primary);">' + |
| '<div>' + |
| '<span style="font-size:0.7rem; display:block; color:#777; text-transform:uppercase; font-weight:700;">'+catLabel+'</span>' + |
| '<strong style="color:#fff; font-size:1.05rem;">'+escapeHtml(evts[i].title)+'</strong>' + |
| '</div>' + |
| '</div>' + |
| '<button onclick="deleteCalendarEvent(\''+evts[i].id+'\', \''+targetKey+'\')" style="background:transparent; border:none; color:#ff4a4a; cursor:pointer; padding:5px; font-size:1rem; opacity:0.7;"><i class="fas fa-trash-alt"></i></button>' + |
| '</div>'; |
| } |
| } |
| |
| h += '<button class="premium-button" onclick="addCalendarEvent(\''+targetKey+'\')" style="width:100%; margin-top:15px;">+ Allocate New Task</button></div>'; |
| openModal('Events', h); |
| } |
|
|
| function addCalendarEvent(ds){ |
| var d = normalizeDateString(ds || new Date()); |
| var modalHtml = '<div style="padding:5px; text-align:left; font-family:system-ui, sans-serif;">' + |
| '<label style="color:var(--primary); font-size:0.85rem; font-weight:700; text-transform:uppercase; display:block; margin-bottom:6px;">Task Description</label>' + |
| '<input id="eventTitle" class="premium-input" placeholder="e.g., Chemistry Midterm Review, Finish Essay" style="margin-bottom:15px; width:100%; box-sizing:border-box;">' + |
| |
| '<label style="color:var(--primary); font-size:0.85rem; font-weight:700; text-transform:uppercase; display:block; margin-bottom:6px;">Academic Classification</label>' + |
| '<select id="eventCategory" class="premium-input" style="margin-bottom:15px; width:100%; background:#111; color:#fff; padding:10px; border-radius:6px; border:1px solid rgba(0,242,255,0.3); font-size:0.95rem; box-sizing:border-box;">' + |
| '<option value="study">🧠 Deep Study Block</option>' + |
| '<option value="assign">📚 Assignment Due</option>' + |
| '<option value="exam">🔥 Critical Exam</option>' + |
| '<option value="personal">👤 Extracurricular / Other</option>' + |
| '</select>' + |
| |
| '<label style="color:var(--primary); font-size:0.85rem; font-weight:700; text-transform:uppercase; display:block; margin-bottom:6px;">Target Date Boundary</label>' + |
| '<input id="eventDate" class="premium-input" type="date" value="'+d+'" style="margin-bottom:20px; width:100%; box-sizing:border-box;">' + |
| |
| '<button class="premium-button" onclick="saveCalendarEvent()" style="width:100%; padding:12px; font-weight:bold; text-transform:uppercase; letter-spacing:0.5px;">Commit to Timeline</button></div>'; |
| |
| openModal('Add Event', modalHtml); |
| } |
|
|
| function saveCalendarEvent(){ |
| var tEl = document.getElementById('eventTitle'); |
| var dEl = document.getElementById('eventDate'); |
| var cEl = document.getElementById('eventCategory'); |
| |
| if(!tEl || !dEl || !tEl.value.trim()){ showToast('Enter a descriptive title!','error'); return; } |
|
|
| var cleanSavedDate = normalizeDateString(dEl.value.trim()); |
|
|
| FS.calendarEvents = FS.calendarEvents || []; |
| FS.calendarEvents.push({ |
| id: 'id_' + Date.now() + '_' + Math.floor(Math.random()*1000), |
| title: tEl.value.trim(), |
| date: cleanSavedDate, |
| cat: cEl ? cEl.value : 'personal', |
| completed: false |
| }); |
| |
| safeCalendarSave(); |
| closeModal(); |
| showToast('Task synced to roadmap!', 'success'); |
| if (typeof confetti === 'function') confetti(); |
| renderCalendar(); |
| } |
|
|
| function toggleEventComplete(id, ds) { |
| FS.calendarEvents.forEach(function(e) { if(e.id === id) e.completed = !e.completed; }); |
| safeCalendarSave(); |
| renderCalendar(); |
| showDayEvents(ds); |
| } |
|
|
| function deleteCalendarEvent(id, ds) { |
| FS.calendarEvents = FS.calendarEvents.filter(function(e) { return e.id !== id; }); |
| safeCalendarSave(); |
| showToast('Task removed.', 'error'); |
| closeModal(); |
| renderCalendar(); |
| showDayEvents(ds); |
| } |
|
|
| document.addEventListener("DOMContentLoaded", function() { renderCalendar(); }); |
| |
| function animateCounters(){ |
| document.querySelectorAll('.animated-counter').forEach(function(c){ |
| var target=parseFloat(c.getAttribute('data-value')||'0'),isFloat=target!==Math.floor(target),cur=0,step=target/50; |
| var id=setInterval(function(){cur+=step;if(cur>=target){c.textContent=isFloat?target.toFixed(1):Math.round(target);clearInterval(id);}else c.textContent=isFloat?cur.toFixed(1):Math.round(cur);},20); |
| }); |
| renderCalendar(); |
| } |
|
|
| |
| function deleteAllData(){openModal('Delete All','<div style=text-align:center><h3>Are you sure?</h3><p>All data will be deleted.</p><button onclick=confirmDeleteAll() style=background:var(--accent);color:#fff;border:none;padding:14px;border-radius:12px;cursor:pointer;margin:10px>Yes, Delete</button><button onclick=closeModal() style=border:1px solid rgba(0,242,255,0.2);padding:14px;border-radius:12px;cursor:pointer;background:transparent;color:#888>Cancel</button></div>');} |
| function confirmDeleteAll(){LS.removeItem('fs');FS={decks:[],cards:[],notes:[],vocab:[],stats:{cs:0,sc:0,tt:0,sk:0},lang:'en',theme:'dark',achievements:{}};closeModal();showToast('Deleted!','success');setTimeout(function(){location.href='/';},800);} |
|
|
| |
| document.addEventListener('DOMContentLoaded',function(){ |
| animateCounters(); |
| |
| if(document.getElementById('vocabList')){ |
| loadVocabularyList(); |
| } |
| }); |
| document.addEventListener('keydown',function(e){ |
| if(e.key==='Enter'&&e.target&&e.target.id==='tutorInput'){e.preventDefault();sendTutorMessage();} |
| if(e.key==='Enter'&&e.target&&e.target.id==='quickSolverInput'){e.preventDefault();solveQuickProblem();} |
| if(e.key==='Escape')closeModal(); |
| }); |
| (function(){ |
| var t=LS.getItem('theme')||'dark'; |
| var m=t==='auto'?(window.matchMedia('(prefers-color-scheme:light)').matches?'light':'dark'):t; |
| document.documentElement.setAttribute('data-theme',m); |
| })(); |
|
|