/* Free Practice page, two pages picked from a dropdown (?view=topic | ?view=mock):
   Topic Tests: topic-wise tests, CAT / IPMAT × VARC / DILR / QA.
   Sectional & Mock Tests: 1) Full mock tests, tabbed by exam; 2) Sectional tests, CAT (VARC/DILR/QA) and
   IPMAT (VARC/QA/LR/DI); 3) Live tests (below).
   The page has its own tests, separate from the PYQ pages: each tab shows only the tests placed on it
   (Admin -> Tests & Mocks -> Website pages -> Free Practice page; groups "Full mock · <exam>",
   "<CAT|IPMAT> sectional · <section>", "<CAT|IPMAT> topic · <section>"). GET /api/mocks only adds the student's attempt info.
   Live Tests (GET /api/live): tests whose window is open, and upcoming ones to register for.
   When a live test's window ends (and it is set to move to Practice) it appears in its Full Mock tab:
   the tab the admin placed it in on this page, otherwise the tab for its exam. */
const FPQ=window.SB_PAGE_DATA.practice;
/* One course per page: cat-mock-tests.html sets window.FPQ_COURSE='CAT', ipmat-mock-tests.html 'IPMAT' (IPMAT Indore,
   IIM-B (B.Sc.), IPMAT Rohtak, JIPMAT and Others). Unset (free-practice-questions.html): both, with a course switch.
   The tests are the same placements (Admin -> Website pages -> Free Practice page). */
const FPQ_COURSE=window.FPQ_COURSE==='CAT'||window.FPQ_COURSE==='IPMAT'?window.FPQ_COURSE:null;
const FPQ_PAGES={CAT:'cat-mock-tests.html',IPMAT:'ipmat-mock-tests.html',CUET:'cuet.html'};
function fpqFam(tab){return tab==='CAT'?'CAT':'IPMAT';}
const FPQ_TABS=FPQ.mockTabs.filter(t=>!FPQ_COURSE||fpqFam(t.key)===FPQ_COURSE);
function fpqExams(kind){return Object.keys(FPQ[kind]).filter(e=>!FPQ_COURSE||e===FPQ_COURSE);}
const h=React.createElement;

