import {calculate} from './engines.mjs'; const form=document.getElementById('calc-form');if(form){ const cfg=JSON.parse(document.getElementById('calc-data').textContent);const error=document.getElementById('error');const msg=document.getElementById('assessment');const bar=document.getElementById('bar');let results=null; function valInputs(){const x={};for(const f of cfg.fields){const el=form.elements.namedItem(f.key);if(!el||el.value.trim()==='')throw Error('All input fields are required.');const v=Number(el.value);if(!Number.isFinite(v)||v<0||(f.strict&&v<=0)||(f.max!==null&&v>f.max)||(f.integer&&!Number.isInteger(v)))throw Error('Check '+f.label+': invalid quantity, percentage or allowed range.');x[f.key]=v;}return x;} function show(k,v){if(v===null)return 'Not achievable';if(k.includes('Feasible'))return v?'Yes':'No';if(k.includes('Occupancy')||k==='deskOccupancy'||k==='passUtil'||k==='roomUtil'||k==='utilPct')return v.toLocaleString('en-IN',{maximumFractionDigits:1})+'%';if(k.includes('Hours')||k.includes('hours')||k==='hoursDemand'||k==='hoursAvailable'||k==='waterPurchasedKL')return v.toLocaleString('en-IN',{maximumFractionDigits:2});if(k==='breakEvenDesks'||k==='breakEvenJobsMix'||k==='breakEvenRepairs')return v.toLocaleString('en-IN',{maximumFractionDigits:0});return '₹'+v.toLocaleString('en-IN',{maximumFractionDigits:2});} function update(){try{const x=valInputs();const r=calculate(cfg.id,x);error.textContent='';results=r;for(const [k] of cfg.outputs){const el=document.getElementById('out-'+k);if(el)el.textContent=show(k,r[k]);}let util=r.utilPct??r.deskOccupancy??0;bar.style.width=Math.min(100,Math.max(0,util))+'%';document.getElementById('progress-label').textContent=(cfg.id==='CALC-213'?'Dedicated desk occupancy':'Capacity use')+': '+(Number(util).toFixed(1))+'%';const feasible=r.breakEvenFeasible===1;const profit=r.profit;msg.className='alert'+(!feasible||profit<0?' bad':'');msg.textContent=(!feasible?'Break-even is not physically achievable at the entered capacity and current mix. ':'Break-even is feasible at the entered capacity and current mix. ')+(profit>=0?'The example shows an accounting profit.':'The example shows an accounting loss.');}catch(e){results=null;error.textContent=e.message;for(const [k] of cfg.outputs){const el=document.getElementById('out-'+k);if(el)el.textContent='—';}bar.style.width='0%';msg.textContent='Correct the highlighted assumptions before using the results.';msg.className='alert bad';}} form.addEventListener('input',update);form.addEventListener('submit',e=>{e.preventDefault();update()});document.getElementById('reset').addEventListener('click',()=>{HTMLFormElement.prototype.reset.call(form);update()});document.getElementById('export').addEventListener('click',()=>{if(!results){error.textContent='Fix the inputs before exporting.';return;}const rows=[['Calculator',document.title.split(' | ')[0]],['Assumption basis','Illustrative; amounts exclude GST unless specified'],...cfg.fields.map(f=>[f.label,form.elements.namedItem(f.key).value]),['METRIC','VALUE'],...cfg.outputs.map(([k,v])=>[v,results[k]===null?'Not achievable':results[k]])];const csv='\ufeff'+rows.map(a=>a.map(t=>'"'+String(t).replaceAll('"','""')+'"').join(',')).join('\r\n');const u=URL.createObjectURL(new Blob([csv],{type:'text/csv;charset=utf-8'}));const a=document.createElement('a');a.href=u;a.download=location.pathname.split('/').pop().replace('.html','')+'-assumptions-and-results.csv';document.body.appendChild(a);a.click();a.remove();setTimeout(()=>URL.revokeObjectURL(u),1000);});update();}