const CACHE='character-shell-v2'; async function cacheShell(){ const r=await fetch('/',{credentials:'same-origin',redirect:'manual'}); if(!r.ok||r.redirected||!r.headers.get('content-type')?.includes('text/html'))return; const html=await r.clone().text(),cache=await caches.open(CACHE); await cache.put('/',r); const urls=new Set([...html.matchAll(/(?:src|href)="(\/assets\/[^" ]+)"/g)].map(match=>match[1])); try{ const manifest=await fetch('/assets/ui-manifest.json',{cache:'no-store'}); if(manifest.ok){for(const path of await manifest.json())if(typeof path==='string'&&path.startsWith('/assets/'))urls.add(path)} }catch{} await Promise.all([...urls].map(async path=>{const response=await fetch(path);if(response.ok&&!response.redirected)await cache.put(path,response)})); } self.addEventListener('install',e=>e.waitUntil(self.skipWaiting())); self.addEventListener('activate',e=>e.waitUntil((async()=>{ for(const key of await caches.keys())if(key.startsWith('character-shell-')&&key!==CACHE)await caches.delete(key); await self.clients.claim();try{await cacheShell()}catch{} })())); self.addEventListener('message',e=>{ if(e.data==='CLEAR_AUTH')e.waitUntil(caches.delete(CACHE)); if(e.data==='CACHE_SHELL')e.waitUntil(cacheShell()); }); self.addEventListener('fetch',e=>{ const url=new URL(e.request.url); if(url.origin!==self.location.origin||e.request.method!=='GET'||url.pathname.startsWith('/api/')||url.pathname.startsWith('/auth/'))return; if(e.request.mode==='navigate'&&url.pathname==='/'){ e.respondWith((async()=>{ try{const r=await fetch(e.request);if(r.ok&&!r.redirected&&r.headers.get('content-type')?.includes('text/html'))await(await caches.open(CACHE)).put('/',r.clone());return r} catch{return await caches.match('/')||new Response('Connect to the internet to sign in.',{status:503})} })());return; } if(url.pathname.startsWith('/assets/'))e.respondWith((async()=>{ const hit=await caches.match(e.request);if(hit)return hit; const r=await fetch(e.request);if(r.ok&&!r.redirected)await(await caches.open(CACHE)).put(e.request,r.clone());return r; })()); });