/* Full-mock tab for a test's exam. */
function fpqExamTab(exam){
const e=String(exam||'').toLowerCase();
if(/^cat\b/.test(e))return 'CAT';
if(/indore|iift/.test(e))return 'IPMAT Indore';
if(/iim.?b|bangalore|b\.?\s?sc/.test(e))return 'IIM-B (B.Sc.)';
if(/rohtak/.test(e))return 'IPMAT Rohtak';
if(/jipmat/.test(e))return 'JIPMAT';
return 'Others';
}
/* Section key (VARC / DILR / QA / LR / DI) of a test's subject, if the exam has that section. */
function fpqSecOf(subject,secs){
const s=String(subject||'').toUpperCase().replace(/[^A-Z]/g,'');
const k=/^(QA|QUANT|MATH)/.test(s)?'QA':/^(VARC|VA|VERBAL|ENGLISH)/.test(s)?'VARC':/^DILR/.test(s)?'DILR':/^(LR|LOGICAL)/.test(s)?'LR':/^(DI|DATA)/.test(s)?'DI':null;
return k&&secs.indexOf(k)>=0?k:null;
}
/* "Opens on" panel of a Coming-soon test: date and time (IST) and how long until then. */
function fpqOpens(at){
const future=at&&at>Date.now();
if(!future)return h('div',{className:'fpq-opens'},h('span',{className:'ic','aria-hidden':true},'⏳'),h('div',null,h('small',null,'Coming soon'),h('b',null,'Questions are being added')));
const d=new Date(at),o={timeZone:'Asia/Kolkata'};
const part=(k)=>d.toLocaleDateString('en-IN',Object.assign({[k]:k==='day'||k==='year'?'numeric':'short'},o));
const date=part('weekday')+', '+part('day')+' '+part('month')+' '+part('year');
const time=d.toLocaleTimeString('en-IN',Object.assign({hour:'numeric',minute:'2-digit',hour12:true},o)).toUpperCase();
const ms=at-Date.now(),days=Math.floor(ms/86400000),hrs=Math.floor(ms/3600000);
const left=days>=1?'in '+days+' day'+(days===1?'':'s'):hrs>=1?'in '+hrs+' hour'+(hrs===1?'':'s'):'in '+Math.max(1,Math.ceil(ms/60000))+' min';
return h('div',{className:'fpq-opens'},h('span',{className:'ic','aria-hidden':true},'📅'),
h('div',null,h('small',null,'Opens on'),h('b',null,date),h('span',{className:'t'},time+' IST')),h('em',null,left));
}
function fpqNice(s){s=String(s||'');return s===s.toUpperCase()?s.toLowerCase().replace(/(^|[\s(\/-])([a-z])/g,(m,a,b)=>a+b.toUpperCase()).replace(/\b(And|Of|The|In|On|For)\b/g,w=>w.toLowerCase()).replace(/^./,c=>c.toUpperCase()):s;}
function fpqLeft(ms){var s=Math.max(0,Math.floor(ms/1000)),d=Math.floor(s/86400),hh=Math.floor(s%86400/3600),mm=Math.floor(s%3600/60),ss=s%60;
return d?d+'d '+hh+'h':hh?hh+'h '+String(mm).padStart(2,'0')+'m':mm+'m '+String(ss).padStart(2,'0')+'s';}
function fpqMins(m){return window.SBListings?window.SBListings.mins(m):m+' mins';}
function fpqFromTest(t,extra){
// chips: the test's own sections (as the admin named them), else its questions' subjects
return Object.assign({title:t.title,desc:t.description||'',href:t.href||('mock.html?id='+t.id),q:t.questions,dur:fpqMins(t.durationMin),marks:t.maxMarks,secs:(t.sections&&t.sections.length?t.sections.map(s=>s.name||s):t.subjects)||[],exam:t.exam,
attempts:t.myAttempts||0,best:t.myBestPct,lastId:t.myLastAttemptId,tries:t.maxAttempts||null,soon:!!t.comingSoon,opensAt:t.opensAt||null},extra||{});
}
/* Start / Retake, with the attempts the admin allows (tries; null = unlimited): the attempts left, and no button once used up */
function fpqStart(r,retake,start){
const T=window.SBListings?window.SBListings.tries(r):{suffix:''};
if(T.done)return h('span',{className:'fpq-btn ghost',style:{cursor:'default'},title:'You have used every attempt this test allows'},T.used);
return h('a',{className:'fpq-btn',href:r.href},(r.attempts?retake||'Retake test':start||'Start test')+T.suffix+' →');
}
function fpqTries(r){
const T=!r.soon&&window.SBListings?window.SBListings.tries(r):{};
return T.note?h('p',{className:'fpq-when',style:{margin:'10px 0 0'}},T.note):null;
}

/* The page is two pages, picked from the dropdown in the hero (and the header's Practice menu):
   ?view=topic  Topic Tests;  ?view=mock  Sectional & Mock Tests (full mocks, sectional tests, live tests).
   Each is sold as its own plan right per course (server/src/lib/plans.js). */
const FPQ_VIEWS=[{key:'topic',label:'Topic Tests'},{key:'mock',label:'Sectional & Mock Tests'}];
function fpqStartView(){
const q=(/[?&]view=(topic|mock)\b/.exec(location.search)||[])[1];
if(q)return q;
if(/^#(full-mocks|sectional|live-tests)$/.test(location.hash))return 'mock';
return 'topic';
}

function FreePracticePage(){
const LS=window.SBListings;
const P=LS?LS.use('practice'):[];
const [view,setViewState]=React.useState(fpqStartView);
const setView=(v)=>{setViewState(v);try{history.replaceState(null,'',location.pathname+'?view='+v);}catch(e){}window.scrollTo({top:0});};
React.useEffect(()=>{document.title=(FPQ_COURSE?FPQ_COURSE+' ':'')+(view==='topic'?'Topic Tests':'Sectional & Mock Tests')+' | Practice | Scorebuddy';},[view]);
const [tests,setTests]=React.useState(null);
const [mockTab,setMockTab]=React.useState(FPQ_TABS[0].key);
/* live tests: { now, upcoming, past }; refreshed every minute, countdowns tick every second */
const [lives,setLives]=React.useState({now:[],upcoming:[],past:[]});
const [,setTick]=React.useState(0);
const skew=React.useRef(0);
/* per kind ('sectional' | 'topic'): chosen exam and section */
const [pick,setPick]=React.useState({sectional:{exam:FPQ_COURSE||'CAT',sec:'VARC',area:''},topic:{exam:FPQ_COURSE||'CAT',sec:'VARC',area:''}});
const choose=(kind,v)=>setPick(p=>{const cur=Object.assign({},p[kind],v);if(v.exam&&FPQ[kind][v.exam].indexOf(cur.sec)<0)cur.sec=FPQ[kind][v.exam][0];if(v.exam||v.sec)cur.area='';return Object.assign({},p,{[kind]:cur});});
React.useEffect(()=>{let live=true;
(window.SBAuth?window.SBAuth.ready.then(()=>window.SBAuth.api('GET','/mocks')):Promise.reject()).then(l=>{if(live)setTests(Array.isArray(l)?l:[]);},()=>{if(live)setTests([]);});
return ()=>{live=false;};},[]);
React.useEffect(()=>{let on=true;
const load=()=>(window.SBAuth?window.SBAuth.ready.then(()=>window.SBAuth.api('GET','/live')):Promise.reject()).then(l=>{if(!on||!l||!l.now)return;
skew.current=l.serverNow-Date.now();const off=x=>!/cuet/i.test(x.exam||''); /* CUET live tests are on cuet.html */
setLives({now:l.now.filter(off),upcoming:l.upcoming.filter(off),past:(l.past||[]).filter(off),serverNow:l.serverNow});},()=>{});
load();const a=setInterval(load,60000),b=setInterval(()=>setTick(x=>x+1),1000);
return ()=>{on=false;clearInterval(a);clearInterval(b);};},[]);
const nowMs=Date.now()+skew.current;
/* re-sort on the client so a window that opens / closes between refreshes moves at once */
const allLive=lives.now.concat(lives.upcoming).filter(L=>!FPQ_COURSE||fpqFam(liveTab(L))===FPQ_COURSE);
const liveNow=allLive.filter(L=>L.startsAt<=nowMs&&L.endsAt>nowMs);
const liveSoon=allLive.filter(L=>L.startsAt>nowMs);
const livePast=lives.past.concat(allLive.filter(L=>L.endsAt<=nowMs&&L.after==='practice'));
function liveTab(L){return L.practiceTab&&FPQ.mockTabs.some(t=>t.key===L.practiceTab)?L.practiceTab:fpqExamTab(L.exam);}
const all=tests||[];
/* Published tests not placed on any page (there is no separate Mock Tests page): full mocks go to their
   exam's Full Mock tab; sectional / topic tests to their exam and section (from the test's subjects),
   or to the exam's Full Mock tab when the section can't be told. */
const loose={};
all.filter(t=>t.onPage===false&&!/cuet/i.test(t.exam||'')).forEach(t=>{ /* CUET tests live on cuet.html */
const tab=fpqExamTab(t.exam),fam=tab==='CAT'?'CAT':['IPMAT Indore','IIM-B (B.Sc.)','IPMAT Rohtak','JIPMAT'].indexOf(tab)>=0?'IPMAT':null;
const kind=t.testType==='sectional'||t.testType==='topic'?t.testType:'full';
let sec=null;
if(kind!=='full'&&fam)for(const s of (t.subjects||[])){sec=fpqSecOf(s,FPQ[kind][fam]);if(sec)break;}
const grp=sec?fam+' '+kind+' · '+sec:'Full mock · '+tab;
(loose[grp]=loose[grp]||[]).push(fpqFromTest(t));
});

/* ---------- rows of one Practice-page group ---------- */
function groupRows(grp,builtIn){
let rows=(builtIn||[]).map(r=>{const o=LS&&LS.forSlot(P,grp,r.title);if(!o)return r;if(o.hidden)return null;
return o.test?fpqFromTest(o.test,{title:o.title||r.title,desc:o.subtitle||r.desc}):Object.assign({},r,{title:o.title||r.title,desc:o.subtitle||r.desc});}).filter(Boolean);
if(LS)rows=LS.insert(rows,LS.added(P,grp).map(o=>fpqFromTest(o.test,{title:o.title,desc:o.subtitle||'',area:o.area||'',position:o.position})));
/* the student's attempts on these tests */
rows.forEach(r=>{const m=/mock\.html\?id=(\d+)/.exec(r.href||'');const t=m&&all.find(x=>String(x.id)===m[1]);if(t){r.attempts=t.myAttempts||0;r.best=t.myBestPct;r.lastId=t.myLastAttemptId;r.tries=t.maxAttempts||null;}});
return rows;
}
/* a tab's own rows (placed live tests hidden until their window ends), then live tests that ended and moved here */
const hideIds=allLive.filter(L=>L.endsAt>nowMs).map(x=>'mock.html?id='+x.mockId);
const mockRows=(tab)=>{
const rows=groupRows('Full mock · '+tab,FPQ.mocks[tab]).filter(r=>hideIds.indexOf(r.href)<0).concat(loose['Full mock · '+tab]||[]),have=rows.map(r=>r.href);
livePast.filter(x=>liveTab(x)===tab&&have.indexOf('mock.html?id='+x.mockId)<0).forEach(x=>{
const t=all.find(m=>m.id===x.mockId);
rows.push(Object.assign(fpqFromTest(t||{id:x.mockId,title:x.title,description:x.description,durationMin:x.durationMin,questions:x.questions,maxMarks:x.maxMarks,subjects:x.sections,exam:x.exam}),{wasLive:true}));});
/* a test that was live (placed here or moved here): the student's live score */
rows.forEach(r=>{const x=livePast.find(L=>'mock.html?id='+L.mockId===r.href);if(x){r.wasLive=true;r.liveMe=x.me&&x.me.attemptId?x.me:null;}});
return rows;
};
const liveRow=(x)=>({live:x,title:x.title,desc:x.description,href:'live/'+encodeURIComponent(x.slug),q:x.questions,dur:fpqMins(x.durationMin),marks:x.maxMarks,secs:x.sections||[],exam:x.exam});
const kindRows=(kind,exam,sec)=>groupRows(exam+' '+kind+' · '+sec,[]).concat(loose[exam+' '+kind+' · '+sec]||[]);

/* ---------- pieces ---------- */
function tabs(list,cur,set,cls,label){
return h('div',{className:'fpq-tabs '+(cls||''),role:'tablist','aria-label':label},list.map(t=>h('button',{key:t.key,type:'button',role:'tab','aria-selected':cur===t.key,className:'fpq-tab'+(cur===t.key?' on':''),onClick:()=>set(t.key)},
t.live?h('i',{className:'fpq-ldot',title:'Live test now','aria-label':'Live test now'}):null,h('span',null,t.label),t.count!=null?h('small',null,t.count):null)));
}
function testCard(r,i){
if(r.live)return liveCard(r,i);
const meta=[r.q?r.q+' Qs':null,r.dur||null,r.marks?r.marks+' marks':null].filter(Boolean);
return h('div',{key:(r.href||'')+i,className:'fpq-card'+(r.soon?' soon':'')},
h('div',{className:'fpq-card-top'},r.soon?h('span',{className:'fpq-soon-tag'},'COMING SOON'):null,r.exam?h('span',{className:'fpq-badge'},r.exam):null,r.wasLive?h('span',{className:'fpq-badge was'},'Was a live test'):null,r.attempts&&!(window.SBListings&&window.SBListings.tries(r).done&&r.best==null)?h('span',{className:'fpq-done'},window.SBListings&&window.SBListings.tries(r).done?'Best '+r.best+'%':'✓ Attempted'+(r.best!=null?' · best '+r.best+'%':'')):null),
h('h3',null,r.title),
r.desc?h('p',null,r.desc):null,
h('div',{className:'fpq-meta'},meta.map(m=>h('span',{key:m},m)),(r.secs||[]).slice(0,4).map(s=>h('span',{key:'s'+s,className:'sec'},s))),
h('div',{className:'fpq-acts'},
r.soon?fpqOpens(r.opensAt):
fpqStart(r),
r.liveMe?h('a',{className:'fpq-btn ghost',href:'analysis.html?id='+r.liveMe.attemptId},'Live rank & analysis'):r.lastId?h('a',{className:'fpq-btn ghost',href:'analysis.html?id='+r.lastId},'Last analysis'):null,
window.SBShare?window.SBShare.button(h,r.href,r.title):null),
r.liveMe?h('p',{className:'fpq-when',style:{margin:'10px 0 0'}},'🏆 Your live score: '+r.liveMe.score+' / '+r.liveMe.total):null,
fpqTries(r));
}
// a live test the student has taken: their score, and (in the window) when rank and solutions open
function fpqTaken(L,me){
const held=L.submitBy>nowMs,at=new Date(L.submitBy).toLocaleString('en-IN',{timeZone:'Asia/Kolkata',day:'numeric',month:'short',hour:'numeric',minute:'2-digit',hour12:true})+' IST';
return h('a',{className:'fpq-taken',href:'analysis.html?id='+me.attemptId},
h('span',{className:'fpq-taken-k'},'✓ You took this test'),
h('b',null,'Score ',me.score,h('small',null,' / '+me.total)),
h('span',{className:'fpq-taken-n'},held?'🔒 Rank, percentile & solutions open '+at:'See your rank & solutions →'));
}
function liveCard(r,i){
const L=r.live,me=L.me||{},soon=L.startsAt>nowMs,meta=[r.q?r.q+' Qs':null,r.dur||null,r.marks?r.marks+' marks':null].filter(Boolean);
const when=new Date(L.startsAt).toLocaleString('en-IN',{timeZone:'Asia/Kolkata',weekday:'short',day:'numeric',month:'short',hour:'numeric',minute:'2-digit',hour12:true})+' IST';
return h('div',{key:'live'+L.slug,className:'fpq-card live'+(soon?' soon':'')},
h('div',{className:'fpq-card-top'},soon?h('span',{className:'fpq-live soon'},'UPCOMING'):h('span',{className:'fpq-live'},h('i',null),'LIVE NOW'),
h('span',{className:'fpq-left'},(soon?'Starts in ':'Closes in ')+fpqLeft((soon?L.startsAt:L.endsAt)-nowMs)),r.exam?h('span',{className:'fpq-badge'},r.exam):null),
h('h3',null,r.title),
r.desc?h('p',null,r.desc):null,
h('div',{className:'fpq-meta'},meta.map(m=>h('span',{key:m},m)),me.attemptId?null:L.free?h('span',{className:'price'},'Free'):window.SB_APP?null:h('span',{className:'price'},'Entry ₹'+L.priceINR),L.registered?h('span',{key:'reg'},L.registered+' registered'):null),
soon?h('p',{className:'fpq-when'},'🗓 '+when):null,
h('div',{className:'fpq-acts'},me.attemptId?fpqTaken(L,me):
soon?h('a',{className:'fpq-btn'+(me.registered?' ghost':''),href:r.href},me.registered?'✓ Registered · details':(L.free?'Register free →':window.SB_APP?'Details →':'Register · ₹'+L.priceINR+' →')):
h('a',{className:'fpq-btn',href:r.href},(me.registered||L.free?'Take the live test':'Register & take test')+' →')));
}
function empty(text,link){
return h('div',{className:'fpq-empty'},h('div',{className:'fpq-empty-ic','aria-hidden':true},'🗂️'),h('p',null,text),link?h('a',{href:link.href,className:'fpq-btn ghost'},link.label):null);
}

/* ---------- section 1: full mocks ---------- */
const mockTabs=FPQ_TABS.map(t=>Object.assign({},t,{count:mockRows(t.key).length}));
const curTab=FPQ_TABS.find(t=>t.key===mockTab)||FPQ_TABS[0];
const mRows=mockRows(curTab.key);
const mockSection=h('section',{className:'fpq-sec',id:'full-mocks'},
h('div',{className:'fpq-head'},h('div',null,h('span',{className:'fpq-kicker'},'01'),h('h2',null,'Full Mock Tests'),
h('p',null,'Complete, timed papers marked exactly like the real exam — instant score, rank, and topic-wise and question-wise analysis after every attempt.'))),
mockTabs.length>1?tabs(mockTabs,curTab.key,setMockTab,'','Full mock tests by exam'):null,
h('div',{className:'fpq-panel',role:'tabpanel'},
mRows.length?h('div',{className:'fpq-grid'},mRows.map(testCard)):empty(curTab.label+' full mock tests are coming soon.',null)));

/* ---------- sections 2 and 3: sectional and topic-wise (exam, then section) ---------- */
function examSection(kind,num,id,title,intro,noun){
const cur=pick[kind],secs=FPQ[kind][cur.exam],sec=secs.indexOf(cur.sec)>=0?cur.sec:secs[0],def=FPQ.secDefs[sec];
const examTabs=fpqExams(kind).map(e=>({key:e,label:e,count:FPQ[kind][e].reduce((a,s2)=>a+kindRows(kind,e,s2).length,0)}));
const secTabs=secs.map(s2=>({key:s2,label:FPQ.secDefs[s2].label,count:kindRows(kind,cur.exam,s2).length}));
const all=kindRows(kind,cur.exam,sec);
/* Topic-wise: area tabs (Admin -> Website pages files each test under an area), in the order the admin placed them */
const areas=[];if(kind==='topic')all.forEach(r=>{if(r.area&&areas.indexOf(r.area)<0)areas.push(r.area);});
const other=all.filter(r=>!r.area).length;
const area=areas.length&&(cur.area==='__other'?other:areas.indexOf(cur.area)>=0)?cur.area:'';
const rows=!area?all:all.filter(r=>area==='__other'?!r.area:r.area===area);
const areaTabs=areas.length?[{key:'',label:'All',count:all.length}].concat(areas.map(a=>({key:a,label:fpqNice(a),count:all.filter(r=>r.area===a).length})),other?[{key:'__other',label:'Other',count:other}]:[]):null;
return h('section',{className:'fpq-sec',id},
h('div',{className:'fpq-head'},h('div',null,h('span',{className:'fpq-kicker'},num),h('h2',null,title),h('p',null,intro))),
h('div',{className:'fpq-topic-bar'},examTabs.length>1?tabs(examTabs,cur.exam,v=>choose(kind,{exam:v}),'fpq-exam','Exam'):null,tabs(secTabs,sec,v=>choose(kind,{sec:v}),'fpq-under','Section')),
areaTabs?tabs(areaTabs,area,v=>choose(kind,{area:v}),'fpq-area','Area'):null,
h('div',{className:'fpq-panel',role:'tabpanel'},h('div',{className:'fpq-sec-title'},h('b',{style:{color:def.color}},cur.exam+' · '+def.label+(area&&area!=='__other'?' · '+fpqNice(area):'')),h('span',null,def.full)),
rows.length?h('div',{className:'fpq-grid'},rows.map(testCard)):empty(cur.exam+' '+def.label+' '+noun+' are coming soon.',null)));
}
const sectionalSection=examSection('sectional','02','sectional','Sectional Tests','One full section at a time, timed like the real exam — build speed and accuracy section by section.','sectional tests');
const topicSection=examSection('topic','01','topic-wise','Topic-wise Tests','Short, timed tests on one topic at a time — find a weak area and fix it. Pick your exam, then a section.','topic-wise tests');

/* ---------- section 4: live tests ---------- */
const liveSection=h('section',{className:'fpq-sec',id:'live-tests'},
h('div',{className:'fpq-head'},h('div',null,h('span',{className:'fpq-kicker'},'03'),h('h2',null,'Live Tests ',liveNow.length?h('span',{className:'fpq-live big'},h('i',null),liveNow.length+' LIVE NOW'):null),
h('p',null,'All-India tests held in a fixed time window — everyone takes the same paper, so your rank is a real benchmark. After the window, each test moves to its category above.'))),
h('div',{className:'fpq-panel'},
liveNow.length?h('div',{className:'fpq-grid'},liveNow.map(x=>liveCard(liveRow(x)))):empty('No live test is running right now.'+(liveSoon.length?' Register for an upcoming one below.':' New live tests are announced here — check back soon.'),null),
liveSoon.length?h('div',{className:'fpq-group'},h('div',{className:'fpq-group-h'},h('h4',{style:{color:'var(--brand-primary)'}},'UPCOMING — REGISTER NOW'),h('span',null,liveSoon.length+' test'+(liveSoon.length===1?'':'s'))),
h('div',{className:'fpq-grid'},liveSoon.map(x=>liveCard(liveRow(x))))):null));
/* banner under the hero while a test is live */
const banner=liveNow.length?h('a',{className:'fpq-banner',href:view==='mock'?'#live-tests':'?view=mock#live-tests'},h('span',{className:'fpq-live'},h('i',null),'LIVE NOW'),
h('b',null,liveNow[0].title+(liveNow.length>1?' + '+(liveNow.length-1)+' more':'')),h('span',{className:'fpq-left'},'Closes in '+fpqLeft(liveNow[0].endsAt-nowMs)),h('em',null,liveNow[0].me&&liveNow[0].me.attemptId?'✓ Taken · score '+liveNow[0].me.score+' / '+liveNow[0].me.total:'Take the test →')):null;

const topic=view==='topic';
return h('div',{className:'fpq'},
h('section',{className:'fpq-hero'},h('div',{className:'fpq-wrap'},
h('div',{className:'fpq-hero-top'},h('span',{className:'fpq-eyebrow'},FPQ_COURSE?FPQ_COURSE+' PRACTICE':'PRACTICE'),
h('label',{className:'fpq-view'},h('span',null,'Show'),
h('select',{value:view,onChange:e=>setView(e.target.value),'aria-label':'Practice page'},FPQ_VIEWS.map(v=>h('option',{key:v.key,value:v.key},v.label))))),
h('div',{role:'navigation','aria-label':'Course',style:{display:'flex',gap:8,flexWrap:'wrap',margin:'0 0 14px'}},['CAT','IPMAT','CUET'].map(c=>h('a',{key:c,href:FPQ_PAGES[c]+(c==='CUET'?'':'?view='+view),'aria-current':c===FPQ_COURSE?'page':undefined,
style:{padding:'7px 16px',borderRadius:999,fontWeight:800,fontSize:13.5,textDecoration:'none',border:'1.5px solid rgba(255,255,255,.45)',background:c===FPQ_COURSE?'#fff':'transparent',color:c===FPQ_COURSE?'var(--navy-900)':'#fff'}},c))),
topic?h('h1',null,(FPQ_COURSE?FPQ_COURSE+' ':'')+'Topic-wise ',h('span',null,'Tests')):h('h1',null,(FPQ_COURSE?FPQ_COURSE+' ':'')+'Sectional & ',h('span',null,'Mock Tests')),
h('p',null,(()=>{const who=FPQ_COURSE==='CAT'?'CAT':FPQ_COURSE==='IPMAT'?'IPMAT Indore, IPMAT Rohtak, JIPMAT and IIM-B (B.Sc.)':'CAT, IPMAT, IIM-B (B.Sc.), JIPMAT and more';
return topic?'Short, timed tests on one topic at a time for '+who+' — find a weak area and fix it, with a detailed analysis after every attempt.'
:'Full-length mocks and sectional tests for '+who+', plus all-India live tests — every attempt scored instantly with a detailed analysis.';})()),
h('div',{className:'fpq-jump'},topic?[
h('a',{key:'t',href:'#topic-wise'},'Topic-wise Tests'),
h('a',{key:'m',href:'?view=mock',onClick:e=>{e.preventDefault();setView('mock');}},'Sectional & Mock Tests →')]:[
h('a',{key:'f',href:'#full-mocks'},'Full Mock Tests'),h('a',{key:'s',href:'#sectional'},'Sectional Tests'),
h('a',{key:'l',href:'#live-tests',className:'live'},liveNow.length?h('i',{className:'fpq-ldot w'}):null,'Live Tests'),
h('a',{key:'t',href:'?view=topic',onClick:e=>{e.preventDefault();setView('topic');}},'Topic Tests →')]))),
h('div',{className:'fpq-wrap fpq-main'},banner,topic?topicSection:[h(React.Fragment,{key:'m'},mockSection),h(React.Fragment,{key:'s'},sectionalSection),h(React.Fragment,{key:'l'},liveSection)]));
}
window.FreePracticePage=FreePracticePage;
