1import{n as e,t}from"./hydrate.js";import{t as n}from"./performanceMetricsStore.js";import{useState as r}from"https://assets.finn.no/npm/react/v19/react.production.min.js";var i=e();function a({sessions:e,onSessionsChange:t}){let[a,o]=r(``),[s,c]=r(``),l=e=>{confirm(`Are you sure you want to delete this session?`)&&(n.deleteSession(e),t())},u=e=>{let t=n.exportSession(e),r=new Blob([t],{type:`application/json`}),i=URL.createObjectURL(r),a=document.createElement(`a`);a.href=i,a.download=`performance-metrics-${e}.json`,a.click(),URL.revokeObjectURL(i)},d=()=>{let e=n.exportAllSessions(),t=new Blob([e],{type:`application/json`}),r=URL.createObjectURL(t),i=document.createElement(`a`);i.href=r,i.download=`performance-metrics-all-sessions.json`,i.click(),URL.revokeObjectURL(r)},f=()=>{confirm(`Are you sure you want to clear all saved sessions?`)&&(n.clearAllSessions(),t())},p=a&&s?n.compareSessions(a,s):{};return(0,i.jsxs)(`div`,{className:`space-y-24`,children:[e.length>=2&&(0,i.jsxs)(`div`,{className:`s-bg-info-subtle s-border-info rounded-8 p-16`,children:[(0,i.jsx)(`h3`,{className:`font-semibold text-18 s-text mb-16`,children:`Compare Sessions`}),(0,i.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-16 mb-16`,children:[(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`label`,{className:`block text-14 font-medium s-text mb-8`,children:`Session 1 (baseline)`}),(0,i.jsxs)(`select`,{value:a,onChange:e=>o(e.target.value),className:`w-full s-border rounded-8 px-12 py-8 text-14 s-text s-bg`,children:[(0,i.jsx)(`option`,{value:``,children:`Select session...`}),e.map(e=>(0,i.jsxs)(`option`,{value:e.id,children:[e.label,` - `,new Date(e.timestamp).toLocaleString()]},e.id))]})]}),(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`label`,{className:`block text-14 font-medium s-text mb-8`,children:`Session 2 (compare to)`}),(0,i.jsxs)(`select`,{value:s,onChange:e=>c(e.target.value),className:`w-full s-border rounded-8 px-12 py-8 text-14 s-text s-bg`,children:[(0,i.jsx)(`option`,{value:``,children:`Select session...`}),e.map(e=>(0,i.jsxs)(`option`,{value:e.id,children:[e.label,` - `,new Date(e.timestamp).toLocaleString()]},e.id))]})]})]}),Object.keys(p).length>0&&(0,i.jsxs)(`div`,{className:`s-bg rounded-8 p-16`,children:[(0,i.jsx)(`h4`,{className:`font-medium text-16 s-text mb-12`,children:`Differences`}),(0,i.jsx)(`div`,{className:`space-y-8`,children:Object.entries(p).map(([e,t])=>(0,i.jsxs)(`div`,{className:`flex justify-between items-center text-14`,children:[(0,i.jsx)(`span`,{className:`font-medium s-text`,children:e}),(0,i.jsxs)(`span`,{className:`font-mono ${t<0?`s-text-positive`:t>0?`s-text-negative`:`s-text-subtle`}`,children:[t>0?`+`:``,t.toFixed(2),`ms`,t<0&&` â¬ï¸`,t>0&&` â¬ï¸`]})]},e))})]})]}),(0,i.jsxs)(`div`,{children:[(0,i.jsxs)(`div`,{className:`flex justify-between items-center mb-16`,children:[(0,i.jsxs)(`h3`,{className:`font-semibold text-18 s-text`,children:[`Saved Sessions (`,e.length,`)`]}),(0,i.jsxs)(`div`,{className:`flex gap-8`,children:[(0,i.jsx)(`w-button`,{variant:`primary`,onClick:d,children:`ð¥ Export All`}),(0,i.jsx)(`w-button`,{variant:`negative`,onClick:f,children:`ðï¸ Clear All`})]})]}),e.length===0?(0,i.jsxs)(`div`,{className:`text-center py-48 s-bg-subtle rounded-8`,children:[(0,i.jsx)(`p`,{className:`s-text-subtle text-16`,children:`No saved sessions yet.`}),(0,i.jsx)(`p`,{className:`text-14 s-text-disabled mt-8`,children:`Sessions are automatically saved after page load when the Performance Observer is active.`})]}):(0,i.jsx)(`div`,{className:`space-y-12`,children:e.map(e=>(0,i.jsxs)(`div`,{className:`s-bg s-border rounded-8 p-16`,children:[(0,i.jsxs)(`div`,{className:`flex justify-between items-start mb-12`,children:[(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`h4`,{className:`font-semibold text-16 s-text`,children:e.label}),(0,i.jsx)(`p`,{className:`text-14 s-text-subtle`,children:new Date(e.timestamp).toLocaleString()}),(0,i.jsx)(`p`,{className:`text-12 s-text-disabled truncate max-w-md`,children:e.url})]}),(0,i.jsxs)(`div`,{className:`flex gap-8`,children:[(0,i.jsx)(`w-button`,{variant:`secondary`,onClick:()=>u(e.id),children:`ð¥ Export`}),(0,i.jsx)(`w-button`,{variant:`negative`,onClick:()=>l(e.id),children:`ðï¸`})]})]}),(0,i.jsx)(`div`,{className:`grid grid-cols-2 md:grid-cols-4 gap-12`,children:[`LCP`,`INP`,`CLS`,`TTFB`].map(t=>{let n=e.metrics.find(e=>e.name===t);return n?(0,i.jsxs)(`div`,{className:`s-bg-subtle px-12 py-8 rounded-8`,children:[(0,i.jsx)(`div`,{className:`text-12 s-text-subtle`,children:t}),(0,i.jsxs)(`div`,{className:`font-mono font-semibold text-14 ${n.rating===`good`?`s-text-positive`:n.rating===`needs-improvement`?`s-text-warning`:n.rating===`poor`?`s-text-negative`:`s-text`}`,children:[n.value.toFixed(2),`ms`]})]},t):null})})]},e.id))})]})]})}function o(){let[e,t]=r(()=>typeof window<`u`?n.getAllSessions():[]),[o,s]=r(0),c=()=>{t(n.getAllSessions()),s(e=>e+1)};return(0,i.jsxs)(`div`,{className:`s-bg rounded-8 shadow-sm s-border p-24`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between mb-24`,children:[(0,i.jsx)(`h2`,{className:`text-20 font-semibold s-text`,children:`Historical Sessions`}),(0,i.jsx)(`w-button`,{variant:`secondary`,onClick:c,children:`ð Refresh`})]}),(0,i.jsx)(a,{sessions:e,onSessionsChange:c},o)]})}t(`performance-dashboard-full-island`,()=>(0,i.jsx)(o,{}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.