import{ar as q,af as ct,ag as ut,aI as mt,ac as pt,aG as ht,ae as gt,aL as ft,ad as xt,aK as bt,aT as t,V as j,i as ke,d as kt,R as me,a9 as Ke,J as vt,aq as $,a5 as W,aY as k,f as Z,j as Be,ab as wt,e as We,y as yt,N as le,a7 as jt,S as Nt,c as J,b3 as St,b8 as $t,v as ve,n as Tt,l as Et,s as Ct,bc as Rt,a_ as He,az as It,aA as At,x as Ge,a2 as we,p as Ot,Q as L,aD as de,b as ye,O as ce,aE as K,b9 as F,t as Je,q as Pt}from"./chunk-02oqS8tD.js";import{I as Lt,a as Mt}from"./chunk-BFW-JOq_.js";import{C as _t,S as Ut}from"./chunk-nlio5-IT.js";import{aR as pe,v as je,aC as qt,aH as Ne,aK as Vt,aI as zt,W as Dt,ad as Ft,b4 as Kt}from"./chunk-B8Q4vgLh.js";import{c as Bt,d as ue,s as Wt}from"./chunk-Cd_gpmCR.js";import{readTelemetrySignals as Ht}from"./chunk-ngFx90MH.js";import{a as Gt}from"./chunk-SwRI5DNY.js";import{J as he}from"./chunk-C73D8OYP.js";import{A as Ze,a as Jt}from"./chunk-CA0oL9aL.js";import{C as ee}from"./chunk-DATNr2Vu.js";import{M as Qe}from"./chunk-BPRhG5Pu.js";import{M as Zt,o as Qt}from"./chunk-Dp5WJOsV.js";import{comparePerformance as Yt}from"./chunk-BgfJmpf-.js";import{R as Ye,D as Y}from"./chunk-x_Z6cwvR.js";import{C as Xt}from"./chunk-D4UWVV5_.js";import"./chunk-CoYD1fGq.js";/**
 * @license lucide-react v0.451.0 - ISC
 *
 * This source code is licensed under the ISC license.
 * See the LICENSE file in the root directory of this source tree.
 */const es=q("CloudOff",[["path",{d:"m2 2 20 20",key:"1ooewy"}],["path",{d:"M5.782 5.782A7 7 0 0 0 9 19h8.5a4.5 4.5 0 0 0 1.307-.193",key:"yfwify"}],["path",{d:"M21.532 16.5A4.5 4.5 0 0 0 17.5 10h-1.79A7.008 7.008 0 0 0 10 5.07",key:"jlfiyv"}]]);/**
 * @license lucide-react v0.451.0 - ISC
 *
 * This source code is licensed under the ISC license.
 * See the LICENSE file in the root directory of this source tree.
 */const ts=q("Equal",[["line",{x1:"5",x2:"19",y1:"9",y2:"9",key:"1nwqeh"}],["line",{x1:"5",x2:"19",y1:"15",y2:"15",key:"g8yjpy"}]]);/**
 * @license lucide-react v0.451.0 - ISC
 *
 * This source code is licensed under the ISC license.
 * See the LICENSE file in the root directory of this source tree.
 */const ss=q("FileJson",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1",key:"1oajmo"}],["path",{d:"M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1",key:"mpwhp6"}]]);/**
 * @license lucide-react v0.451.0 - ISC
 *
 * This source code is licensed under the ISC license.
 * See the LICENSE file in the root directory of this source tree.
 */const rs=q("Flag",[["path",{d:"M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z",key:"i9b6wo"}],["line",{x1:"4",x2:"4",y1:"22",y2:"15",key:"1cm3nv"}]]);/**
 * @license lucide-react v0.451.0 - ISC
 *
 * This source code is licensed under the ISC license.
 * See the LICENSE file in the root directory of this source tree.
 */const Xe=q("GitCompare",[["circle",{cx:"18",cy:"18",r:"3",key:"1xkwt0"}],["circle",{cx:"6",cy:"6",r:"3",key:"1lh9wr"}],["path",{d:"M13 6h3a2 2 0 0 1 2 2v7",key:"1yeb86"}],["path",{d:"M11 18H8a2 2 0 0 1-2-2V9",key:"19pyzm"}]]);/**
 * @license lucide-react v0.451.0 - ISC
 *
 * This source code is licensed under the ISC license.
 * See the LICENSE file in the root directory of this source tree.
 */const ns=q("Share2",[["circle",{cx:"18",cy:"5",r:"3",key:"gq8acd"}],["circle",{cx:"6",cy:"12",r:"3",key:"w7nqdw"}],["circle",{cx:"18",cy:"19",r:"3",key:"1xt0gg"}],["line",{x1:"8.59",x2:"15.42",y1:"13.51",y2:"17.49",key:"47mynk"}],["line",{x1:"15.41",x2:"8.59",y1:"6.51",y2:"10.49",key:"1n3mei"}]]);/**
 * @license lucide-react v0.451.0 - ISC
 *
 * This source code is licensed under the ISC license.
 * See the LICENSE file in the root directory of this source tree.
 */const as=q("ShieldQuestion",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"M9.1 9a3 3 0 0 1 5.82 1c0 2-3 3-3 3",key:"mhlwft"}],["path",{d:"M12 17h.01",key:"p32p05"}]]);/**
 * @license lucide-react v0.451.0 - ISC
 *
 * This source code is licensed under the ISC license.
 * See the LICENSE file in the root directory of this source tree.
 */const et=q("Terminal",[["polyline",{points:"4 17 10 11 4 5",key:"akl6gq"}],["line",{x1:"12",x2:"20",y1:"19",y2:"19",key:"q2wloq"}]]);/**
 * @license lucide-react v0.451.0 - ISC
 *
 * This source code is licensed under the ISC license.
 * See the LICENSE file in the root directory of this source tree.
 */const os=q("Waypoints",[["circle",{cx:"12",cy:"4.5",r:"2.5",key:"r5ysbb"}],["path",{d:"m10.2 6.3-3.9 3.9",key:"1nzqf6"}],["circle",{cx:"4.5",cy:"12",r:"2.5",key:"jydg6v"}],["path",{d:"M7 12h10",key:"b7w52i"}],["circle",{cx:"19.5",cy:"12",r:"2.5",key:"1piiel"}],["path",{d:"m13.8 17.7 3.9-3.9",key:"1wyg1y"}],["circle",{cx:"12",cy:"19.5",r:"2.5",key:"13o1pw"}]]);function Se(e){return/^(\d+)/.exec(e.trim())?.[1]??e.trim()}function is(e){try{return new URL(e).origin}catch{return e.includes("?")?"unparseable-url":e}}const $e=e=>e.toFixed(3);function ls(e){let s=2166136261;for(let r=0;r<e.length;r+=1)s^=e.charCodeAt(r),s=Math.imul(s,16777619)>>>0;return s.toString(16).padStart(8,"0")}function B(e){const s=[],r=[],n=(l,c,p)=>{s.push({key:l,label:c,value:p})},o=(l,c)=>{r.push({key:l,reason:c})};if(e.url?n("origin","Origin",is(e.url)):o("origin","The snapshot recorded no URL, so the application under test is unknown."),e.appVersion?n("appVersion","App version",e.appVersion):o("appVersion","No version marker was found on the page. The application may not publish one, or the read may have failed — those are not distinguishable, so this cannot be part of an identity."),e.device?(n("browser","Browser",`${e.device.browser} ${Se(e.device.browserVersion)}`),n("os","Operating system",`${e.device.os} ${Se(e.device.osVersion)}`),n("screen","Screen",`${String(e.device.resolution.width)}x${String(e.device.resolution.height)}@${String(e.device.devicePixelRatio)}`),n("locale","Locale",`${e.device.language}/${e.device.timezone}`)):o("browser","The snapshot did not record a browser description."),n("viewport","Viewport",e.viewport?`${e.viewport.profileId}:${String(e.viewport.width)}x${String(e.viewport.height)}${e.viewport.rotate?":rotated":""}`:"not-emulated"),e.network){const l=e.network;n("network","Network",l.offline?"offline":`${l.presetId}:${String(l.latencyMs)}ms:${String(l.downloadKbps)}/${String(l.uploadKbps)}kbps`),l.packetLoss>0&&(n("network.lossRequested","Packet loss requested",`${String(l.packetLoss)}%`),o("network.lossEnforced","Chrome accepts the packet-loss parameter without reporting whether it is enforced, so whether two executions really experienced the same loss cannot be part of their identity."))}else n("network","Network","browser-default");n("geo","Location",e.geo?`${$e(e.geo.latitude)},${$e(e.geo.longitude)}:${e.geo.permission}`:"not-overridden");const m=Object.entries(e.permissions??{}).filter(([,l])=>l!==void 0).sort(([l],[c])=>l.localeCompare(c)).map(([l,c])=>`${l}=${String(c)}`);n("permissions","Permissions",m.length===0?"none-set":m.join(","));const d=[...e.rules??[]].map(l=>`${l.name}|${l.action}|${l.match}`).sort((l,c)=>l.localeCompare(c));n("rules","Network rules",d.length===0?"none-armed":d.join(";")),e.state&&o("state",'Storage and cookie counts change on their own — a session refresh or one analytics write moves them without changing the conditions under test — so hashing them would put every execution in its own group and make "same environment" undecidable. The values themselves are never recorded.');const a=s.map(l=>`${l.key}=${l.value}`).join(`
`);return{hash:ls(a),dimensions:s,omitted:r,complete:r.length===0}}function tt(e,s){const r=new Set(e.dimensions.map(a=>a.key)),n=new Set(s.dimensions.map(a=>a.key)),o=[...[...r].filter(a=>!n.has(a)),...[...n].filter(a=>!r.has(a))].sort((a,l)=>a.localeCompare(l));if(o.length>0)return{verdict:"incomparable",changed:[],asymmetric:o,summary:`These two environments were recorded with different information (${o.join(", ")}), so they cannot be compared by identity. Use the full comparison instead.`};if(e.hash===s.hash){const a=e.complete&&s.complete;return{verdict:a?"identical":"equivalent-where-measured",changed:[],asymmetric:[],summary:a?"Same environment on every dimension a snapshot can record.":`Same environment on everything measured. ${String(Math.max(e.omitted.length,s.omitted.length))} dimension${Math.max(e.omitted.length,s.omitted.length)===1?"":"s"} could not be measured and may still differ.`}}const m=new Map(s.dimensions.map(a=>[a.key,a.value])),d=e.dimensions.filter(a=>m.get(a.key)!==a.value).map(a=>a.key);return{verdict:"different",changed:d,asymmetric:[],summary:`Different environment: ${d.join(", ")}.`}}async function st(e){const s=[];if(e.state&&(e.state.cookies>0||e.state.localStorageKeys>0)&&s.push({key:"state",label:"Application state",verdict:"cannot",note:`The snapshot records ${String(e.state.cookies)} cookies and ${String(e.state.localStorageKeys)} storage keys but never their values — that is deliberate, because a snapshot ends up in bug reports. Sign in as the same user, or apply a saved cookie set from the Cookies screen.`}),e.viewport&&s.push({key:"viewport",label:`Viewport ${String(e.viewport.width)} × ${String(e.viewport.height)}`,verdict:"will-apply"}),e.network&&e.network.presetId!=="online"){const r=e.network.packetLoss>0&&e.network.packetLossStatus==="rejected";s.push({key:"network",label:`Network ${e.network.offline?"offline":e.network.presetId.toUpperCase()}`,verdict:r?"partial":"will-apply",...r?{note:"Latency and bandwidth will be applied. The packet-loss setting was refused by this browser when the snapshot was taken and will be refused again."}:{}})}if(e.geo&&s.push({key:"geo",label:`Location ${e.geo.label}`,verdict:"will-apply"}),e.permissions&&Object.keys(e.permissions).length>0&&s.push({key:"permissions",label:`${String(Object.keys(e.permissions).length)} browser permissions`,verdict:"will-apply"}),e.rules&&e.rules.length>0){const r=await pe.list(),n=new Set(e.rules.map(m=>m.name)),o=r.filter(m=>n.has(m.name));s.push({key:"rules",label:`${String(e.rules.length)} network rule${e.rules.length===1?"":"s"}`,verdict:o.length===e.rules.length?"will-apply":o.length===0?"cannot":"partial",...o.length===e.rules.length?{}:{note:o.length===0?`None of these rules exist locally any more (${e.rules.map(m=>m.name).join(", ")}). Recreate them on the Network rules screen — the snapshot records what each one did.`:`${String(o.length)} of ${String(e.rules.length)} rules were found by name. The missing ones were renamed or deleted.`}})}return e.device&&s.push({key:"browser",label:`${e.device.browser} ${e.device.browserVersion} on ${e.device.os}`,verdict:"cannot",note:"Nothing can change the browser or OS you are running. If the failure is version-specific, this reproduction will not show it."}),e.appVersion&&s.push({key:"app-version",label:`App version ${e.appVersion}`,verdict:"cannot",note:"The application build is decided by whatever is deployed, not by the browser. Check that the environment you are testing is still on this build."}),e.url?s.push({key:"navigate",label:`Open ${e.url}`,verdict:"will-apply"}):s.push({key:"navigate",label:"Open the page",verdict:"cannot",note:"The snapshot recorded no URL, so there is no page to return to."}),{steps:s,actionable:s.some(r=>r.verdict==="will-apply"||r.verdict==="partial")}}const Te=12e3;async function ds(e){try{const[s]=await chrome.scripting.executeScript({target:{tabId:e},func:()=>({width:document.documentElement.clientWidth,height:document.documentElement.clientHeight})});return s?.result??null}catch{return null}}async function Ee(){try{return(await chrome.tabs.query({active:!0,windowType:"normal"}))[0]??null}catch{return null}}async function cs(e,s){const r=Date.now()+s;for(;Date.now()<r;){try{if((await chrome.tabs.get(e)).status==="complete")return!0}catch{return!1}await new Promise(n=>setTimeout(n,250))}return!1}async function us(e,s={}){const r=[],n=await st(e),o=i=>{r.push(i)},m=async(i,h,T)=>{try{o(await T())}catch(b){o({key:i,label:h,status:"failed",reason:b.message})}},d=await ms(e,s.cookieProfileId);if(d?await m("cookies",`Cookie set “${d.name}”`,async()=>{const i=await Gt(d);if(i.total===0)return{key:"cookies",label:`Cookie set “${d.name}”`,status:"skipped",reason:"That set contains no cookies."};const h=i.applied===i.total;return{key:"cookies",label:`Cookie set “${d.name}”`,status:h?"applied":i.applied===0?"failed":"partial",detail:`${String(i.applied)} of ${String(i.total)} cookies`,...h?{}:{reason:i.applied===0?`Chrome refused every cookie in that set. ${i.firstProblem??"They may all have expired — which is what an “Expired session” set is for."}`:`Chrome refused ${String(i.total-i.applied)}. ${i.firstProblem??"The usual cause is an expiry date in the past."}`},verification:{method:"counted",expected:`${String(i.total)} cookies`,observed:`${String(i.applied)} accepted`,matched:h}}}):e.state&&e.state.cookies>0&&o({key:"cookies",label:"Session and application state",status:"unsupported",reason:`The snapshot records ${String(e.state.cookies)} cookies and ${String(e.state.localStorageKeys)} storage keys but never their values — that is deliberate, because a snapshot ends up in bug reports. Save a cookie set on the Cookies screen and it can be restored here; otherwise sign in as the same user first.`}),e.viewport){const i=`${String(e.viewport.width)} × ${String(e.viewport.height)}`;await m("viewport",`Viewport ${i}`,async()=>{const h=await ct(e.viewport.profileId,e.viewport.rotate);if("error"in h)throw new Error(h.error);const T=await Ee(),b=T?.id==null?null:await ds(T.id);if(!b)return{key:"viewport",label:`Viewport ${i}`,status:"unverifiable",reason:"The override was accepted, but this page cannot be measured from the extension (a browser page, a PDF, or a navigation in flight), so we cannot confirm it took effect."};const v=b.width===e.viewport.width;return{key:"viewport",label:`Viewport ${i}`,status:v?"applied":"partial",...v?{}:{reason:`The page reports a layout width of ${String(b.width)} px, not ${String(e.viewport.width)} px. Another debugger may hold the tab, or the window is too narrow to render this viewport unscaled.`},verification:{method:"measured-in-page",expected:`${String(e.viewport.width)} px layout width`,observed:`${String(b.width)} px`,matched:v}}})}if(e.rules&&e.rules.length>0){const i=e.rules.length,h=`${String(i)} network rule${i===1?"":"s"}`;await m("rules",h,async()=>{const T=await pe.list(),b=new Set(e.rules.map(C=>C.name)),v=T.filter(C=>b.has(C.name)).map(C=>({...C,enabled:!0}));if(v.length===0)return{key:"rules",label:h,status:"failed",reason:`None of these rules exist locally any more (${e.rules.map(C=>C.name).join(", ")}). Recreate them on the Network rules screen — the snapshot records what each one did.`};const E=await ut(v);if(!E.ok)throw new Error(E.error);const I=await mt(),O=new Set((I?.rules??[]).map(C=>C.name)),P=[...b].filter(C=>O.has(C)),M=P.length===i;return{key:"rules",label:h,status:M?"applied":P.length===0?"failed":"partial",detail:`${String(P.length)} of ${String(i)} armed`,...M?{}:{reason:`${String(i-P.length)} of these rules could not be armed — they were renamed, deleted, or their match pattern no longer compiles. Missing: ${[...b].filter(C=>!O.has(C)).join(", ")}.`},verification:{method:"read-back",expected:`${String(i)} rules armed`,observed:`${String(P.length)} armed`,matched:M}}})}if(e.geo){const i=`Location ${e.geo.label}`;await m("geo",i,async()=>{const h=await pt(e.geo);if(!h.ok)throw new Error(h.error);const b=(await ht())?.geo,v=b!==void 0&&Math.abs(b.latitude-e.geo.latitude)<5e-4&&Math.abs(b.longitude-e.geo.longitude)<5e-4;return{key:"geo",label:i,status:v?"applied":"unverifiable",...v?{}:{reason:"The override was accepted but the background does not report it back — most often because another debugger took the tab. The page may still be reading its real location."},verification:{method:"read-back",expected:`${e.geo.latitude.toFixed(4)}, ${e.geo.longitude.toFixed(4)}`,observed:b?`${b.latitude.toFixed(4)}, ${b.longitude.toFixed(4)}`:"not reported",matched:v}}})}if(e.permissions&&Object.keys(e.permissions).length>0){const i=Object.entries(e.permissions).filter(([,T])=>T!==void 0),h=`${String(i.length)} browser permission${i.length===1?"":"s"}`;await m("permissions",h,async()=>{const T=await gt(e.permissions);if(!T.ok)throw new Error(T.error);const{effective:b}=await ft(),v=i.filter(([I,O])=>b[I]===O),E=v.length===i.length;return{key:"permissions",label:h,status:E?"applied":v.length===0?"failed":"partial",detail:`${String(v.length)} of ${String(i.length)} confirmed by Chrome`,...E?{}:{reason:`Chrome reports a different decision for ${i.filter(([I,O])=>b[I]!==O).map(([I])=>I).join(", ")}. A site setting changed by hand in Chrome's own UI wins over ours.`},verification:{method:"read-back",expected:i.map(([I,O])=>`${I}=${String(O)}`).join(", "),observed:Object.entries(b).map(([I,O])=>`${I}=${String(O)}`).join(", ")||"none set",matched:E}}})}if(e.network&&e.network.presetId!=="online"){const i=`Network ${e.network.offline?"offline":e.network.presetId.toUpperCase()}`;await m("network",i,async()=>{const h=await xt({presetId:e.network.presetId,offline:e.network.offline,latencyMs:e.network.latencyMs,downloadKbps:e.network.downloadKbps,uploadKbps:e.network.uploadKbps,packetLoss:e.network.packetLoss});if(!h.ok)throw new Error(h.error);const b=(await bt())?.conditions,v=b!==void 0&&b.latencyMs===e.network.latencyMs&&b.downloadKbps===e.network.downloadKbps&&b.offline===e.network.offline,E=e.network.packetLoss>0;return{key:"network",label:i,status:v?E?"unverifiable":"applied":"unverifiable",...v&&!E?{}:{reason:v?`Latency and bandwidth were re-applied and confirmed. The ${String(e.network.packetLoss)}% packet loss cannot be confirmed: Chrome accepts the parameter without reporting whether it enforces it.`:"The conditions were accepted but the background does not report them back — most often because another debugger took the tab."},verification:{method:"read-back",expected:`${String(e.network.latencyMs)} ms / ${String(e.network.downloadKbps)} kbps`,observed:b?`${String(b.latencyMs)} ms / ${String(b.downloadKbps)} kbps`:"not reported",matched:v}}})}let a=!1,l=null;if(e.url){const i=`Open ${e.url}`;await m("navigate",i,async()=>{const h=await Ee();if(h?.id==null)throw new Error("there is no browser tab to navigate");l=h.id,await chrome.tabs.update(h.id,{url:e.url,active:!0}),a=await cs(h.id,s.settleMs??Te);const b=(await chrome.tabs.get(h.id).catch(()=>null))?.url??"unknown",v=ps(e.url,b);return{key:"navigate",label:i,status:v?"applied":a?"partial":"unverifiable",...v?{}:{reason:a?`The tab ended up at ${b}. A redirect — a sign-in wall, a locale route — took it somewhere else, so the page under test is not the one the snapshot recorded.`:`The page had not finished loading after ${String(Math.round((s.settleMs??Te)/1e3))} s. Under the throttling this reproduction applied that can be normal; check the tab.`},verification:{method:"read-back",expected:e.url,observed:b,matched:v}}})}else o({key:"navigate",label:"Open the page",status:"unsupported",reason:"The snapshot recorded no URL, so there is no page to return to."});let c=null,p=null;if(e.url===void 0||a||l===null)try{p=await Bt({});const i=B(e),h=B(p);c={original:i.hash,current:h.hash,comparison:tt(i,h)}}catch{}const S=(i,h)=>B(i).dimensions.find(T=>T.key===h)?.value;if(e.device){const i=`${e.device.browser} ${e.device.browserVersion} on ${e.device.os}`,h=`${S(e,"browser")??"?"} / ${S(e,"os")??"?"}`,T=p?S(p,"browser"):void 0,b=p?S(p,"os"):void 0,v=T!==void 0&&b!==void 0?`${T} / ${b}`:null,E=v!==null&&v===h;o({key:"browser",label:i,status:v===null?"unverifiable":E?"applied":"unsupported",...E?{}:{reason:v===null?"The browser could not be re-read, so whether you are on the same version as the original run is unconfirmed.":`You are on ${v}, and this failure was recorded on ${h}. Nothing can change the browser or OS you are running — if the failure is version-specific, this reproduction will not show it.`},verification:{method:"read-back",expected:h,observed:v??"not re-read",matched:E}})}if(e.appVersion){const i=p?.appVersion,h=i!==void 0&&i===e.appVersion;o({key:"app-version",label:`App version ${e.appVersion}`,status:i===void 0?"unverifiable":h?"applied":"unsupported",...h?{}:{reason:i===void 0?"The page no longer publishes a version marker, so we cannot confirm this environment is still on the build the failure was recorded against.":`This environment is now on ${i}, and the failure was recorded against ${e.appVersion}. The application build is decided by what is deployed, not by the browser — the code that failed may no longer be there.`},verification:{method:"read-back",expected:e.appVersion,observed:i??"no version marker",matched:h}})}const w=r.filter(i=>i.status==="applied").length,f=r.filter(i=>i.status!=="applied"&&i.status!=="skipped").length,y=r.every(i=>i.status==="applied"||i.status==="skipped"),u=r.every(i=>i.verification===void 0||i.verification.matched),g=c!==null&&(c.comparison.verdict==="identical"||c.comparison.verdict==="equivalent-where-measured"),N=y&&u&&g;return{entries:r,appliedCount:w,unrestoredCount:f,faithful:N,headline:hs(r,N,c),fingerprint:c,notReproduced:n.steps.filter(i=>i.verdict==="cannot"||i.verdict==="partial")}}async function ms(e,s){if(s!==void 0)return await je.get(s)??null;if(e.profile===void 0)return null;const r=await qt.get(e.profile.id);return r?.cookieProfileId?await je.get(r.cookieProfileId)??null:null}function ps(e,s){try{const r=new URL(e),n=new URL(s);return r.origin===n.origin&&r.pathname===n.pathname}catch{return e===s}}function hs(e,s,r){if(e.length===0)return"There was nothing in this snapshot to restore.";const n=e.filter(m=>m.status==="unsupported").length,o=e.filter(m=>m.status==="failed"||m.status==="partial"||m.status==="unverifiable").length;return s?r?.comparison.verdict==="identical"?"Environment restored exactly — every condition was re-applied and confirmed.":"Environment restored and confirmed on every dimension that can be measured. Some cannot be measured and may still differ.":o===0&&n>0?`Every condition that can be re-applied was restored and confirmed. ${String(n)} cannot be recreated from a browser — see below.`:o===0?"Conditions re-applied, but the environment could not be confirmed as a whole. Check the entries below before trusting this reproduction.":`${String(o)} condition${o===1?"":"s"} could not be restored or confirmed. This is not the original environment — check the entries below before judging whether the failure is real.`}function gs(e,s,r,n){const o=s.filter(i=>i.severity==="error"),m=o[0],d=m?`${e.title} — ${G(m.message,90)}`:e.summary?`${e.title} — ${G(e.summary,90)}`:e.title,a=e.error??e.summary??(m?m.message:`The ${e.kind.replace(/-/g," ")} check completed with status ${e.status}.`),l=[];if(e.snapshot){const i=ue(e.snapshot).filter(h=>h!==e.snapshot?.url);i.length>0&&l.push(`Set up the environment: ${i.join("; ")}`),e.snapshot.url&&l.push(`Open ${e.snapshot.url}`)}for(const i of s)fs.has(i.type)&&l.push(G(i.message,140));l.length===0&&l.push(`Run the ${e.kind.replace(/-/g," ")} check on the page.`);const{expected:c,actual:p}=xs(e,o),S=e.snapshot?ue(e.snapshot):["No environment snapshot was captured."],w=r.map(i=>i.signedUrl).filter(i=>i!==void 0),f=r.filter(i=>i.problem!==void 0),y=[...new Set((n?.requests??[]).filter(i=>i.failed||i.status>=400).map(i=>i.traceId).filter(i=>i!==void 0))],u=n?.consoleErrors.slice(0,8)??[],g=n?.failedRequests.slice(0,8)??[],N=["## Summary",a,"","## Steps to reproduce",...l.map((i,h)=>`${String(h+1)}. ${i}`),"","## Expected result",c,"","## Actual result",p,"","## Environment",...S.map(i=>`- ${i}`),"",...u.length>0?["## Console errors",...u.map(i=>`- \`${G(i.message,200)}\``),""]:[],...g.length>0?["## Failed requests",...g.map(i=>`- ${i.method} ${i.url} → ${String(i.status)}`),""]:[],...n!==void 0&&!n.capturing?["## Console and network","_Application telemetry capture was off during this run, so no console or network activity was recorded._",""]:[],...y.length>0?["## Trace ids",...y.map(i=>`- \`${i}\``),""]:[],...w.length>0?["## Evidence",...w.map(i=>`- ${i}`),""]:[],...f.length>0?[`_${String(f.length)} evidence item${f.length===1?"":"s"} could not be stored: ${f[0]?.problem??"unknown reason"}._`,""]:[],"## Reference",`- Execution id: \`${e.id}\``,`- Tool: ${e.kind}`,`- Ran at: ${new Date(e.startedAt).toISOString()}`,...e.context?.testRunId?[`- Test run: \`${e.context.testRunId}\``]:[],...e.context?.testCaseId?[`- Test case: \`${e.context.testCaseId}\``]:[]].join(`
`);return{title:d,body:N,fields:{summary:a,stepsToReproduce:l,expected:c,actual:p,environment:S,evidenceUrls:w,traceIds:y,executionId:e.id},...e.context?.testRunId?{linkedContext:e.context}:{}}}const fs=new Set(["STEP_PASSED","STEP_FAILED","ACTION","VIEWPORT_CAPTURED","HUMAN_INTERVENTION_REQUESTED"]);function xs(e,s){const r=s.map(o=>G(o.message,160)),n=r.length>0?r.map(o=>`- ${o}`).join(`
`):e.summary??"See the summary above.";switch(e.kind){case"accessibility":return{expected:"Every image has alternative text, every control has an accessible name, text meets the WCAG 1.4.3 contrast minimum, and the page is navigable by keyboard.",actual:`The scan found:
${n}`};case"responsive":return{expected:"The layout adapts to every tested viewport with no horizontal scrolling, clipped text or undersized tap targets.",actual:`At the tested sizes:
${n}`};case"visual":return{expected:"The page renders identically to the reference image, within the stated pixel tolerance.",actual:e.summary??"The comparison found differences — see the attached diff image."};case"page-quality":return{expected:"Every link and image resolves, every control is labelled, and the console is clean.",actual:`The scan found:
${n}`};case"workflow-replay":return{expected:"Every step of the recorded workflow completes and the journey reaches its end state.",actual:`The replay reported:
${n}`};default:return{expected:"The check completes without errors.",actual:n}}}function G(e,s){const r=e.trim().replace(/\s+/g," ");return r.length<=s?r:`${r.slice(0,s)}…`}const bs=2e3,ks=5e3,vs=1500,ws=new Set(["EXECUTION_COMPLETED","EXECUTION_FAILED","EXECUTION_STOPPED"]);function ys(e){return e.type==="EXECUTION_STARTED"?"start":ws.has(e.type)?"outcome":e.type.startsWith("STEP_")||e.type==="HUMAN_INTERVENTION_REQUESTED"?"action":"note"}function oe(e){try{return new URL(e).pathname}catch{const s=e.split("?")[0]??e;return s===""?e:s}}const Ce=e=>e.failed||e.status>=400;function rt(e){const s=[],r=[],n=[],o=new Map;for(const u of e.events){const g={id:`evt:${u.id}`,kind:ys(u),at:u.timestamp,title:u.message,detail:u.type,severity:u.severity==="debug"?"info":u.severity,ref:{source:"event",id:u.id}};s.push(g),o.set(u.id,g)}const m=new Set;for(const u of e.events)for(const g of u.evidenceIds??[])m.add(g);for(const u of e.evidence)s.push({id:`ev:${u.id}`,kind:"evidence",at:u.timestamp,title:u.label,detail:u.type,ref:{source:"evidence",id:u.id}});for(const u of e.events)for(const g of u.evidenceIds??[])e.evidence.some(N=>N.id===g)&&r.push({from:`evt:${u.id}`,to:`ev:${g}`,relation:"captured",basis:"explicit",confidence:"certain",because:"recorded by this event"});for(const u of e.interceptions)s.push({id:`int:${u.id}`,kind:"intercept",at:u.timestamp,title:u.problem?`${u.ruleName} could not be applied`:`${u.ruleName} → ${u.action}`,detail:`${u.method} ${u.url}${u.status===void 0?"":` · ${String(u.status)}`}`,severity:u.problem?"warn":"info",ref:{source:"intercept",id:u.id}});const d=e.signals?.requests??[];(!e.signals||e.signals.capturing!==!0)&&n.push({input:"Network and console",reason:"Telemetry capture was off during this execution, so requests and console errors were never recorded. This is not the same as there having been none."});const a=d.map((u,g)=>{const N=Ce(u);return{id:`req:${String(g)}`,kind:"request",at:u.timestamp,title:`${u.method} ${oe(u.url)}`,detail:u.failed?"no response":`${String(u.status)} · ${String(Math.round(u.duration))} ms`,severity:N?"error":"info",ref:{source:"request",url:u.url,method:u.method}}});s.push(...a);const l=(e.signals?.consoleErrors??[]).map((u,g)=>({id:`con:${String(g)}`,kind:"console",at:u.timestamp,title:u.message,severity:"error"}));s.push(...l);const c=new Map;d.forEach((u,g)=>{u.traceId&&!c.has(u.traceId)&&c.set(u.traceId,g)});for(const[u,g]of c)s.push({id:`trc:${u}`,kind:"trace",at:d[g]?.timestamp??0,title:`Trace ${u.slice(0,12)}…`,detail:"propagated to the backend by the application",ref:{source:"trace",traceId:u}});d.forEach((u,g)=>{u.traceId&&r.push({from:`req:${String(g)}`,to:`trc:${u.traceId}`,relation:"traced-to",basis:"trace-id",confidence:"certain",because:"the request carried this trace id"})});for(const u of e.interceptions){const g=oe(u.url),N=d.map((h,T)=>({request:h,index:T})).filter(({request:h})=>h.method===u.method&&oe(h.url)===g&&Math.abs(h.timestamp-u.timestamp)<=ks);if(N.length===0)continue;const i=N.reduce((h,T)=>Math.abs(h.request.timestamp-u.timestamp)<=Math.abs(T.request.timestamp-u.timestamp)?h:T);r.push({from:`req:${String(i.index)}`,to:`int:${u.id}`,relation:"answered-by",basis:"url-match",confidence:N.length===1?"certain":"likely",because:N.length===1?"a rule acted on this exact request":`a rule acted on one of ${String(N.length)} requests to this path; this is the closest in time`})}const p=[...o.values()].filter(u=>u.kind==="action").sort((u,g)=>u.at-g.at);p.length===0&&d.length>0&&n.push({input:"User actions",reason:"This execution recorded no interaction steps, so requests cannot be attributed to anything the tester did. Requests and console errors are still shown, unlinked."}),d.forEach((u,g)=>{let N;for(const h of p)if(h.at<=u.timestamp)N=h;else break;if(!N)return;const i=u.timestamp-N.at;i>bs||r.push({from:N.id,to:`req:${String(g)}`,relation:"triggered",basis:"time-window",confidence:"likely",because:`started ${String(Math.round(i))} ms after this step`})}),d.forEach((u,g)=>{if(!Ce(u))return;const N=u.timestamp+Math.max(0,u.duration);l.forEach(i=>{i.at<N||i.at-N>vs||r.push({from:`req:${String(g)}`,to:i.id,relation:"raised",basis:"time-window",confidence:"possible",because:`logged ${String(Math.round(i.at-N))} ms after this request failed`})})});const S=[...o.values()].filter(u=>u.kind==="outcome").sort((u,g)=>g.at-u.at)[0],w=e.status==="failed"||e.status==="error"||S?.severity==="error";if(S&&w){const u=s.filter(N=>N.severity==="error"&&N.id!==S.id&&N.at<=S.at).sort((N,i)=>i.at-N.at),g=u[0];g&&r.push({from:g.id,to:S.id,relation:"concluded",basis:"time-window",confidence:u.length===1?"likely":"possible",because:u.length===1?"the only error recorded before the execution ended":`the last of ${String(u.length)} errors recorded before the execution ended`})}s.sort((u,g)=>u.at-g.at);const f=js(S?.id,s,r),y=e.evidence.filter(u=>!m.has(u.id)).length;return y>0&&n.push({input:"Unlinked evidence",reason:`${String(y)} item${y===1?"":"s"} of evidence ${y===1?"was":"were"} captured outside any recorded event, so ${y===1?"it is":"they are"} shown without a cause.`}),{nodes:s,edges:r,chain:f,gaps:n}}const Re={certain:3,likely:2,possible:1};function js(e,s,r){if(e===void 0)return[];const n=new Map(s.map(a=>[a.id,a])),o=[],m=new Set;let d=e;for(;d!==void 0&&!m.has(d);){m.add(d);const a=n.get(d);a&&o.push(a);const l=r.filter(p=>p.to===d&&!m.has(p.from)).filter(p=>p.relation!=="captured"&&p.relation!=="traced-to");if(l.length===0)break;d=l.reduce((p,S)=>{const w=Re[S.confidence]-Re[p.confidence];return w!==0?w>0?S:p:(n.get(S.from)?.at??0)>(n.get(p.from)?.at??0)?S:p}).from}return o.length<2?[]:o.reverse()}function Ns(e,s){return e.edges.filter(r=>r.to===s)}const Ss={start:vt,action:ke,request:Ke,intercept:me,console:et,trace:os,evidence:kt,note:ke,outcome:rs},Ie={certain:{label:"certain",className:"text-foreground"},likely:{label:"likely",className:"text-muted-foreground"},possible:{label:"possible",className:"text-muted-foreground/80 italic"}},$s={triggered:"triggered","answered-by":"was answered by",raised:"raised","traced-to":"was traced to",captured:"captured",concluded:"ended the execution as"};function Ts({graph:e,onOpenNode:s}){const{chain:r,gaps:n}=e;return r.length===0?t.jsxs(j,{title:"Why this happened",children:[t.jsxs("div",{className:"rounded-lg border border-dashed border-stroke px-3 py-4 text-center dark:border-stroke/30",children:[t.jsx("p",{className:"text-[11px] font-medium",children:"No cause could be traced"}),t.jsx("p",{className:"mt-1 text-[10px] leading-relaxed text-muted-foreground",children:"Nothing recorded during this execution links to how it ended. That is normal for a run that passed, and for one where the evidence needed to connect the failure was not captured."})]}),n.length>0&&t.jsx(Ae,{graph:e})]}):t.jsxs(j,{title:"Why this happened",hint:"Each link shows what it was inferred from. Proximity in time is the weakest of them.",children:[t.jsx("div",{children:r.map((o,m)=>{const a=(m===0?[]:Ns(e,o.id).filter(p=>p.from===r[m-1]?.id))[0],l=Ss[o.kind],c=s!==void 0&&o.ref!==void 0;return t.jsxs("div",{children:[a&&t.jsxs("div",{className:"flex items-start gap-1.5 py-1 pl-2.5",children:[t.jsx(Ze,{className:"mt-px h-2.5 w-2.5 shrink-0 text-stroke dark:text-stroke/50"}),t.jsxs("p",{className:"min-w-0 text-[9.5px] leading-relaxed text-muted-foreground",children:[t.jsx("span",{className:"font-semibold",children:$s[a.relation]??a.relation})," — ",a.because," · ",t.jsx("span",{className:Ie[a.confidence].className,children:Ie[a.confidence].label})]})]}),t.jsxs("button",{type:"button",disabled:!c,onClick:()=>c&&s(o),className:$("flex min-h-6 w-full items-start gap-2 rounded-lg border px-2 py-1.5 text-left",o.severity==="error"?"border-alert-orange/40 bg-alert-orange/[0.05]":"border-stroke bg-stroke/[0.06] dark:border-stroke/30 dark:bg-white/[0.03]",c&&"hover:border-dynamic-azure/50"),children:[t.jsx(l,{className:$("mt-0.5 h-3 w-3 shrink-0",o.severity==="error"?"text-alert-orange":"text-muted-foreground")}),t.jsxs("span",{className:"min-w-0 flex-1",children:[t.jsx("span",{className:"block break-words text-[10.5px] font-medium leading-snug",children:o.title}),o.detail&&t.jsx("span",{className:"mt-0.5 block break-all font-mono text-[9px] text-muted-foreground",children:o.detail})]})]})]},o.id)})}),t.jsx(Ae,{graph:e})]})}function Ae({graph:e}){return e.gaps.length===0?null:t.jsxs("div",{className:"space-y-1 rounded-lg border border-stroke bg-stroke/[0.06] px-2.5 py-2 dark:border-stroke/30 dark:bg-white/[0.03]",children:[t.jsxs("p",{className:"flex items-center gap-1.5 text-[10px] font-semibold text-muted-foreground",children:[t.jsx(W,{className:"h-2.5 w-2.5 shrink-0"}),"Not included in this analysis"]}),e.gaps.map(s=>t.jsxs("p",{className:"text-[9.5px] leading-relaxed text-muted-foreground",children:[t.jsxs("span",{className:"font-semibold text-foreground",children:[s.input,"."]})," ",s.reason]},s.input))]})}const Oe={changed:{label:"changed",className:"text-alert-orange border-alert-orange/40 bg-alert-orange/[0.05]"},added:{label:"added",className:"text-dynamic-azure border-dynamic-azure/40 bg-dynamic-azure/[0.05]"},removed:{label:"removed",className:"text-dynamic-azure border-dynamic-azure/40 bg-dynamic-azure/[0.05]"},same:{label:"same",className:"text-muted-foreground border-stroke dark:border-stroke/30"},incomparable:{label:"unknown",className:"text-muted-foreground border-stroke dark:border-stroke/30"}};function Es({diff:e,beforeLabel:s,afterLabel:r}){const n=e.entries.filter(d=>d.status==="changed"||d.status==="added"||d.status==="removed"),o=e.entries.filter(d=>d.status==="same"),m=e.entries.filter(d=>d.status==="incomparable");return t.jsxs("div",{className:"space-y-3",children:[t.jsxs("div",{className:"rounded-lg border border-stroke bg-stroke/[0.06] px-2.5 py-2 dark:border-stroke/30 dark:bg-white/[0.03]",children:[t.jsx("p",{className:"text-[10.5px] font-semibold",children:n.length===0?"Nothing comparable differed":`${String(n.length)} difference${n.length===1?"":"s"}`}),t.jsxs("p",{className:"mt-0.5 text-[9.5px] leading-relaxed text-muted-foreground",children:[String(o.length)," unchanged · ",String(m.length)," could not be compared"]}),t.jsxs("p",{className:"mt-1.5 flex flex-wrap gap-x-2 gap-y-0.5 border-t border-stroke/40 pt-1.5 font-mono text-[9px] text-muted-foreground dark:border-stroke/20",children:[t.jsxs("span",{className:"break-all",children:["A · ",s]}),t.jsxs("span",{className:"break-all",children:["B · ",r]})]})]}),n.length>0&&t.jsx(j,{title:"Different",children:t.jsx("div",{className:"space-y-1",children:n.map(d=>t.jsx(nt,{entry:d,defaultOpen:!0},d.key))})}),m.length>0&&t.jsx(Pe,{title:"Could not be compared",icon:ee,hint:"These are not unchanged. One or both snapshots have no reading for them.",entries:m}),o.length>0&&t.jsx(Pe,{title:"Unchanged",icon:ts,entries:o})]})}function Pe({title:e,icon:s,hint:r,entries:n}){const[o,m]=k.useState(!1);return t.jsxs("section",{className:"space-y-2",children:[t.jsxs("button",{type:"button",onClick:()=>m(!o),className:"flex min-h-6 w-full items-center gap-1.5 text-left",children:[t.jsx(s,{className:"h-2.5 w-2.5 shrink-0 text-muted-foreground"}),t.jsxs("span",{className:"text-[10px] font-semibold uppercase tracking-wide text-muted-foreground",children:[e," · ",String(n.length)]}),t.jsx(Z,{className:$("h-3 w-3 shrink-0 text-muted-foreground transition-transform",o&&"rotate-180")})]}),r&&t.jsx("p",{className:"text-[9.5px] leading-relaxed text-muted-foreground",children:r}),o&&t.jsx("div",{className:"space-y-1",children:n.map(d=>t.jsx(nt,{entry:d},d.key))})]})}function nt({entry:e,defaultOpen:s=!1}){const r=(e.parts??[]).filter(a=>a.status!=="same"),[n,o]=k.useState(s&&r.length>0),m=Oe[e.status],d=(e.parts??[]).length>0;return t.jsxs("div",{className:$("rounded-lg border px-2 py-1.5",m.className),children:[t.jsxs("button",{type:"button",disabled:!d,onClick:()=>d&&o(!n),className:"flex min-h-5 w-full items-start justify-between gap-2 text-left",children:[t.jsxs("span",{className:"min-w-0 flex-1",children:[t.jsx("span",{className:"block text-[10.5px] font-semibold text-foreground",children:e.dimension}),(e.before!==void 0||e.after!==void 0)&&t.jsxs("span",{className:"mt-0.5 block break-words font-mono text-[9px] text-muted-foreground",children:[e.before??"—",e.status==="same"?"":` → ${e.after??"—"}`]})]}),t.jsxs("span",{className:"flex shrink-0 items-center gap-1",children:[t.jsx("span",{className:"text-[9px] font-semibold uppercase tracking-wide",children:m.label}),d&&t.jsx(Z,{className:$("h-2.5 w-2.5 transition-transform",n&&"rotate-180")})]})]}),e.reason&&t.jsxs("p",{className:"mt-1 flex gap-1 border-t border-current/15 pt-1 text-[9px] leading-relaxed text-muted-foreground",children:[t.jsx(Be,{className:"mt-px h-2 w-2 shrink-0"}),t.jsx("span",{children:e.reason})]}),n&&e.parts&&t.jsx("div",{className:"mt-1.5 space-y-1 border-t border-current/15 pt-1.5",children:e.parts.map(a=>t.jsxs("div",{className:"flex items-start justify-between gap-2",children:[t.jsxs("span",{className:"min-w-0 flex-1",children:[t.jsx("span",{className:"block text-[9.5px] text-muted-foreground",children:a.dimension}),t.jsxs("span",{className:"block break-words font-mono text-[9px] text-foreground",children:[a.before??"—",a.status==="same"?"":` → ${a.after??"—"}`]}),a.reason&&t.jsx("span",{className:"mt-0.5 block text-[9px] leading-relaxed text-muted-foreground",children:a.reason})]}),t.jsx("span",{className:$("shrink-0 text-[9px] font-semibold uppercase tracking-wide",a.status==="same"?"text-muted-foreground/70":"text-foreground"),children:Oe[a.status].label})]},a.key))})]})}const Cs={applied:{label:"restored",icon:We,className:"text-emerald-700 dark:text-emerald-400",tone:"clean"},partial:{label:"partly restored",icon:W,className:"text-amber-700 dark:text-amber-400",tone:"alert"},failed:{label:"failed",icon:wt,className:"text-alert-orange",tone:"alert"},unsupported:{label:"cannot be restored",icon:Be,className:"text-muted-foreground",tone:"unknown"},unverifiable:{label:"unconfirmed",icon:ee,className:"text-muted-foreground",tone:"unknown"},skipped:{label:"nothing to do",icon:Qe,className:"text-muted-foreground",tone:"unknown"}},X={clean:"border-emerald-500/30 bg-emerald-500/[0.04]",alert:"border-alert-orange/40 bg-alert-orange/[0.05]",unknown:"border-stroke bg-stroke/[0.06] dark:border-stroke/30 dark:bg-white/[0.03]"};function Rs({ledger:e}){const s=e.entries.filter(o=>o.status!=="applied"&&o.status!=="skipped"),r=e.entries.filter(o=>o.status==="applied"),n=e.entries.filter(o=>o.status==="skipped");return t.jsxs(j,{title:"Reproduction",hint:"What was put back, and what could not be.",children:[t.jsxs("div",{className:$("rounded-lg border px-2.5 py-2",e.faithful?X.clean:s.some(o=>o.status==="failed"||o.status==="partial")?X.alert:X.unknown),children:[t.jsx("p",{className:"text-[10.5px] font-semibold leading-relaxed",children:e.headline}),t.jsxs("p",{className:"mt-1 font-mono text-[9px] text-muted-foreground",children:[String(e.appliedCount)," restored · ",String(e.unrestoredCount)," not restored"]}),e.fingerprint&&t.jsxs("p",{className:"mt-1.5 border-t border-current/15 pt-1.5 text-[9.5px] leading-relaxed text-muted-foreground",children:[t.jsx("span",{className:"font-semibold text-foreground",children:"Environment identity."})," ",e.fingerprint.comparison.summary," ",t.jsxs("span",{className:"font-mono",children:[e.fingerprint.original," → ",e.fingerprint.current]})]}),e.fingerprint===null&&t.jsx("p",{className:"mt-1.5 border-t border-current/15 pt-1.5 text-[9.5px] leading-relaxed text-muted-foreground",children:"The environment could not be re-measured as a whole — most often because the page had not finished loading. That is not the same as a mismatch."})]}),s.length>0&&t.jsx("div",{className:"space-y-1",children:s.map(o=>t.jsx(Le,{entry:o},o.key))}),r.length>0&&t.jsx("div",{className:"space-y-1",children:r.map(o=>t.jsx(Le,{entry:o},o.key))}),n.length>0&&t.jsxs("p",{className:"text-[9.5px] leading-relaxed text-muted-foreground",children:["Nothing to restore for: ",n.map(o=>o.label).join(", "),"."]})]})}function Le({entry:e}){const s=Cs[e.status],r=s.icon;return t.jsx("div",{className:$("rounded-lg border px-2 py-1.5",X[s.tone]),children:t.jsxs("div",{className:"flex items-start gap-1.5",children:[t.jsx(r,{className:$("mt-0.5 h-2.5 w-2.5 shrink-0",s.className)}),t.jsxs("div",{className:"min-w-0 flex-1",children:[t.jsxs("p",{className:"flex flex-wrap items-baseline gap-x-1.5",children:[t.jsx("span",{className:"min-w-0 break-words text-[10.5px] font-medium",children:e.label}),t.jsx("span",{className:$("shrink-0 text-[9px] font-semibold uppercase tracking-wide",s.className),children:s.label})]}),e.detail&&t.jsx("p",{className:"mt-0.5 font-mono text-[9px] text-muted-foreground",children:e.detail}),e.verification&&e.verification.method!=="none"&&t.jsxs("p",{className:"mt-0.5 font-mono text-[9px] leading-relaxed text-muted-foreground",children:["wanted ",e.verification.expected," · got ",e.verification.observed]}),e.reason&&t.jsx("p",{className:"mt-1 text-[9.5px] leading-relaxed text-muted-foreground",children:e.reason})]})]})})}const Is={local:es,pending:jt,syncing:le,synced:We,partial:W,retrying:le,failed:W,"auth-required":yt},As={clean:"text-emerald-700 dark:text-emerald-400 border-emerald-500/30 bg-emerald-500/[0.05]",alert:"text-alert-orange border-alert-orange/40 bg-alert-orange/[0.05]",unknown:"text-muted-foreground border-stroke bg-stroke/[0.06] dark:border-stroke/30 dark:bg-white/[0.03]"};function Os({executionId:e}){const[s,r]=k.useState(null),[n,o]=k.useState(!1),[m,d]=k.useState(!1),a=()=>{$t(e).then(r)};k.useEffect(a,[e]);const l=s?.state??"local",c=Nt[l],p=Is[l],S=l==="failed"||l==="partial"||l==="retrying";return t.jsxs("div",{className:"space-y-1",children:[t.jsxs("button",{type:"button",onClick:()=>o(!n),className:$("flex min-h-6 w-full items-center gap-1.5 rounded-lg border px-2 py-1 text-left",As[c.tone]),children:[t.jsx(p,{className:$("h-2.5 w-2.5 shrink-0",l==="syncing"&&"animate-spin")}),t.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wide",children:c.label}),s?.attempts?t.jsxs("span",{className:"ml-auto font-mono text-[9px] opacity-70",children:[String(s.attempts)," attempt",s.attempts===1?"":"s"]}):null]}),n&&t.jsxs("div",{className:"rounded-lg border border-stroke bg-stroke/[0.06] px-2 py-1.5 dark:border-stroke/30 dark:bg-white/[0.03]",children:[t.jsx("p",{className:"text-[9.5px] leading-relaxed text-muted-foreground",children:c.meaning}),s?.lastError&&t.jsx("p",{className:"mt-1 break-words font-mono text-[9px] text-muted-foreground",children:s.lastError}),s?.rejected&&s.rejected.length>0&&t.jsx("div",{className:"mt-1 space-y-0.5 border-t border-stroke/40 pt-1 dark:border-stroke/20",children:s.rejected.slice(0,5).map(w=>t.jsxs("p",{className:"break-words font-mono text-[9px] text-muted-foreground",children:[w.stream," · ",w.reason]},`${w.stream}:${w.id}`))}),s?.serverCounts&&t.jsxs("p",{className:"mt-1 font-mono text-[9px] text-muted-foreground",children:["server has ",String(s.serverCounts.events)," events · ",String(s.serverCounts.evidence)," evidence"]}),S&&t.jsxs(J,{size:"sm",variant:"outline",className:"mt-1.5 h-6 w-full",loading:m,onClick:()=>{d(!0),St(e).then(a).finally(()=>d(!1))},children:[t.jsx(le,{className:"h-2.5 w-2.5"}),"Retry now"]})]})]})}const Ps={regression:"alert",improvement:"clean","no-change":"clean","environment-differs":"unknown","insufficient-data":"unknown"},Ls={regression:"Slower",improvement:"Faster","no-change":"No change","environment-differs":"Environment differs","insufficient-data":"Not enough data"},at={clean:"border-emerald-500/30 bg-emerald-500/[0.04] text-emerald-700 dark:text-emerald-400",alert:"border-alert-orange/40 bg-alert-orange/[0.05] text-alert-orange",unknown:"border-stroke bg-stroke/[0.06] text-muted-foreground dark:border-stroke/30 dark:bg-white/[0.03]"};function z(e,s){return e===null?"—":s==="score"?e.toFixed(3):s==="count"?String(Math.round(e)):e>=1e3?`${(e/1e3).toFixed(2)}s`:`${String(Math.round(e))}ms`}function Ms({summary:e,comparison:s,previousLabel:r}){return e?t.jsxs(t.Fragment,{children:[t.jsxs(j,{title:"Performance",hint:`From ${String(e.samples)} sample${e.samples===1?"":"s"}, settled state of the page.`,children:[s&&t.jsxs("div",{className:$("rounded-lg border px-2.5 py-2",at[Ps[s.verdict]]),children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-wide",children:Ls[s.verdict]}),t.jsx("p",{className:"mt-1 text-[10px] leading-relaxed text-muted-foreground",children:s.basis}),r&&t.jsxs("p",{className:"mt-1 font-mono text-[9px] text-muted-foreground",children:["compared with ",r]})]}),t.jsxs("div",{className:"space-y-1",children:[(s?.metrics??[]).map(n=>t.jsx(_s,{metric:n},n.key)),!s&&t.jsx(Us,{summary:e})]})]}),e.longTasks&&t.jsx(j,{title:"Long tasks",children:t.jsxs("div",{className:"rounded-lg bg-stroke/10 px-2.5 py-1.5 font-mono text-[10px] dark:bg-white/[0.03]",children:[t.jsxs("p",{children:[String(e.longTasks.count)," tasks · ",String(Math.round(e.longTasks.totalDuration))," ms total · longest ",String(Math.round(e.longTasks.maxDuration))," ms"]}),t.jsx("p",{className:"mt-1 text-[9px] leading-relaxed text-muted-foreground",children:"A long task blocks the main thread for over 50 ms — during which the page cannot respond to input at all."})]})})]}):t.jsx(j,{title:"Performance",children:t.jsxs("div",{className:"rounded-lg border border-dashed border-stroke px-3 py-4 text-center dark:border-stroke/30",children:[t.jsx("p",{className:"text-[11px] font-medium",children:"No performance data"}),t.jsx("p",{className:"mt-1 text-[10px] leading-relaxed text-muted-foreground",children:"Telemetry capture was off during this execution, or the page could not be instrumented — so no web vitals were recorded. This is not a statement about how the page performed."})]})})}function _s({metric:e}){const s=e.verdict==="worse"?Jt:e.verdict==="better"?Ze:e.verdict==="not-measured"?ee:Qe,r=e.verdict==="worse"?"alert":e.verdict==="better"?"clean":"unknown";return t.jsxs("div",{className:$("rounded-lg border px-2 py-1.5",at[r]),children:[t.jsxs("div",{className:"flex items-baseline justify-between gap-2",children:[t.jsx("span",{className:"min-w-0 text-[10.5px] font-medium text-foreground",children:e.label}),t.jsxs("span",{className:"shrink-0 font-mono text-[10px] tabular-nums",children:[z(e.before,e.unit)," → ",z(e.after,e.unit)]})]}),t.jsxs("div",{className:"mt-0.5 flex items-center gap-1",children:[t.jsx(s,{className:"h-2.5 w-2.5 shrink-0"}),t.jsx("span",{className:"font-mono text-[9px]",children:e.deltaPercent===null?e.verdict==="not-measured"?"not measured":"no baseline to compare":`${e.deltaPercent>0?"+":""}${String(e.deltaPercent)}%`})]}),e.reason&&t.jsx("p",{className:"mt-1 text-[9px] leading-relaxed text-muted-foreground",children:e.reason})]})}function Us({summary:e}){const s=[{label:"Largest Contentful Paint",value:z(e.vitals.lcp,"ms")},{label:"First Contentful Paint",value:z(e.vitals.fcp,"ms")},{label:"Time to First Byte",value:z(e.vitals.ttfb,"ms")},{label:"Interaction to Next Paint",value:z(e.vitals.inp,"ms")},{label:"Cumulative Layout Shift",value:z(e.vitals.cls,"score")},{label:"Page load",value:z(e.navigation?.pageLoadTime??null,"ms")}];return t.jsxs("div",{className:"rounded-lg bg-stroke/10 px-2.5 py-1.5 dark:bg-white/[0.03]",children:[s.map(r=>t.jsxs("div",{className:"flex items-baseline justify-between gap-3 py-0.5",children:[t.jsx("span",{className:"text-[10px] text-muted-foreground",children:r.label}),t.jsx("span",{className:"shrink-0 font-mono text-[10px] tabular-nums",children:r.value})]},r.label)),t.jsx("p",{className:"mt-1 border-t border-stroke/40 pt-1 text-[9px] leading-relaxed text-muted-foreground dark:border-stroke/20",children:"A dash means the metric was not measured — INP needs an interaction, and LCP needs a large element to paint. It does not mean zero."})]})}const qs=e=>`${String(Math.round(e*100))}%`,Q=e=>e>=1e3?`${(e/1e3).toFixed(2)}s`:`${String(Math.round(e))}ms`;function Vs({report:e}){return e.observed?t.jsxs(j,{title:`Observed API behaviour · ${String(e.endpoints.length)}`,hint:"What the endpoints did during this execution — not what the API guarantees.",children:[t.jsx("p",{className:"text-[9.5px] leading-relaxed text-muted-foreground",children:e.note}),e.endpoints.length===0?t.jsx("div",{className:"rounded-lg border border-dashed border-stroke px-3 py-3 text-center text-[10px] text-muted-foreground dark:border-stroke/30",children:"Capture was on and this execution made no requests."}):t.jsx("div",{className:"space-y-1",children:e.endpoints.map(s=>t.jsx(zs,{endpoint:s},`${s.method} ${s.path}`))})]}):t.jsx(j,{title:"Observed API behaviour",children:t.jsxs("div",{className:"rounded-lg border border-dashed border-stroke px-3 py-4 text-center dark:border-stroke/30",children:[t.jsx("p",{className:"text-[11px] font-medium",children:"Nothing was observed"}),t.jsx("p",{className:"mt-1 text-[10px] leading-relaxed text-muted-foreground",children:e.note})]})})}function zs({endpoint:e}){const[s,r]=k.useState(!1),n=e.errorRate>0;return t.jsxs("div",{className:$("rounded-lg border px-2 py-1.5",n?"border-alert-orange/40 bg-alert-orange/[0.05]":"border-stroke bg-stroke/[0.06] dark:border-stroke/30 dark:bg-white/[0.03]"),children:[t.jsxs("button",{type:"button",onClick:()=>r(!s),className:"flex min-h-6 w-full items-start gap-2 text-left",children:[t.jsx("span",{className:"shrink-0 font-mono text-[9px] font-semibold uppercase text-muted-foreground",children:e.method}),t.jsxs("span",{className:"min-w-0 flex-1",children:[t.jsx("span",{className:"block break-all font-mono text-[10px] font-medium",children:e.path}),t.jsxs("span",{className:"mt-0.5 block font-mono text-[9px] text-muted-foreground",children:[String(e.requests)," request",e.requests===1?"":"s"," ·"," ",t.jsxs("span",{className:n?"text-alert-orange":void 0,children:[qs(e.errorRate)," errors"]}),e.noResponse>0?` · ${String(e.noResponse)} no response`:""]})]}),t.jsx(Z,{className:$("mt-0.5 h-3 w-3 shrink-0 transition-transform",s&&"rotate-180")})]}),s&&t.jsxs("div",{className:"mt-1.5 space-y-1 border-t border-current/15 pt-1.5",children:[t.jsx("div",{className:"flex flex-wrap gap-x-3 gap-y-0.5 font-mono text-[9px] text-muted-foreground",children:e.statuses.map(o=>t.jsxs("span",{children:[o.status===0?"no response":String(o.status)," × ",String(o.count)]},o.status))}),e.latency?t.jsxs("p",{className:"font-mono text-[9px] text-muted-foreground",children:["p50 ",Q(e.latency.p50)," · p95 ",Q(e.latency.p95)," · p99 ",Q(e.latency.p99)]}):t.jsxs("p",{className:"font-mono text-[9px] leading-relaxed text-muted-foreground",children:[(e.durations??[]).map(Q).join(" · ")||"no completed requests",t.jsxs("span",{className:"block",children:["Percentiles need at least ",String(Zt)," completed requests; these are the raw durations."]})]}),e.traceIds.length>0&&t.jsxs("p",{className:"break-all font-mono text-[9px] text-muted-foreground",children:["trace ",e.traceIds[0],e.traceIds.length>1?` +${String(e.traceIds.length-1)}`:""]})]})]})}const Ds={transport:Ct,headers:as,cookies:Et,storage:Tt,"third-party":ve,"url-parameters":ve},Fs={transport:"Transport",headers:"Headers",cookies:"Cookies",storage:"Storage","third-party":"Third-party requests","url-parameters":"URL parameters"},Ks={high:"border-alert-orange/45 bg-alert-orange/[0.06] text-alert-orange",medium:"border-amber-500/35 bg-amber-500/[0.05] text-amber-700 dark:text-amber-400",low:"border-stroke bg-stroke/[0.06] text-muted-foreground dark:border-stroke/30",informational:"border-stroke bg-stroke/[0.06] text-muted-foreground dark:border-stroke/30 dark:bg-white/[0.03]"};function Bs({report:e}){const s=new Map;for(const r of e.observations)s.set(r.group,[...s.get(r.group)??[],r]);return t.jsxs(t.Fragment,{children:[e.notChecked.length>0&&t.jsx(j,{title:"Not examined",hint:"No finding here means nothing was looked at.",children:t.jsx("div",{className:"space-y-1",children:e.notChecked.map(r=>t.jsxs("div",{className:"rounded-lg border border-stroke bg-stroke/[0.06] px-2 py-1.5 dark:border-stroke/30 dark:bg-white/[0.03]",children:[t.jsxs("p",{className:"flex items-center gap-1.5 text-[10.5px] font-semibold",children:[t.jsx(ee,{className:"h-2.5 w-2.5 shrink-0 text-muted-foreground"}),r.surface]}),t.jsx("p",{className:"mt-0.5 text-[9.5px] leading-relaxed text-muted-foreground",children:r.reason})]},r.surface))})}),t.jsxs(j,{title:e.observations.length===0?"Observations":`Observations · ${String(e.observations.length)}`,children:[e.observations.length===0?t.jsxs("div",{className:"rounded-lg border border-dashed border-stroke px-3 py-3 dark:border-stroke/30",children:[t.jsx("p",{className:"text-[11px] font-medium",children:"Nothing observed in what was examined"}),t.jsx("p",{className:"mt-1 text-[10px] leading-relaxed text-muted-foreground",children:"None of the surfaces above produced an observation. Read that alongside what was not examined — it is not a statement that the application is secure."})]}):t.jsx("div",{className:"space-y-2",children:[...s.entries()].map(([r,n])=>{const o=Ds[r];return t.jsxs("div",{className:"space-y-1",children:[t.jsxs("p",{className:"flex items-center gap-1.5 text-[9.5px] font-semibold uppercase tracking-wide text-muted-foreground",children:[t.jsx(o,{className:"h-2.5 w-2.5 shrink-0"}),Fs[r]]}),n.map(m=>t.jsxs("div",{className:$("rounded-lg border px-2 py-1.5",Ks[m.severity]),children:[t.jsxs("p",{className:"flex items-start gap-1.5",children:[m.severity==="high"&&t.jsx(W,{className:"mt-0.5 h-2.5 w-2.5 shrink-0"}),t.jsx("span",{className:"min-w-0 break-words text-[10.5px] font-semibold text-foreground",children:m.title}),t.jsx("span",{className:"ml-auto shrink-0 text-[8.5px] font-semibold uppercase tracking-wide",children:m.severity})]}),t.jsx("p",{className:"mt-0.5 text-[9.5px] leading-relaxed text-muted-foreground",children:m.detail}),t.jsx("p",{className:"mt-1 break-all border-t border-current/15 pt-1 font-mono text-[9px] text-muted-foreground",children:m.evidence})]},m.id))]},r)})}),t.jsx("p",{className:"text-[9px] leading-relaxed text-muted-foreground",children:e.note})]})]})}const Ws=["access_token","refresh_token","id_token","token","api_key","apikey","secret","password","passwd","pwd","auth","session","sessionid","sid"],Me=/token|secret|password|passwd|credential|api[-_]?key|private[-_]?key|session/i,Hs=/^(eyJ[\w-]{8,}\.[\w-]{8,}\.[\w-]{8,}|[A-Za-z0-9_-]{40,})$/,_e=e=>{try{return new URL(e).host}catch{return null}};function Gs(e){const s=[],r=[],n=e.snapshot?.url,o=n?_e(n):null;n?.startsWith("http://")&&!/^https?:\/\/(localhost|127\.0\.0\.1|\[::1\])/i.test(n)&&s.push({id:"transport-insecure-page",group:"transport",severity:"high",title:"The page under test was served over HTTP",detail:"Everything on this page — form values, cookies, tokens — travelled unencrypted and is readable by anything on the network path.",evidence:n});const m=e.signals?.capturing===!0?e.signals.requests:null;if(m===null)r.push({surface:"Network requests",reason:"Telemetry capture was off, so mixed content, third-party calls and URL parameters could not be inspected. No finding here means nothing was looked at."});else{const a=m.filter(l=>l.url.startsWith("http://")&&!/^https?:\/\/(localhost|127\.0\.0\.1|\[::1\])/i.test(l.url));n?.startsWith("https://")&&a.length>0&&s.push({id:"transport-mixed-content",group:"transport",severity:"high",title:`${String(a.length)} request${a.length===1?"":"s"} left a secure page over plain HTTP`,detail:"Mixed content: the page is HTTPS but these requests are not, so their contents are exposed and browsers may block them.",evidence:a.slice(0,3).map(l=>`${l.method} ${ie(l.url)}`).join(", ")});for(const l of m){const c=Js(l.url);c.length!==0&&s.push({id:`url-param-${l.method}-${ie(l.url)}-${c.join("-")}`,group:"url-parameters",severity:"high",title:"A credential-shaped parameter appears in a URL",detail:"URLs reach browser history, Referer headers, server logs and analytics. TCR masks the value in its own copy, which is why it appears redacted here — but the real request carried it, and everything else on that path received it. Send it in a header or a body instead.",evidence:`${l.method} ${ie(l.url)} — parameter${c.length===1?"":"s"} ${c.join(", ")}`})}if(o){const l=new Map;for(const c of m){const p=_e(c.url);p&&p!==o&&!p.endsWith(`.${o}`)&&l.set(p,(l.get(p)??0)+1)}l.size>0&&s.push({id:"third-party-requests",group:"third-party",severity:"informational",title:`${String(l.size)} third-party host${l.size===1?"":"s"} received requests`,detail:"Third-party requests are normal. Worth a look for anything unexpected — data leaving to a host nobody added deliberately.",evidence:[...l.entries()].sort((c,p)=>p[1]-c[1]).slice(0,6).map(([c,p])=>`${c} (${String(p)})`).join(", ")})}}if(e.cookies===void 0)r.push({surface:"Cookie flags",reason:"Cookie values were not read for this execution — a snapshot records counts only. Open the Cookies screen to inspect Secure, HttpOnly and SameSite."});else for(const a of e.cookies){const l=[];if(a.secure||l.push("not Secure"),a.httpOnly||l.push("not HttpOnly"),a.sameSite==="no_restriction"&&l.push("SameSite=None"),l.length===0)continue;const c=Me.test(a.name);s.push({id:`cookie-${a.name}`,group:"cookies",severity:c&&!a.httpOnly?"high":"medium",title:`Cookie “${a.name}” is ${l.join(" and ")}`,detail:c&&!a.httpOnly?"A session cookie readable from JavaScript can be taken by any script that runs on the page.":"Secure keeps a cookie off plain HTTP; HttpOnly keeps it away from page script; SameSite limits cross-site sending.",evidence:`${a.name} on ${a.domain}${a.path}`})}const d=e.storageKeys;if(d===void 0&&e.storageEntries===void 0)r.push({surface:"Local and session storage",reason:"Storage was not inspected for this execution. Open the Application state screen to look for credential-shaped keys."});else{for(const a of d??[])Me.test(a)&&s.push({id:`storage-key-${a}`,group:"storage",severity:"medium",title:`Storage key “${a}” is named like a credential`,detail:"Web storage is readable by any script on the origin and survives the tab. The name alone is not proof it holds a secret — worth confirming what is in it.",evidence:a});for(const a of e.storageEntries??[])Hs.test(a.value.trim())&&s.push({id:`storage-value-${a.key}`,group:"storage",severity:"high",title:`Storage key “${a.key}” holds a credential-shaped value`,detail:"The value looks like a bearer token or JWT. Anything running on this origin can read it, and it persists after the tab closes.",evidence:`${a.key} = ${Ye} (${String(a.value.trim().length)} characters)`})}return r.push({surface:"Security response headers",reason:"Content-Security-Policy, Strict-Transport-Security and X-Frame-Options are response headers, and the captured network view stores them stripped. They were not evaluated."}),{observations:s.sort((a,l)=>Ue(l.severity)-Ue(a.severity)),notChecked:r,note:"Passive observations from evidence already captured. Nothing was probed or sent — this is not a penetration test, and a clean result is not a statement that the application is secure."}}const Ue=e=>e==="high"?3:e==="medium"?2:e==="low"?1:0;function ie(e){const s=ot(e);return s?s.host==="relative.invalid"?s.pathname:`${s.host}${s.pathname}`:(e.split("?")[0]??e).slice(0,120)}function Js(e){const s=ot(e);if(!s)return[];const r=[];return s.searchParams.forEach((n,o)=>{n!==""&&Ws.includes(o.toLowerCase())&&r.push(o)}),[...new Set(r)]}function ot(e){try{return new URL(e)}catch{try{return new URL(e,"https://relative.invalid")}catch{return null}}}const Zs=e=>e.offline?"Offline":`${e.presetId} · ${String(e.latencyMs)} ms · ${String(e.downloadKbps)}↓ / ${String(e.uploadKbps)}↑ kbps${e.packetLoss>0?` · ${String(e.packetLoss)}% loss`:""}`,Qs=e=>{const s=Object.entries(e).filter(([,r])=>r!==void 0);return s.length===0?"none set":s.sort(([r],[n])=>r.localeCompare(n)).map(([r,n])=>`${r}=${String(n)}`).join(", ")};function U(e,s,r,n,o,m,d){const a=d===void 0||d.length===0?{}:{parts:d};if(r===void 0&&n===void 0)return{key:e,dimension:s,status:"same",before:m,after:m};if(r===void 0)return{key:e,dimension:s,status:"added",before:m,after:o(n),...a};if(n===void 0)return{key:e,dimension:s,status:"removed",before:o(r),after:m,...a};const l=o(r),c=o(n);return{key:e,dimension:s,status:l===c?"same":"changed",before:l,after:c,...a}}function qe(e,s,r,n,o){return r===void 0&&n===void 0?null:r===void 0||n===void 0?{key:e,dimension:s,status:"incomparable",...r===void 0?{}:{before:r},...n===void 0?{}:{after:n},reason:o}:{key:e,dimension:s,status:r===n?"same":"changed",before:r,after:n}}const R=(e,s,r,n)=>({key:e,dimension:s,status:r===n?"same":"changed",before:r,after:n});function Ys(e,s){const r=[],n=c=>{c!==null&&r.push(c)};n(qe("url","URL",e.url,s.url,"One snapshot did not record the page URL, so the two cannot be compared.")),n(qe("appVersion","App version",e.appVersion,s.appVersion,"One snapshot found no version marker on the page. The application may not publish one, or the read may have failed — those are not distinguishable, so this is not reported as a change.")),e.device&&s.device?(n(R("browser","Browser",`${e.device.browser} ${e.device.browserVersion}`,`${s.device.browser} ${s.device.browserVersion}`)),n(R("os","Operating system",`${e.device.os} ${e.device.osVersion}`,`${s.device.os} ${s.device.osVersion}`)),n(R("screen","Screen",`${String(e.device.resolution.width)}×${String(e.device.resolution.height)} @${String(e.device.devicePixelRatio)}`,`${String(s.device.resolution.width)}×${String(s.device.resolution.height)} @${String(s.device.devicePixelRatio)}`)),n(R("timezone","Time zone",e.device.timezone,s.device.timezone)),n(R("language","Language",e.device.language,s.device.language))):(e.device||s.device)&&r.push({key:"browser",dimension:"Browser",status:"incomparable",reason:"One snapshot did not record the browser description."}),n(U("viewport","Viewport",e.viewport,s.viewport,c=>`${c.profileId} · ${String(c.width)}×${String(c.height)}${c.rotate?" rotated":""}`,"not emulated")),n(U("network","Network",e.network,s.network,Zs,"browser default",e.network&&s.network?[R("network.preset","Preset",e.network.presetId,s.network.presetId),R("network.offline","Offline",String(e.network.offline),String(s.network.offline)),R("network.latency","Latency",`${String(e.network.latencyMs)} ms`,`${String(s.network.latencyMs)} ms`),R("network.down","Download",`${String(e.network.downloadKbps)} kbps`,`${String(s.network.downloadKbps)} kbps`),R("network.up","Upload",`${String(e.network.uploadKbps)} kbps`,`${String(s.network.uploadKbps)} kbps`),e.network.packetLoss>0||s.network.packetLoss>0?{key:"network.loss",dimension:"Packet loss",status:"incomparable",before:`${String(e.network.packetLoss)}% requested`,after:`${String(s.network.packetLoss)}% requested`,reason:"Chrome accepts the packet-loss parameter without reporting whether it is enforced, so neither snapshot can say what the browser actually did."}:R("network.loss","Packet loss","none requested","none requested")]:void 0)),n(U("geo","Location",e.geo,s.geo,c=>`${c.label} · ${c.latitude.toFixed(4)}, ${c.longitude.toFixed(4)} · permission ${c.permission}`,"not overridden")),n(U("permissions","Permissions",e.permissions,s.permissions,Qs,"none set",Xs(e.permissions??{},s.permissions??{})));const o=e.rules??[],m=s.rules??[];if(n(U("rules","Network rules armed",e.rules,s.rules,c=>`${String(c.length)} armed`,"none armed",er(o,m))),e.state&&s.state){n(R("state.cookies","Cookies",String(e.state.cookies),String(s.state.cookies))),n(R("state.local","localStorage keys",String(e.state.localStorageKeys),String(s.state.localStorageKeys))),n(R("state.session","sessionStorage keys",String(e.state.sessionStorageKeys),String(s.state.sessionStorageKeys)));for(const[c,p]of[["state.idb","IndexedDB databases"],["state.cache","Cache Storage keys"],["state.sw","Service workers"]])r.push({key:c,dimension:p,status:"incomparable",reason:"Snapshots do not measure this — counting it needs an asynchronous read that starting an execution must not wait for. Both snapshots record zero regardless of what was there. The Application State panel reads the real numbers."})}else(e.state||s.state)&&r.push({key:"state",dimension:"Application state",status:"incomparable",reason:"One snapshot did not record storage counts."});n(U("profile","Environment profile",e.profile,s.profile,c=>c.name,"no profile")),n(U("run","Test run",e.context?.testRunId,s.context?.testRunId,c=>c,"not linked to a run"));const d=r.filter(c=>c.status==="changed"||c.status==="added"||c.status==="removed").length,a=r.filter(c=>c.status==="incomparable").length,l=r.filter(c=>c.status==="same").length;return{entries:r,changed:d,same:l,incomparable:a,identical:d===0}}function Xs(e,s){return[...new Set([...Object.keys(e),...Object.keys(s)])].sort().map(n=>{const o=e[n],m=s[n];return U(`permissions.${n}`,n,o,m,d=>d,"not set")})}function er(e,s){return[...new Set([...e.map(n=>n.name),...s.map(n=>n.name)])].sort().map(n=>{const o=e.find(d=>d.name===n),m=s.find(d=>d.name===n);return U(`rules.${n}`,n,o,m,d=>`${d.action} · ${d.match}`,"not armed")})}const tr=1,_=e=>Vt(e,Y.redactUrlParams);function sr(e){const s=e.action,r=o=>{if(o===void 0)return;const m={};for(const a of o)m[a.name]=a.value;const d=zt(m,Y.redactHeaders);return o.map(a=>({name:a.name,value:d[a.name]??a.value}))},n=(()=>{switch(s.kind){case"mock-response":case"modify-response":return{...s,...s.headers===void 0?{}:{headers:r(s.headers)},...s.body===void 0?{}:{body:Ne(s.body,Y.redactBodyKeys)}};case"modify-request":return{...s,...s.headers===void 0?{}:{headers:r(s.headers)},...s.body===void 0?{}:{body:Ne(s.body,Y.redactBodyKeys)},...s.url===void 0?{}:{url:_(s.url)}};case"redirect":return{...s,url:_(s.url)};default:return s}})();return{...e,name:_(e.name),action:n}}function rr(e){const{execution:s}=e,r=[],n=s.snapshot;n?.state&&(n.state.cookies>0||n.state.localStorageKeys>0)&&r.push({field:"environment.state",reason:`The original ran with ${String(n.state.cookies)} cookies and ${String(n.state.localStorageKeys)} storage keys. Their values are never recorded and never travel — a shared session is a credential handed to whoever opens this file. Sign in as an equivalent user before replaying.`});const o=(e.rules??[]).map(sr);(e.rules??[]).length>0&&r.push({field:"rules[].headers, rules[].body",reason:"Header and body values in the shared rules were passed through the same redactor as telemetry. An Authorization header or a token-shaped body field will read as masked — re-enter your own if the rule needs one."});const d=[...new Set((n?.rules??[]).map(f=>f.name))].filter(f=>!o.some(y=>y.name===f));d.length>0&&r.push({field:"rules",reason:`${String(d.length)} rule${d.length===1?"":"s"} armed during the original run could not be included, only named: ${d.join(", ")}. The environment snapshot records what each one did.`});const a=e.workflow?{name:_(e.workflow.name),...e.workflow.startUrl===void 0?{}:{startUrl:e.workflow.startUrl},steps:e.workflow.steps.map(f=>({index:f.index,kind:f.kind,label:_(f.label),selectors:f.selectors,...f.waitBeforeMs===void 0?{}:{waitBeforeMs:f.waitBeforeMs},needsValue:f.value!==void 0&&f.value!==""}))}:void 0;a&&a.steps.some(f=>f.needsValue)&&r.push({field:"workflow.steps[].value",reason:"Typed values are dropped rather than masked. The recorder flags password fields, but a reference field can hold a licence key and an email field holds personal data — so no step value travels. Steps marked `needsValue` need your own input on replay."});const l={events:e.events,interceptions:e.interceptions,evidence:e.evidence,signals:e.signals??null,...s.status===void 0?{}:{status:s.status}},c=rt(l),S=s.status==="failed"||s.status==="error"||c.chain.length>0?{summary:_(s.error??s.summary??"The execution did not pass."),chain:c.chain.map((f,y)=>{const u=c.edges.find(g=>g.to===f.id&&g.from===c.chain[y-1]?.id);return{kind:f.kind,title:_(f.title),...u===void 0?{}:{because:`${u.relation} — ${u.because} (${u.confidence})`}}}),gaps:c.gaps}:void 0,w=[...new Set((e.signals?.requests??[]).map(f=>f.traceId).filter(f=>typeof f=="string"&&f.length>0))];return{formatVersion:tr,createdAt:Date.now(),execution:{id:s.id,kind:s.kind,title:_(s.title),status:s.status,startedAt:s.startedAt,...s.finishedAt===void 0?{}:{finishedAt:s.finishedAt},...s.summary===void 0?{}:{summary:_(s.summary)}},environment:n??{capturedAt:0},fingerprint:B(n??{}),rules:o,...a===void 0?{}:{workflow:a},...S===void 0?{}:{failure:S},evidence:e.evidence.map(f=>({id:f.id,type:f.type,label:_(f.label),source:f.source,...f.bucketPath===void 0?{}:{bucketPath:f.bucketPath}})),traces:w,...e.ledger===void 0||e.ledger===null?{}:{ledger:e.ledger},redactions:r}}const nr=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),Ve=nr(Ye),ar=[{name:"bearer token",pattern:new RegExp(`\\bbearer\\s+(?!${Ve})[A-Za-z0-9._~+/-]{16,}`,"i")},{name:"JWT",pattern:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/},{name:"token in a URL",pattern:new RegExp(`[?&](access_token|refresh_token|id_token|api_key|apikey)=(?!${Ve})[^&"'\\s]+`,"i")},{name:"private key block",pattern:/-----BEGIN [A-Z ]*PRIVATE KEY-----/},{name:"AWS access key id",pattern:/\bAKIA[0-9A-Z]{16}\b/},{name:"Google API key",pattern:/\bAIza[0-9A-Za-z_-]{35}\b/}];function or(e){const s=JSON.stringify(e),r=ar.filter(n=>n.pattern.test(s)).map(n=>({shape:n.name,where:"somewhere in the serialised package"}));return{safe:r.length===0,findings:r}}function ir(e){const s=or(e);if(!s.safe)throw new Error(`This reproduction package was not shared because it still contains something shaped like a credential (${s.findings.map(r=>r.shape).join(", ")}). That is a bug in the package builder, not in your data — please report it.`);return JSON.stringify(e,null,2)}const lr=[{id:"overview",label:"Overview"},{id:"timeline",label:"Timeline"},{id:"evidence",label:"Evidence"},{id:"console",label:"Console"},{id:"network",label:"Network"},{id:"quality",label:"Quality"},{id:"environment",label:"Environment"}];function Ar({route:e}){const s=Rt(x=>x.go),[r,n]=k.useState(null),[o,m]=k.useState([]),[d,a]=k.useState([]),[l,c]=k.useState([]),[p,S]=k.useState(null),[w,f]=k.useState("loading"),[y,u]=k.useState("overview"),[g,N]=k.useState(null),[i,h]=k.useState(!1),[T,b]=k.useState(!1),[v,E]=k.useState(null),I=k.useMemo(()=>Qt(p),[p]),O=k.useMemo(()=>Gs({signals:p,...r?.snapshot===void 0?{}:{snapshot:r.snapshot}}),[p,r]),P=k.useMemo(()=>r?.performanceSummary??null,[r]),[M,C]=k.useState(null);k.useEffect(()=>{r&&He(50,r.projectId).then(x=>{const D=x.find(V=>V.id!==r.id&&V.title===r.title&&V.startedAt<r.startedAt);C(D??null)})},[r]);const lt=k.useMemo(()=>{const x=M?.performanceSummary;if(!x||!P||!r)return null;const D=r.snapshot!==void 0&&M?.snapshot!==void 0&&["identical","equivalent-where-measured"].includes(tt(B(M.snapshot),B(r.snapshot)).verdict);return Yt(x,P,{sameEnvironment:D,samePage:x.pageUrl===void 0||P.pageUrl===void 0?void 0:x.pageUrl===P.pageUrl})},[M,P,r]),ge=k.useMemo(()=>rt({events:o,interceptions:l,evidence:d,signals:p,...r===null?{}:{status:r.status}}),[o,l,d,p,r]),te=k.useCallback(async()=>{const x=await Dt.get(e.executionId);if(!x){f("missing");return}n(x);const[D,V,ne]=await Promise.all([It(x.id),At(x.id),Ft.list()]);m(D),a(V);const A=x.startedAt,ae=x.finishedAt??Date.now();c(ne.filter(be=>be.timestamp>=A&&be.timestamp<=ae)),f("ready")},[e.executionId]);k.useEffect(()=>{te()},[te]),k.useEffect(()=>{(y==="console"||y==="network"||y==="overview")&&p===null&&Ht().then(S)},[y,p]),k.useEffect(()=>{r?.snapshot&&g===null&&st(r.snapshot).then(N)},[r,g]);const se=async()=>{if(!r?.snapshot)return;b(!0),E(null);const x=await us(r.snapshot);b(!1),E(x),u("environment"),x.faithful?F.success("Environment restored and confirmed"):x.unrestoredCount>0?F.info(`${String(x.unrestoredCount)} conditions not restored — see Reproduction`):F.info("Reproduction finished — see Reproduction for what was confirmed")},dt=async()=>{if(!r)return;const x=new Set((r.snapshot?.rules??[]).map(A=>A.name)),[D,V]=await Promise.all([pe.list(),Kt.list()]),ne=V.find(A=>A.name===r.title)??V.find(A=>A.startUrl===r.snapshot?.url)??null;try{const A=rr({execution:r,events:o,evidence:d,interceptions:l,signals:p,rules:D.filter(ae=>x.has(ae.name)),workflow:ne,ledger:v});await navigator.clipboard.writeText(ir(A)),F.success(A.redactions.length===0?"Reproduction package copied":`Reproduction package copied — ${String(A.redactions.length)} things the recipient must supply themselves`)}catch(A){F.error(A.message)}},fe=()=>{if(!r)return;const x=gs(r,o,d,p??void 0);navigator.clipboard.writeText(`${x.title}

${x.body}`).then(()=>F.success("Bug report copied — paste it into a new bug")).catch(()=>F.error("Could not reach the clipboard"))};if(w==="loading")return t.jsx(Ge,{label:"Loading execution…"});if(w==="missing"||!r)return t.jsx(we,{title:"Execution",onBack:()=>s({name:"executions"}),children:t.jsx(Ot,{title:"That execution is gone",message:"Executions are kept within a fixed local budget, oldest shed first. Evidence uploaded to a test run is still in TCR.",onRetry:()=>s({name:"executions"}),retryLabel:"Back to executions"})});const xe=r.status==="failed"||r.status==="error",re=o.find(x=>x.severity==="error");return t.jsxs(we,{title:r.title,subtitle:`${r.status} · ${K(r.startedAt)}${r.finishedAt?` · ${de(r.finishedAt-r.startedAt)}`:""}`,onBack:()=>s({name:"executions"}),actions:t.jsxs(t.Fragment,{children:[t.jsx(J,{size:"sm",variant:"outline",className:"h-7",onClick:fe,title:"Copy a full bug report",children:t.jsx(ye,{className:"h-3 w-3"})}),r.snapshot&&g?.actionable===!0&&t.jsxs(J,{size:"sm",className:"h-7",loading:T,onClick:()=>void se(),children:[t.jsx(ce,{className:"h-3 w-3"}),"Reproduce"]})]}),sticky:t.jsx("div",{className:"-mx-1 flex gap-0.5 overflow-x-auto px-1",children:lr.map(x=>t.jsxs("button",{type:"button",onClick:()=>u(x.id),className:$("shrink-0 whitespace-nowrap rounded-md px-2 py-1 text-[10px] font-semibold transition-colors",y===x.id?"bg-dynamic-azure/12 text-dynamic-azure":"text-muted-foreground hover:text-foreground"),children:[x.label,x.id==="evidence"&&d.length>0?` ${String(d.length)}`:"",x.id==="timeline"&&o.length>0?` ${String(o.length)}`:""]},x.id))}),children:[y==="overview"&&t.jsxs(t.Fragment,{children:[xe&&t.jsxs("div",{className:"rounded-lg border border-alert-orange/40 bg-alert-orange/[0.06] p-2.5",children:[t.jsxs("p",{className:"flex items-center gap-1.5 text-[11px] font-semibold text-alert-orange",children:[t.jsx(W,{className:"h-3 w-3 shrink-0"}),r.status==="error"?"Execution errored":"Execution failed"]}),t.jsx("p",{className:"mt-1 break-words text-[10.5px] leading-relaxed text-foreground",children:r.error??r.summary??"No summary was recorded."}),ge.chain.length===0&&re&&re.message!==r.summary&&t.jsxs("p",{className:"mt-1.5 border-t border-alert-orange/20 pt-1.5 text-[10px] leading-relaxed text-muted-foreground",children:["First failure: ",re.message]})]}),xe&&t.jsx(Ts,{graph:ge,onOpenNode:x=>u(dr(x))}),t.jsx(j,{title:"Sync",children:t.jsx(Os,{executionId:r.id})}),t.jsx(j,{title:"Result",children:t.jsxs("div",{className:"rounded-lg bg-stroke/10 px-2.5 py-1.5 dark:bg-white/[0.03]",children:[t.jsx(L,{label:"Status",value:r.status}),t.jsx(L,{label:"Summary",value:r.summary??"—"}),t.jsx(L,{label:"Started",value:new Date(r.startedAt).toLocaleString()}),r.finishedAt&&t.jsx(L,{label:"Duration",value:de(r.finishedAt-r.startedAt)}),t.jsx(L,{label:"Events",value:String(r.eventCount)}),t.jsx(L,{label:"Evidence",value:String(r.evidenceCount)})]})}),r.snapshot&&t.jsx(j,{title:"Environment",actions:t.jsx("button",{type:"button",onClick:()=>u("environment"),className:"text-[10px] font-semibold text-dynamic-azure hover:underline",children:"Full snapshot"}),children:t.jsx("p",{className:"rounded-lg bg-stroke/10 px-2.5 py-2 text-[10.5px] leading-relaxed dark:bg-white/[0.03]",children:Wt(r.snapshot)||"Default environment — nothing was overridden."})}),l.length>0&&t.jsxs(j,{title:"Requests changed during this execution",children:[t.jsx("div",{className:"space-y-1",children:l.slice(0,6).map(x=>t.jsxs("div",{className:"flex items-start gap-1.5 rounded-lg border border-alert-orange/30 bg-alert-orange/[0.04] px-2 py-1.5",children:[t.jsx(me,{className:"mt-0.5 h-2.5 w-2.5 shrink-0 text-alert-orange"}),t.jsxs("span",{className:"min-w-0 flex-1",children:[t.jsxs("span",{className:"block text-[10px] font-semibold text-alert-orange",children:[x.ruleName," — ",x.action,x.status?` → ${String(x.status)}`:""]}),t.jsxs("span",{className:"block break-all font-mono text-[9px] text-muted-foreground",children:[x.method," ",x.url]})]})]},x.id))}),t.jsx("p",{className:"text-[10px] leading-relaxed text-muted-foreground",children:"These responses did not come from the server. If this execution failed, check whether a rule caused it before treating it as an application defect."})]}),t.jsx(j,{title:"Next",children:t.jsxs("div",{className:"grid grid-cols-2 gap-1.5",children:[t.jsx(H,{icon:_t,label:r.context?.testRunId?"Already in a run":"Save to TCR",hint:r.context?.testRunId?"Bound to a test run":"Create a test case and run",disabled:!!r.context?.testRunId,onClick:()=>h(!0)}),t.jsx(H,{icon:ye,label:"Create bug",hint:"Copy a full report",onClick:fe}),t.jsx(H,{icon:ce,label:"Reproduce",hint:g?.actionable===!0?"Recreate the environment":"Nothing to recreate",disabled:g?.actionable!==!0,onClick:()=>void se()}),t.jsx(H,{icon:ns,label:"Share reproduction",hint:"Portable state, secrets stripped",onClick:()=>void dt()}),t.jsx(H,{icon:Xe,label:"Compare",hint:"Against another execution",onClick:()=>u("environment")})]})})]}),y==="timeline"&&t.jsx(cr,{events:o,interceptions:l,evidence:d,startedAt:r.startedAt}),y==="evidence"&&t.jsx(ur,{evidence:d}),i&&t.jsx(Ut,{open:i,onClose:()=>h(!1),execution:r,events:o,evidence:d,onSaved:()=>{te()}}),y==="console"&&t.jsx(ze,{signals:p,kind:"console",startedAt:r.startedAt,finishedAt:r.finishedAt}),y==="network"&&t.jsx(ze,{signals:p,kind:"network",startedAt:r.startedAt,finishedAt:r.finishedAt}),y==="quality"&&t.jsxs(t.Fragment,{children:[t.jsx(Ms,{summary:P,comparison:lt,...M===null?{}:{previousLabel:`${M.title} · ${K(M.startedAt)}`}}),t.jsx(Vs,{report:I}),t.jsx(Bs,{report:O})]}),y==="environment"&&t.jsx(mr,{execution:r,plan:g,ledger:v,reproducing:T,onReproduce:()=>void se()})]})}function dr(e){switch(e.kind){case"request":case"trace":return"network";case"console":return"console";case"evidence":return"evidence";default:return"timeline"}}function cr({events:e,interceptions:s,evidence:r,startedAt:n}){const o=[...e.map(a=>({at:a.timestamp,kind:"event",event:a})),...s.map(a=>({at:a.timestamp,kind:"intercept",record:a}))].sort((a,l)=>a.at-l.at||(a.kind==="event"&&l.kind==="event"?a.event.sequence-l.event.sequence:0)),[m,d]=k.useState(null);return o.length===0?t.jsx(j,{children:t.jsxs("div",{className:"rounded-lg border border-dashed border-stroke px-3 py-6 text-center dark:border-stroke/30",children:[t.jsx("p",{className:"text-[11px] font-medium",children:"No events recorded"}),t.jsx("p",{className:"mt-1 text-[10px] text-muted-foreground",children:"This execution finished before anything was logged, or its events have been shed from local storage."})]})}):t.jsx(j,{title:`Timeline · ${String(o.length)}`,hint:"Offsets are from the start of the execution.",children:t.jsx("div",{className:"space-y-0.5",children:o.map((a,l)=>{const c=a.kind==="event"?a.event.id:a.record.id,p=pr(a.at-n),S=m===c;if(a.kind==="intercept")return t.jsxs("div",{className:"flex items-start gap-2 rounded px-1.5 py-1",children:[t.jsx("span",{className:"w-9 shrink-0 pt-0.5 font-mono text-[9px] text-muted-foreground",children:p}),t.jsx(me,{className:"mt-0.5 h-2.5 w-2.5 shrink-0 text-alert-orange"}),t.jsxs("span",{className:"min-w-0 flex-1",children:[t.jsxs("span",{className:"block text-[10.5px] leading-snug text-alert-orange",children:[a.record.action==="mock-response"?"API mocked":`Request ${a.record.action}`,a.record.status?` → ${String(a.record.status)}`:""]}),t.jsxs("span",{className:"block break-all font-mono text-[9px] text-muted-foreground",children:[a.record.method," ",a.record.url]})]})]},c);const w=a.event,f=r.filter(u=>w.evidenceIds?.includes(u.id)),y=w.meta&&Object.keys(w.meta).length>0||f.length>0;return t.jsxs("div",{children:[t.jsxs("button",{type:"button",onClick:()=>y&&d(S?null:c),className:$("flex w-full items-start gap-2 rounded px-1.5 py-1 text-left",y&&"hover:bg-stroke/15"),children:[t.jsx("span",{className:"w-9 shrink-0 pt-0.5 font-mono text-[9px] text-muted-foreground",children:p}),t.jsx("span",{className:$("mt-1 h-1.5 w-1.5 shrink-0 rounded-full",w.severity==="error"?"bg-alert-orange":w.severity==="warn"?"bg-amber-500":l===0?"bg-dynamic-azure":"bg-stroke")}),t.jsxs("span",{className:"min-w-0 flex-1",children:[t.jsx("span",{className:$("block break-words text-[10.5px] leading-snug",w.severity==="error"&&"font-medium text-alert-orange"),children:w.message}),t.jsx("span",{className:"block text-[9px] uppercase tracking-wide text-muted-foreground/70",children:w.type.toLowerCase().replace(/_/g," ")})]}),y&&t.jsx(Z,{className:$("mt-0.5 h-2.5 w-2.5 shrink-0 text-muted-foreground",S&&"rotate-180")})]}),S&&t.jsxs("div",{className:"ml-11 mb-1 space-y-1 rounded-lg bg-stroke/10 p-2 dark:bg-white/[0.03]",children:[w.meta&&Object.keys(w.meta).length>0&&t.jsx(he,{value:w.meta,label:"Event detail",collapsedByDefault:!1}),f.map(u=>t.jsx(it,{evidence:u},u.id))]})]},c)})})})}function ur({evidence:e}){const[s,r]=k.useState(null);if(e.length===0)return t.jsx(j,{children:t.jsxs("div",{className:"rounded-lg border border-dashed border-stroke px-3 py-6 text-center dark:border-stroke/30",children:[t.jsx("p",{className:"text-[11px] font-medium",children:"No evidence for this execution"}),t.jsx("p",{className:"mt-1 text-[10px] text-muted-foreground",children:"Nothing was captured, or its artifacts could not be stored."})]})});const n=new Set(["screenshot","responsive-capture","visual-diff"]),o=e.filter(a=>n.has(a.type)&&(a.signedUrl??a.localImageKey)),m=e.filter(a=>!o.includes(a)),d=o.map(a=>({id:a.id,label:a.label,...a.signedUrl===void 0?{}:{url:a.signedUrl},...a.localImageKey===void 0?{}:{localKey:a.localImageKey},...a.imageWidth===void 0?{}:{width:a.imageWidth},...a.imageHeight===void 0?{}:{height:a.imageHeight},...a.problem===void 0?{}:{problem:a.problem}}));return t.jsxs(t.Fragment,{children:[d.length>0&&t.jsxs(j,{title:`Images · ${String(d.length)}`,children:[t.jsx("div",{className:"grid grid-cols-2 gap-1.5",children:d.map((a,l)=>t.jsxs("div",{children:[t.jsx(Lt,{image:a,onOpen:()=>r(l)}),t.jsx("p",{className:"mt-1 truncate text-[9.5px]",children:a.label}),a.problem&&t.jsx("p",{className:"truncate text-[9px] text-amber-700 dark:text-amber-400",title:a.problem,children:a.problem})]},a.id))}),s!==null&&t.jsx(Mt,{images:d,startAt:s,onClose:()=>r(null)})]}),m.length>0&&t.jsx(j,{title:`Records · ${String(m.length)}`,children:t.jsx("div",{className:"space-y-1.5",children:m.map(a=>t.jsx(it,{evidence:a},a.id))})})]})}function it({evidence:e}){const[s,r]=k.useState(!1);return t.jsxs("div",{className:"rounded-lg border border-stroke/70 dark:border-stroke/25",children:[t.jsxs("button",{type:"button",onClick:()=>r(n=>!n),className:"flex w-full items-start gap-2 px-2 py-1.5 text-left",children:[t.jsx(ss,{className:"mt-0.5 h-3 w-3 shrink-0 text-muted-foreground"}),t.jsxs("span",{className:"min-w-0 flex-1",children:[t.jsx("span",{className:"block break-words text-[10.5px] font-medium leading-snug",children:e.label}),t.jsxs("span",{className:"block text-[9px] text-muted-foreground",children:[e.type," · ",e.source," · ",K(e.timestamp)]}),e.problem&&t.jsx("span",{className:"mt-0.5 block text-[9px] leading-snug text-amber-700 dark:text-amber-400",children:e.problem})]}),(e.data??e.signedUrl)&&t.jsx(Z,{className:$("mt-0.5 h-2.5 w-2.5 shrink-0 text-muted-foreground",s&&"rotate-180")})]}),s&&t.jsxs("div",{className:"border-t border-stroke/40 p-2 dark:border-stroke/20",children:[e.signedUrl&&t.jsxs("a",{href:e.signedUrl,target:"_blank",rel:"noreferrer noopener",className:"mb-1.5 flex items-center gap-1 text-[10px] text-dynamic-azure hover:underline",children:[t.jsx(Pt,{className:"h-2.5 w-2.5"}),"Open the stored artifact"]}),e.data&&t.jsx(he,{value:e.data,label:e.label,collapsedByDefault:!0})]})]})}function ze({signals:e,kind:s,startedAt:r,finishedAt:n}){if(e===null)return t.jsx(Ge,{label:"Reading captured logs…"});if(!e.capturing)return t.jsx(j,{children:t.jsx("div",{className:"rounded-lg border border-stroke/70 p-2.5 dark:border-stroke/25",children:t.jsxs("p",{className:"flex items-start gap-1.5 text-[10.5px] leading-relaxed text-muted-foreground",children:[t.jsx(Je,{className:"mt-0.5 h-3 w-3 shrink-0"}),t.jsxs("span",{children:["Application telemetry capture is off, so nothing was recorded. Turn it on from the execution toolbar — it is opt-in because it patches the page's own ",t.jsx("code",{children:"fetch"}),", XHR and console — then reload the page and run the tool again."]})]})})});const o=n??Date.now(),m=l=>l.filter(c=>c.timestamp>=r&&c.timestamp<=o);if(s==="console"){const l=m(e.consoleErrors);return t.jsxs(t.Fragment,{children:[t.jsx(De,{}),t.jsx(j,{title:`Console errors · ${String(l.length)}`,children:l.length===0?t.jsx("p",{className:"rounded-lg bg-stroke/10 px-2.5 py-2 text-[10.5px] text-muted-foreground dark:bg-white/[0.03]",children:"No console errors were captured while this execution ran."}):t.jsx("div",{className:"space-y-1.5",children:l.map((c,p)=>t.jsxs("div",{className:"rounded-lg border border-alert-orange/30 bg-alert-orange/[0.04] p-2",children:[t.jsxs("p",{className:"flex items-start gap-1.5 break-words text-[10px] leading-relaxed",children:[t.jsx(et,{className:"mt-0.5 h-2.5 w-2.5 shrink-0 text-alert-orange"}),t.jsx("span",{className:"min-w-0 font-mono",children:c.message})]}),c.stack&&t.jsx("pre",{className:"mt-1 max-h-24 overflow-auto rounded bg-stroke/15 p-1.5 font-mono text-[9px] leading-snug dark:bg-white/[0.04]",children:c.stack})]},`${String(c.timestamp)}-${String(p)}`))})})]})}const d=m(e.requests),a=d.filter(l=>l.failed||l.status>=400);return t.jsxs(t.Fragment,{children:[t.jsx(De,{}),a.length>0&&t.jsx(j,{title:`Failed requests · ${String(a.length)}`,children:t.jsx("div",{className:"space-y-1",children:a.map((l,c)=>t.jsx(Fe,{request:l},`f-${String(c)}`))})}),t.jsx(j,{title:`All requests · ${String(d.length)}`,children:d.length===0?t.jsx("p",{className:"rounded-lg bg-stroke/10 px-2.5 py-2 text-[10.5px] text-muted-foreground dark:bg-white/[0.03]",children:"No requests were captured while this execution ran."}):t.jsx("div",{className:"space-y-1",children:d.slice(0,80).map((l,c)=>t.jsx(Fe,{request:l},String(c)))})})]})}function De(){return t.jsxs("div",{className:"flex items-start gap-1.5 rounded-lg bg-stroke/10 px-2.5 py-2 dark:bg-white/[0.03]",children:[t.jsx(Je,{className:"mt-0.5 h-2.5 w-2.5 shrink-0 text-muted-foreground"}),t.jsx("p",{className:"text-[10px] leading-relaxed text-muted-foreground",children:"Read live from the current capture session and filtered to this execution's time window. Telemetry is a rolling buffer, so an older execution may show nothing here even though it recorded plenty at the time — the full logs are shipped to TCR by the telemetry upload."})]})}function Fe({request:e}){const s=e.failed||e.status>=400;return t.jsxs("div",{className:$("flex items-start gap-1.5 rounded px-1.5 py-1",s?"bg-alert-orange/[0.06]":"hover:bg-stroke/10"),children:[t.jsx(Ke,{className:$("mt-0.5 h-2.5 w-2.5 shrink-0",s?"text-alert-orange":"text-muted-foreground")}),t.jsxs("span",{className:"min-w-0 flex-1",children:[t.jsxs("span",{className:"flex items-baseline gap-1.5",children:[t.jsx("span",{className:$("shrink-0 font-mono text-[9px] font-semibold",s?"text-alert-orange":"text-muted-foreground"),children:e.failed&&e.status===0?"ERR":String(e.status)}),t.jsx("span",{className:"shrink-0 font-mono text-[9px] text-muted-foreground",children:e.method}),t.jsx("span",{className:"min-w-0 flex-1 truncate font-mono text-[9.5px]",children:hr(e.url)}),t.jsx("span",{className:"shrink-0 text-[9px] text-muted-foreground",children:de(e.duration)})]}),e.traceId&&t.jsxs("span",{className:"mt-0.5 flex items-center gap-1 font-mono text-[9px] text-muted-foreground",children:[t.jsx(Xt,{className:"h-2 w-2"}),"trace ",e.traceId.slice(0,16),"…"]})]})]})}function mr({execution:e,plan:s,ledger:r,reproducing:n,onReproduce:o}){if(!e.snapshot)return t.jsx(j,{children:t.jsxs("div",{className:"rounded-lg border border-dashed border-stroke px-3 py-6 text-center dark:border-stroke/30",children:[t.jsx("p",{className:"text-[11px] font-medium",children:"No environment snapshot"}),t.jsx("p",{className:"mt-1 text-[10px] text-muted-foreground",children:"This execution ran before the snapshot could be taken — usually because there was no targetable tab."})]})});const m=ue(e.snapshot);return t.jsxs(t.Fragment,{children:[t.jsx(j,{title:"Snapshot",hint:"What the environment actually was when this execution started.",children:t.jsx("div",{className:"space-y-0.5 rounded-lg bg-stroke/10 p-2.5 dark:bg-white/[0.03]",children:m.map((d,a)=>t.jsx("p",{className:"break-words font-mono text-[10px] leading-relaxed",children:d},String(a)))})}),r&&t.jsx(Rs,{ledger:r}),t.jsx(gr,{execution:e}),s&&t.jsxs(j,{title:"Reproduce",hint:"What can and cannot be recreated on this machine.",children:[t.jsx("div",{className:"space-y-1",children:s.steps.map(d=>t.jsxs("div",{className:$("rounded-lg border px-2 py-1.5",d.verdict==="will-apply"&&"border-emerald-500/30 bg-emerald-500/[0.04]",d.verdict==="partial"&&"border-amber-500/30 bg-amber-500/[0.05]",d.verdict==="cannot"&&"border-stroke/60 dark:border-stroke/25",d.verdict==="nothing-to-do"&&"border-stroke/60 dark:border-stroke/25"),children:[t.jsxs("p",{className:"flex items-baseline gap-1.5",children:[t.jsx("span",{className:$("shrink-0 text-[9px] font-semibold uppercase tracking-wide",d.verdict==="will-apply"&&"text-emerald-700 dark:text-emerald-400",d.verdict==="partial"&&"text-amber-700 dark:text-amber-400",d.verdict==="cannot"&&"text-muted-foreground"),children:d.verdict==="will-apply"?"will apply":d.verdict==="partial"?"partial":"cannot"}),t.jsx("span",{className:"min-w-0 break-words text-[10.5px]",children:d.label})]}),d.note&&t.jsx("p",{className:"mt-0.5 text-[9.5px] leading-relaxed text-muted-foreground",children:d.note})]},d.key))}),t.jsxs(J,{size:"sm",className:"h-7 w-full",loading:n,disabled:!s.actionable,onClick:o,children:[t.jsx(ce,{className:"h-3 w-3"}),s.actionable?"Recreate this environment":"Nothing here can be recreated"]})]}),e.snapshot.device&&t.jsx(j,{title:"Device",children:t.jsxs("div",{className:"rounded-lg bg-stroke/10 px-2.5 py-1.5 dark:bg-white/[0.03]",children:[t.jsx(L,{label:"Browser",value:`${e.snapshot.device.browser} ${e.snapshot.device.browserVersion}`}),t.jsx(L,{label:"Engine",value:e.snapshot.device.engine}),t.jsx(L,{label:"OS",value:`${e.snapshot.device.os} ${e.snapshot.device.osVersion}`}),t.jsx(L,{label:"Screen",value:`${String(e.snapshot.device.resolution.width)} × ${String(e.snapshot.device.resolution.height)} @ ${String(e.snapshot.device.devicePixelRatio)}×`}),t.jsx(L,{label:"Timezone",value:e.snapshot.device.timezone}),t.jsx(L,{label:"Language",value:e.snapshot.device.language})]})}),t.jsx(j,{title:"Raw snapshot",children:t.jsx(he,{value:e.snapshot,label:"Environment snapshot",collapsedByDefault:!0})})]})}function H({icon:e,label:s,hint:r,onClick:n,disabled:o}){return t.jsxs("button",{type:"button",onClick:n,disabled:o,className:$("flex flex-col items-start gap-0.5 rounded-lg border border-stroke/70 px-2.5 py-2 text-left transition-colors dark:border-stroke/25",o?"cursor-not-allowed opacity-50":"hover:border-dynamic-azure/50 hover:bg-dynamic-azure/[0.04]"),children:[t.jsxs("span",{className:"flex items-center gap-1.5",children:[t.jsx(e,{className:"h-3 w-3 text-muted-foreground"}),t.jsx("span",{className:"text-[10.5px] font-semibold",children:s})]}),t.jsx("span",{className:"text-[9.5px] text-muted-foreground",children:r})]})}function pr(e){if(e<0)return"00:00";const s=Math.floor(e/1e3),r=Math.floor(s/60),n=s%60;return`${String(r).padStart(2,"0")}:${String(n).padStart(2,"0")}`}function hr(e){try{const s=new URL(e);return`${s.pathname}${s.search}`}catch{return e}}function gr({execution:e}){const[s,r]=k.useState(null),[n,o]=k.useState(null),[m,d]=k.useState(!1);k.useEffect(()=>{!m||s!==null||He(40,e.projectId).then(c=>r(c.filter(p=>p.id!==e.id&&p.snapshot!==void 0)))},[m,s,e.id,e.projectId]);const a=s?.find(c=>c.id===n)??null,l=a?.snapshot&&e.snapshot?Ys(a.snapshot,e.snapshot):null;return m?t.jsxs(j,{title:"Compare",hint:"Pick the run to compare against. Differences are listed first.",actions:t.jsx("button",{type:"button",onClick:()=>{d(!1),o(null)},className:"text-[10px] font-semibold text-dynamic-azure hover:underline",children:"Close"}),children:[s===null&&t.jsx("p",{className:"text-[10px] text-muted-foreground",children:"Loading executions…"}),s!==null&&s.length===0&&t.jsxs("div",{className:"rounded-lg border border-dashed border-stroke px-3 py-4 text-center dark:border-stroke/30",children:[t.jsx("p",{className:"text-[11px] font-medium",children:"Nothing to compare against"}),t.jsx("p",{className:"mt-1 text-[10px] leading-relaxed text-muted-foreground",children:"No other execution in this workspace recorded an environment snapshot. Comparison needs two."})]}),s!==null&&s.length>0&&t.jsx("div",{className:"space-y-1",children:s.slice(0,12).map(c=>t.jsx("button",{type:"button",onClick:()=>o(c.id===n?null:c.id),className:$("flex min-h-6 w-full items-start justify-between gap-2 rounded-lg border px-2 py-1.5 text-left",c.id===n?"border-dynamic-azure/50 bg-dynamic-azure/[0.05]":"border-stroke hover:border-dynamic-azure/40 dark:border-stroke/30"),children:t.jsxs("span",{className:"min-w-0 flex-1",children:[t.jsx("span",{className:"block break-words text-[10.5px] font-medium leading-snug",children:c.title}),t.jsxs("span",{className:"block text-[9px] text-muted-foreground",children:[c.status," · ",K(c.startedAt)]})]})},c.id))}),l&&a&&t.jsx(Es,{diff:l,beforeLabel:`${a.title} · ${K(a.startedAt)}`,afterLabel:`${e.title} · ${K(e.startedAt)}`})]}):t.jsx(j,{children:t.jsxs(J,{size:"sm",variant:"outline",className:"h-7 w-full",onClick:()=>d(!0),children:[t.jsx(Xe,{className:"h-3 w-3"}),"Compare with another execution"]})})}export{Ar as ExecutionDetailScreen};
//# sourceMappingURL=chunk-eTI_I1BA.js.map
