diff --git a/core/src/main/kotlin/me/eternal/purrfectsnap/core/features/impl/global/CompanionServer.kt b/core/src/main/kotlin/me/eternal/purrfectsnap/core/features/impl/global/CompanionServer.kt
index ce96e8c4..fbc0b9c6 100644
--- a/core/src/main/kotlin/me/eternal/purrfectsnap/core/features/impl/global/CompanionServer.kt
+++ b/core/src/main/kotlin/me/eternal/purrfectsnap/core/features/impl/global/CompanionServer.kt
@@ -722,189 +722,6 @@ function closeDetail(){
q('ne').querySelectorAll('.net-row').forEach(function(r){r.classList.remove('selected');});
}
// ---- Shared ----
-function filter(listId,filterId){
- var f=q(filterId).value.toLowerCase();
- q(listId).querySelectorAll('.log-+e).toISOString().slice(11,23)}
-function q(id){return document.getElementById(id)}
-function loadHistory(){
- fetch('/logs').then(function(r){return r.json();}).then(function(a){a.forEach(function(e){addLog(e,false);});});
- fetch('/network').then(function(r){return r.json();}).then(function(a){a.forEach(function(e){addNet(e,false);});});
-}
-function startSSE(){
- var es=new EventSource('/events');
- es.onopen=function(){q('dot').textContent='● connected';q('dot').className='on';};
- es.onerror=function(){q('dot').textContent='● disconnected';q('dot').className='off';};
- es.addEventListener('log',function(e){addLog(JSON.parse(e.data),true);});
- es.addEventListener('network',function(e){addNet(JSON.parse(e.data),true);});
- es.addEventListener('network_update',function(e){updateNet(JSON.parse(e.data));});
-}
-// ---- Logs ----
-function addLog(e,live){
- lc++;
- var el=document.createElement('div');
- el.className='log-row '+(e.level||'I');
- el.textContent='['+ts(e.ts)+'] '+(e.level||'I')+' '+(e.tag||'')+': '+(e.msg||'');
- el.dataset.t=el.textContent.toLowerCase();
- applyLogFilter(el);
- q('le').appendChild(el);
- if(live&&q('ls').checked)el.scrollIntoView();
- upd();
-}
-function applyLogFilter(el){
- var f=q('lf').value.toLowerCase();
- el.style.display=(!f||el.dataset.t.includes(f))?'':'none';
-}
-// ---- Network rows ----
-function methodClass(m){return m||'GET';}
-function statusSpan(e){
- if(!e.done)return '…';
- if(e.status&&e.status>=400)return ''+e.status+'';
- return ''+(e.status||'ok')+'';
-}
-function sizeStr(bytes){
- if(bytes==null)return '';
- if(bytes<1024)return bytes+'B';
- return (bytes/1024).toFixed(1)+'K';
-}
-function addNet(e,live){
- nc++;
- netMap[e.id]=e;
- var el=document.createElement('div');
- el.className='net-row';
- el.id='nr-'+e.id;
- el.dataset.t=(e.uri||'').toLowerCase();
- el.innerHTML=''+(e.method||'?')+''+
- statusSpan(e)+
- ''+(e.uri||'')+''+
- ''+(e.resSize!=null?sizeStr(e.resSize):'')+'';
- el.onclick=function(){openDetail(e.id);};
- applyNetFilter(el);
- q('ne').appendChild(el);
- if(live&&q('ns').checked)el.scrollIntoView();
- upd();
-}
-function updateNet(e){
- netMap[e.id]=Object.assign(netMap[e.id]||{},e);
- var row=q('nr-'+e.id);
- if(!row)return;
- var m=netMap[e.id];
- row.innerHTML=''+(m.method||'?')+''+
- statusSpan(m)+
- ''+(m.uri||'')+''+
- ''+(m.resSize!=null?sizeStr(m.resSize):'')+'';
- row.onclick=function(){openDetail(m.id);};
- if(detailId===e.id)refreshDetail();
-}
-function applyNetFilter(el){
- var f=q('nf').value.toLowerCase();
- el.style.display=(!f||el.dataset.t.includes(f))?'':'none';
-}
-function filterNet(){
- q('ne').querySelectorAll('.net-row').forEach(applyNetFilter);
-}
-// ---- Detail panel ----
-function openDetail(id){
- detailId=id;
- detailFull=null;
- var sum=netMap[id];
- if(!sum)return;
- q('detail').style.display='flex';
- q('ne').querySelectorAll('.net-row').forEach(function(r){r.classList.remove('selected');});
- var row=q('nr-'+id);
- if(row)row.classList.add('selected');
- renderDetailMeta(sum);
- q('d-body').textContent='Loading…';
- fetch('/network/'+id).then(function(r){return r.json();}).then(function(full){
- detailFull=full;
- renderDetailMeta(full);
- renderBody();
- }).catch(function(){q('d-body').textContent='Failed to load details.';});
-}
-function refreshDetail(){
- if(!detailId)return;
- var sum=netMap[detailId];
- if(!sum)return;
- renderDetailMeta(sum);
- if(detailFull)renderBody();
-}
-function renderDetailMeta(e){
- var m=e.method||'?';
- q('d-badge').className='badge '+methodClass(m);
- q('d-badge').textContent=m;
- q('d-badge').style.cssText='';
- q('d-status').textContent=e.status||(e.done?'ok':'…');
- q('d-status').className=e.status&&e.status>=400?'status-err':'status-ok';
- q('d-uri').textContent=e.uri||'';
-}
-function showTab(tab){
- detailTab=tab;
- q('tab-req').className='tab-btn'+(tab==='req'?' active':'');
- q('tab-res').className='tab-btn'+(tab==='res'?' active':'');
- renderBody();
-}
-function toggleHex(){
- hexMode=!hexMode;
- q('btn-hex').className='tab-btn'+(hexMode?' active':'');
- renderBody();
-}
-function renderBody(){
- if(!detailFull){q('d-body').textContent='Loading…';return;}
- var b64=detailTab==='res'?detailFull.resBody:detailFull.reqBody;
- if(!b64){q('d-body').textContent='(empty)';return;}
- var truncated=b64.endsWith('==TRUNCATED==');
- if(truncated)b64=b64.slice(0,b64.length-13);
- var bytes=b64ToBytes(b64);
- var suffix=truncated?'\n\n[truncated at 48 KB]':'';
- if(hexMode){q('d-body').textContent=hexDump(bytes)+suffix;return;}
- var text=tryUtf8(bytes);
- if(text){
- var pretty=tryJsonPretty(text);
- q('d-body').textContent=(pretty||text)+suffix;
- }else{
- q('d-body').textContent=hexDump(bytes)+suffix;
- }
-}
-function b64ToBytes(b64){
- var bin=atob(b64),bytes=new Uint8Array(bin.length);
- for(var i=0;i=32||c===10||c===13||c===9)printable++;}
- return(printable/Math.min(text.length,200))>0.85?text:null;
- }catch(e){return null;}
-}
-function tryJsonPretty(text){
- try{return JSON.stringify(JSON.parse(text),null,2);}catch(e){return null;}
-}
-function hexDump(bytes){
- var lines=[];
- for(var i=0;i=32&&b<127?String.fromCharCode(b):'.';}).join('');
- lines.push(i.toString(16).padStart(8,'0')+' '+hex.padEnd(48)+' '+asc);
- }
- return lines.join('\n');
-}
-function copyBody(){
- if(!detailFull)return;
- var b64=detailTab==='res'?detailFull.resBody:detailFull.reqBody;
- if(!b64)return;
- if(b64.endsWith('==TRUNCATED=='))b64=b64.slice(0,b64.length-13);
- var text=tryUtf8(b64ToBytes(b64))||b64;
- navigator.clipboard&&navigator.clipboard.writeText(text);
-}
-function closeDetail(){
- detailId=null;
- detailFull=null;
- q('detail').style.display='none';
- q('ne').querySelectorAll('.net-row').forEach(function(r){r.classList.remove('selected');});
-}
-// ---- Shared ----
function filter(listId,filterId){
var f=q(filterId).value.toLowerCase();
q(listId).querySelectorAll('.log-row').forEach(function(el){