@@ -550,19 +550,25 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
550550 }
551551
552552 // --- 4. AI & RUN ---
553- let spinnerInterval = null ;
554- function termSpinner ( msg ) {
553+ let spinnerInterval = null , spinnerTabId = null ;
554+ function termSpinner ( msg , tabId ) {
555+ clearInterval ( spinnerInterval ) ;
556+ const tid = tabId || activeTabId ;
557+ spinnerTabId = tid ;
558+ if ( tid !== activeTabId ) return ;
555559 const term = document . getElementById ( 'terminal' ) ;
556560 const frames = [ '⠋' , '⠙' , '⠹' , '⠸' , '⠼' , '⠴' , '⠦' , '⠧' , '⠇' , '⠏' ] ;
557561 let i = 0 ;
558562 term . style . color = '#facc15' ;
559563 term . innerText = `${ frames [ 0 ] } ${ msg } ` ;
560- spinnerInterval = setInterval ( ( ) => { i = ( i + 1 ) % frames . length ; term . innerText = `${ frames [ i ] } ${ msg } ` ; syncDockedTerminal ( ) ; } , 80 ) ;
561- return term ;
564+ spinnerInterval = setInterval ( ( ) => {
565+ if ( activeTabId !== tid ) { clearInterval ( spinnerInterval ) ; return ; }
566+ i = ( i + 1 ) % frames . length ; term . innerText = `${ frames [ i ] } ${ msg } ` ; syncDockedTerminal ( ) ;
567+ } , 80 ) ;
562568 }
563569 function termDone ( text , color , tabId ) {
564- clearInterval ( spinnerInterval ) ;
565570 const tid = tabId || activeTabId ;
571+ if ( spinnerTabId === tid ) { clearInterval ( spinnerInterval ) ; spinnerTabId = null ; }
566572 if ( tabs [ tid ] ) { tabs [ tid ] . terminalOutput = text ; tabs [ tid ] . terminalColor = color || '#10b981' ; }
567573 if ( tid === activeTabId ) {
568574 const term = document . getElementById ( 'terminal' ) ;
@@ -595,7 +601,7 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
595601 if ( ! genMgr . acquire ( key ) ) return ;
596602 const body = document . getElementById ( 'aiAnalysisBody' ) ;
597603 body . innerHTML = "<p class='animate-pulse text-blue-400 font-bold'>ANALYZING PATTERNS...</p>" ;
598- termSpinner ( 'Analyzing patterns...' ) ;
604+ termSpinner ( 'Analyzing patterns...' , tabId ) ;
599605 try {
600606 const text = await geminiCall ( `Explain optimal approach:\n${ tabs [ tabId ] . statement } ` ) ;
601607 tabs [ tabId ] . aiAnalysis = text ;
@@ -616,7 +622,7 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
616622 btn . classList . add ( 'animate-pulse' ) ;
617623 const feedbackDiv = document . getElementById ( `feedback-${ stepKey } ` ) ;
618624 if ( feedbackDiv ) feedbackDiv . classList . add ( 'hidden' ) ;
619- termSpinner ( `Validating step ${ stepKey } ...` ) ;
625+ termSpinner ( `Validating step ${ stepKey } ...` , tabId ) ;
620626 try {
621627 const text = await geminiCall ( `Problem: ${ tabs [ tabId ] . statement } \nStep: ${ stepKey } \nInput: ${ content } \n\nGive short feedback (<60 words)` ) ;
622628 if ( activeTabId === tabId ) { feedbackDiv . innerHTML = marked . parse ( text ) ; feedbackDiv . classList . remove ( 'hidden' ) ; }
@@ -654,7 +660,7 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
654660 const tabId = activeTabId ;
655661 const key = `boilerplate_${ tabId } _${ lang } ` ;
656662 if ( ! genMgr . acquire ( key ) ) return ;
657- termSpinner ( `Generating ${ lang } boilerplate...` ) ;
663+ termSpinner ( `Generating ${ lang } boilerplate...` , tabId ) ;
658664 try {
659665 const javaHint = lang === 'java' ? ' For Java: use public class Main with public static void main.' : '' ;
660666 const prompt = `Generate ONLY ${ lang } boilerplate (no solution) for:\n${ tabs [ tabId ] . statement } \n\nUse function name: solve. Include main/entry point.${ javaHint } ONLY code, NO markdown fences.` ;
@@ -700,7 +706,7 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
700706 if ( ! genMgr . acquire ( key ) ) return ;
701707 const btns = getGenTestBtns ( ) ;
702708 btns . forEach ( b => { b . innerHTML = 'Generating...' ; b . classList . add ( 'animate-pulse' ) ; } ) ;
703- if ( ! silent ) termSpinner ( 'Generating tests...' ) ;
709+ if ( ! silent ) termSpinner ( 'Generating tests...' , tabId ) ;
704710 try {
705711 const lang = tabs [ tabId ] . lang || 'python' ;
706712 const prompt = `Generate unit tests for this ${ lang } code. Problem: ${ tabs [ tabId ] . statement } \nCode:\n${ code } \n\nPrint a table of pass/fail results. Return ONLY code, NO markdown fences.` ;
@@ -776,12 +782,12 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
776782 const fullScript = editors [ `${ tabId } _code` ] . getValue ( ) ;
777783
778784 if ( selectedLang !== 'javascript' ) {
779- termSpinner ( 'Sanity check...' ) ;
785+ termSpinner ( 'Sanity check...' , tabId ) ;
780786 const check = await sanityCheck ( fullScript , selectedLang ) ;
781787 if ( ! check . safe ) { termDone ( `[BLOCKED] ${ check . reason } ` , '#f87171' , tabId ) ; return ; }
782788 }
783789
784- termSpinner ( 'Running...' ) ;
790+ termSpinner ( 'Running...' , tabId ) ;
785791 let runSuccess = false ;
786792 if ( selectedLang === 'javascript' ) {
787793 const r = await runJsInSandbox ( fullScript ) ;
@@ -805,12 +811,12 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
805811 const fullScript = editors [ `${ tabId } _code` ] . getValue ( ) + '\n\n' + editors [ `${ tabId } _tests` ] . getValue ( ) ;
806812
807813 if ( selectedLang !== 'javascript' ) {
808- termSpinner ( 'Sanity check...' ) ;
814+ termSpinner ( 'Sanity check...' , tabId ) ;
809815 const check = await sanityCheck ( fullScript , selectedLang ) ;
810816 if ( ! check . safe ) { termDone ( `[BLOCKED] ${ check . reason } ` , '#f87171' , tabId ) ; return ; }
811817 }
812818
813- termSpinner ( 'Running code + tests...' ) ;
819+ termSpinner ( 'Running code + tests...' , tabId ) ;
814820 if ( selectedLang === 'javascript' ) {
815821 const r = await runJsInSandbox ( fullScript ) ;
816822 termDone ( r . output || '(no output)' , r . success ? '#10b981' : '#f87171' , tabId ) ;
@@ -842,6 +848,8 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
842848
843849 function clearTerminal ( ) {
844850 document . getElementById ( 'terminal' ) . innerText = '' ;
851+ if ( activeTabId && tabs [ activeTabId ] ) { tabs [ activeTabId ] . terminalOutput = '' ; tabs [ activeTabId ] . terminalColor = '' ; }
852+ syncDockedTerminal ( ) ;
845853 }
846854
847855 async function loadState ( ) {
0 commit comments