brakit 0.10.0 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,90 +1,90 @@
1
- (function(){'use strict';var wr=Object.defineProperty;var Rr=Object.getOwnPropertyDescriptor;var u=(o,s,t,e)=>{for(var r=e>1?void 0:e?Rr(s,t):s,i=o.length-1,n;i>=0;i--)(n=o[i])&&(r=(e?n(s,t,r):n(r))||r);return e&&r&&wr(s,t,r),r};var zt=globalThis,Zt=zt.ShadowRoot&&(zt.ShadyCSS===void 0||zt.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,os=Symbol(),is=new WeakMap,Jt=class{constructor(s,t,e){if(this._$cssResult$=true,e!==os)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=s,this.t=t;}get styleSheet(){let s=this.o,t=this.t;if(Zt&&s===void 0){let e=t!==void 0&&t.length===1;e&&(s=is.get(t)),s===void 0&&((this.o=s=new CSSStyleSheet).replaceSync(this.cssText),e&&is.set(t,s));}return s}toString(){return this.cssText}},ns=o=>new Jt(typeof o=="string"?o:o+"",void 0,os);var as=(o,s)=>{if(Zt)o.adoptedStyleSheets=s.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(let t of s){let e=document.createElement("style"),r=zt.litNonce;r!==void 0&&e.setAttribute("nonce",r),e.textContent=t.cssText,o.appendChild(e);}},ye=Zt?o=>o:o=>o instanceof CSSStyleSheet?(s=>{let t="";for(let e of s.cssRules)t+=e.cssText;return ns(t)})(o):o;var{is:Ar,defineProperty:Ir,getOwnPropertyDescriptor:Cr,getOwnPropertyNames:Lr,getOwnPropertySymbols:Mr,getPrototypeOf:Nr}=Object,K=globalThis,ls=K.trustedTypes,Or=ls?ls.emptyScript:"",kr=K.reactiveElementPolyfillSupport,Mt=(o,s)=>o,Nt={toAttribute(o,s){switch(s){case Boolean:o=o?Or:null;break;case Object:case Array:o=o==null?o:JSON.stringify(o);}return o},fromAttribute(o,s){let t=o;switch(s){case Boolean:t=o!==null;break;case Number:t=o===null?null:Number(o);break;case Object:case Array:try{t=JSON.parse(o);}catch{t=null;}}return t}},te=(o,s)=>!Ar(o,s),cs={attribute:true,type:String,converter:Nt,reflect:false,useDefault:false,hasChanged:te};Symbol.metadata??(Symbol.metadata=Symbol("metadata")),K.litPropertyMetadata??(K.litPropertyMetadata=new WeakMap);var j=class extends HTMLElement{static addInitializer(s){this._$Ei(),(this.l??(this.l=[])).push(s);}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(s,t=cs){if(t.state&&(t.attribute=false),this._$Ei(),this.prototype.hasOwnProperty(s)&&((t=Object.create(t)).wrapped=true),this.elementProperties.set(s,t),!t.noAccessor){let e=Symbol(),r=this.getPropertyDescriptor(s,e,t);r!==void 0&&Ir(this.prototype,s,r);}}static getPropertyDescriptor(s,t,e){let{get:r,set:i}=Cr(this.prototype,s)??{get(){return this[t]},set(n){this[t]=n;}};return {get:r,set(n){let l=r?.call(this);i?.call(this,n),this.requestUpdate(s,l,e);},configurable:true,enumerable:true}}static getPropertyOptions(s){return this.elementProperties.get(s)??cs}static _$Ei(){if(this.hasOwnProperty(Mt("elementProperties")))return;let s=Nr(this);s.finalize(),s.l!==void 0&&(this.l=[...s.l]),this.elementProperties=new Map(s.elementProperties);}static finalize(){if(this.hasOwnProperty(Mt("finalized")))return;if(this.finalized=true,this._$Ei(),this.hasOwnProperty(Mt("properties"))){let t=this.properties,e=[...Lr(t),...Mr(t)];for(let r of e)this.createProperty(r,t[r]);}let s=this[Symbol.metadata];if(s!==null){let t=litPropertyMetadata.get(s);if(t!==void 0)for(let[e,r]of t)this.elementProperties.set(e,r);}this._$Eh=new Map;for(let[t,e]of this.elementProperties){let r=this._$Eu(t,e);r!==void 0&&this._$Eh.set(r,t);}this.elementStyles=this.finalizeStyles(this.styles);}static finalizeStyles(s){let t=[];if(Array.isArray(s)){let e=new Set(s.flat(1/0).reverse());for(let r of e)t.unshift(ye(r));}else s!==void 0&&t.push(ye(s));return t}static _$Eu(s,t){let e=t.attribute;return e===false?void 0:typeof e=="string"?e:typeof s=="string"?s.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=false,this.hasUpdated=false,this._$Em=null,this._$Ev();}_$Ev(){this._$ES=new Promise(s=>this.enableUpdating=s),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(s=>s(this));}addController(s){(this._$EO??(this._$EO=new Set)).add(s),this.renderRoot!==void 0&&this.isConnected&&s.hostConnected?.();}removeController(s){this._$EO?.delete(s);}_$E_(){let s=new Map,t=this.constructor.elementProperties;for(let e of t.keys())this.hasOwnProperty(e)&&(s.set(e,this[e]),delete this[e]);s.size>0&&(this._$Ep=s);}createRenderRoot(){let s=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return as(s,this.constructor.elementStyles),s}connectedCallback(){this.renderRoot??(this.renderRoot=this.createRenderRoot()),this.enableUpdating(true),this._$EO?.forEach(s=>s.hostConnected?.());}enableUpdating(s){}disconnectedCallback(){this._$EO?.forEach(s=>s.hostDisconnected?.());}attributeChangedCallback(s,t,e){this._$AK(s,e);}_$ET(s,t){let e=this.constructor.elementProperties.get(s),r=this.constructor._$Eu(s,e);if(r!==void 0&&e.reflect===true){let i=(e.converter?.toAttribute!==void 0?e.converter:Nt).toAttribute(t,e.type);this._$Em=s,i==null?this.removeAttribute(r):this.setAttribute(r,i),this._$Em=null;}}_$AK(s,t){let e=this.constructor,r=e._$Eh.get(s);if(r!==void 0&&this._$Em!==r){let i=e.getPropertyOptions(r),n=typeof i.converter=="function"?{fromAttribute:i.converter}:i.converter?.fromAttribute!==void 0?i.converter:Nt;this._$Em=r;let l=n.fromAttribute(t,i.type);this[r]=l??this._$Ej?.get(r)??l,this._$Em=null;}}requestUpdate(s,t,e,r=false,i){if(s!==void 0){let n=this.constructor;if(r===false&&(i=this[s]),e??(e=n.getPropertyOptions(s)),!((e.hasChanged??te)(i,t)||e.useDefault&&e.reflect&&i===this._$Ej?.get(s)&&!this.hasAttribute(n._$Eu(s,e))))return;this.C(s,t,e);}this.isUpdatePending===false&&(this._$ES=this._$EP());}C(s,t,{useDefault:e,reflect:r,wrapped:i},n){e&&!(this._$Ej??(this._$Ej=new Map)).has(s)&&(this._$Ej.set(s,n??t??this[s]),i!==true||n!==void 0)||(this._$AL.has(s)||(this.hasUpdated||e||(t=void 0),this._$AL.set(s,t)),r===true&&this._$Em!==s&&(this._$Eq??(this._$Eq=new Set)).add(s));}async _$EP(){this.isUpdatePending=true;try{await this._$ES;}catch(t){Promise.reject(t);}let s=this.scheduleUpdate();return s!=null&&await s,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??(this.renderRoot=this.createRenderRoot()),this._$Ep){for(let[r,i]of this._$Ep)this[r]=i;this._$Ep=void 0;}let e=this.constructor.elementProperties;if(e.size>0)for(let[r,i]of e){let{wrapped:n}=i,l=this[r];n!==true||this._$AL.has(r)||l===void 0||this.C(r,void 0,i,l);}}let s=false,t=this._$AL;try{s=this.shouldUpdate(t),s?(this.willUpdate(t),this._$EO?.forEach(e=>e.hostUpdate?.()),this.update(t)):this._$EM();}catch(e){throw s=false,this._$EM(),e}s&&this._$AE(t);}willUpdate(s){}_$AE(s){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=true,this.firstUpdated(s)),this.updated(s);}_$EM(){this._$AL=new Map,this.isUpdatePending=false;}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(s){return true}update(s){this._$Eq&&(this._$Eq=this._$Eq.forEach(t=>this._$ET(t,this[t]))),this._$EM();}updated(s){}firstUpdated(s){}};j.elementStyles=[],j.shadowRootOptions={mode:"open"},j[Mt("elementProperties")]=new Map,j[Mt("finalized")]=new Map,kr?.({ReactiveElement:j}),(K.reactiveElementVersions??(K.reactiveElementVersions=[])).push("2.1.2");var kt=globalThis,ds=o=>o,ee=kt.trustedTypes,ps=ee?ee.createPolicy("lit-html",{createHTML:o=>o}):void 0,gs="$lit$",z=`lit$${Math.random().toFixed(9).slice(2)}$`,bs="?"+z,Dr=`<${bs}>`,ot=document,Dt=()=>ot.createComment(""),Ht=o=>o===null||typeof o!="object"&&typeof o!="function",Re=Array.isArray,Hr=o=>Re(o)||typeof o?.[Symbol.iterator]=="function",_e=`[
2
- \f\r]`,Ot=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,hs=/-->/g,us=/>/g,rt=RegExp(`>|${_e}(?:([^\\s"'>=/]+)(${_e}*=${_e}*(?:[^
3
- \f\r"'\`<>=]|("|')|))|$)`,"g"),ms=/'/g,fs=/"/g,Es=/^(?:script|style|textarea|title)$/i,Ae=o=>(s,...t)=>({_$litType$:o,strings:s,values:t}),a=Ae(1),O=Ae(2),Y=Symbol.for("lit-noChange"),p=Symbol.for("lit-nothing"),vs=new WeakMap,it=ot.createTreeWalker(ot,129);function ys(o,s){if(!Re(o)||!o.hasOwnProperty("raw"))throw Error("invalid template strings array");return ps!==void 0?ps.createHTML(s):s}var Pr=(o,s)=>{let t=o.length-1,e=[],r,i=s===2?"<svg>":s===3?"<math>":"",n=Ot;for(let l=0;l<t;l++){let c=o[l],d,h,m=-1,v=0;for(;v<c.length&&(n.lastIndex=v,h=n.exec(c),h!==null);)v=n.lastIndex,n===Ot?h[1]==="!--"?n=hs:h[1]!==void 0?n=us:h[2]!==void 0?(Es.test(h[2])&&(r=RegExp("</"+h[2],"g")),n=rt):h[3]!==void 0&&(n=rt):n===rt?h[0]===">"?(n=r??Ot,m=-1):h[1]===void 0?m=-2:(m=n.lastIndex-h[2].length,d=h[1],n=h[3]===void 0?rt:h[3]==='"'?fs:ms):n===fs||n===ms?n=rt:n===hs||n===us?n=Ot:(n=rt,r=void 0);let x=n===rt&&o[l+1].startsWith("/>")?" ":"";i+=n===Ot?c+Dr:m>=0?(e.push(d),c.slice(0,m)+gs+c.slice(m)+z+x):c+z+(m===-2?l:x);}return [ys(o,i+(o[t]||"<?>")+(s===2?"</svg>":s===3?"</math>":"")),e]},Pt=class o{constructor({strings:s,_$litType$:t},e){let r;this.parts=[];let i=0,n=0,l=s.length-1,c=this.parts,[d,h]=Pr(s,t);if(this.el=o.createElement(d,e),it.currentNode=this.el.content,t===2||t===3){let m=this.el.content.firstChild;m.replaceWith(...m.childNodes);}for(;(r=it.nextNode())!==null&&c.length<l;){if(r.nodeType===1){if(r.hasAttributes())for(let m of r.getAttributeNames())if(m.endsWith(gs)){let v=h[n++],x=r.getAttribute(m).split(z),y=/([.?@])?(.*)/.exec(v);c.push({type:1,index:i,name:y[2],strings:x,ctor:y[1]==="."?xe:y[1]==="?"?Se:y[1]==="@"?Te:ht}),r.removeAttribute(m);}else m.startsWith(z)&&(c.push({type:6,index:i}),r.removeAttribute(m));if(Es.test(r.tagName)){let m=r.textContent.split(z),v=m.length-1;if(v>0){r.textContent=ee?ee.emptyScript:"";for(let x=0;x<v;x++)r.append(m[x],Dt()),it.nextNode(),c.push({type:2,index:++i});r.append(m[v],Dt());}}}else if(r.nodeType===8)if(r.data===bs)c.push({type:2,index:i});else {let m=-1;for(;(m=r.data.indexOf(z,m+1))!==-1;)c.push({type:7,index:i}),m+=z.length-1;}i++;}}static createElement(s,t){let e=ot.createElement("template");return e.innerHTML=s,e}};function pt(o,s,t=o,e){if(s===Y)return s;let r=e!==void 0?t._$Co?.[e]:t._$Cl,i=Ht(s)?void 0:s._$litDirective$;return r?.constructor!==i&&(r?._$AO?.(false),i===void 0?r=void 0:(r=new i(o),r._$AT(o,t,e)),e!==void 0?(t._$Co??(t._$Co=[]))[e]=r:t._$Cl=r),r!==void 0&&(s=pt(o,r._$AS(o,s.values),r,e)),s}var $e=class{constructor(s,t){this._$AV=[],this._$AN=void 0,this._$AD=s,this._$AM=t;}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(s){let{el:{content:t},parts:e}=this._$AD,r=(s?.creationScope??ot).importNode(t,true);it.currentNode=r;let i=it.nextNode(),n=0,l=0,c=e[0];for(;c!==void 0;){if(n===c.index){let d;c.type===2?d=new qt(i,i.nextSibling,this,s):c.type===1?d=new c.ctor(i,c.name,c.strings,this,s):c.type===6&&(d=new we(i,this,s)),this._$AV.push(d),c=e[++l];}n!==c?.index&&(i=it.nextNode(),n++);}return it.currentNode=ot,r}p(s){let t=0;for(let e of this._$AV)e!==void 0&&(e.strings!==void 0?(e._$AI(s,e,t),t+=e.strings.length-2):e._$AI(s[t])),t++;}},qt=class o{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(s,t,e,r){this.type=2,this._$AH=p,this._$AN=void 0,this._$AA=s,this._$AB=t,this._$AM=e,this.options=r,this._$Cv=r?.isConnected??true;}get parentNode(){let s=this._$AA.parentNode,t=this._$AM;return t!==void 0&&s?.nodeType===11&&(s=t.parentNode),s}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(s,t=this){s=pt(this,s,t),Ht(s)?s===p||s==null||s===""?(this._$AH!==p&&this._$AR(),this._$AH=p):s!==this._$AH&&s!==Y&&this._(s):s._$litType$!==void 0?this.$(s):s.nodeType!==void 0?this.T(s):Hr(s)?this.k(s):this._(s);}O(s){return this._$AA.parentNode.insertBefore(s,this._$AB)}T(s){this._$AH!==s&&(this._$AR(),this._$AH=this.O(s));}_(s){this._$AH!==p&&Ht(this._$AH)?this._$AA.nextSibling.data=s:this.T(ot.createTextNode(s)),this._$AH=s;}$(s){let{values:t,_$litType$:e}=s,r=typeof e=="number"?this._$AC(s):(e.el===void 0&&(e.el=Pt.createElement(ys(e.h,e.h[0]),this.options)),e);if(this._$AH?._$AD===r)this._$AH.p(t);else {let i=new $e(r,this),n=i.u(this.options);i.p(t),this.T(n),this._$AH=i;}}_$AC(s){let t=vs.get(s.strings);return t===void 0&&vs.set(s.strings,t=new Pt(s)),t}k(s){Re(this._$AH)||(this._$AH=[],this._$AR());let t=this._$AH,e,r=0;for(let i of s)r===t.length?t.push(e=new o(this.O(Dt()),this.O(Dt()),this,this.options)):e=t[r],e._$AI(i),r++;r<t.length&&(this._$AR(e&&e._$AB.nextSibling,r),t.length=r);}_$AR(s=this._$AA.nextSibling,t){for(this._$AP?.(false,true,t);s!==this._$AB;){let e=ds(s).nextSibling;ds(s).remove(),s=e;}}setConnected(s){this._$AM===void 0&&(this._$Cv=s,this._$AP?.(s));}},ht=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(s,t,e,r,i){this.type=1,this._$AH=p,this._$AN=void 0,this.element=s,this.name=t,this._$AM=r,this.options=i,e.length>2||e[0]!==""||e[1]!==""?(this._$AH=Array(e.length-1).fill(new String),this.strings=e):this._$AH=p;}_$AI(s,t=this,e,r){let i=this.strings,n=false;if(i===void 0)s=pt(this,s,t,0),n=!Ht(s)||s!==this._$AH&&s!==Y,n&&(this._$AH=s);else {let l=s,c,d;for(s=i[0],c=0;c<i.length-1;c++)d=pt(this,l[e+c],t,c),d===Y&&(d=this._$AH[c]),n||(n=!Ht(d)||d!==this._$AH[c]),d===p?s=p:s!==p&&(s+=(d??"")+i[c+1]),this._$AH[c]=d;}n&&!r&&this.j(s);}j(s){s===p?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,s??"");}},xe=class extends ht{constructor(){super(...arguments),this.type=3;}j(s){this.element[this.name]=s===p?void 0:s;}},Se=class extends ht{constructor(){super(...arguments),this.type=4;}j(s){this.element.toggleAttribute(this.name,!!s&&s!==p);}},Te=class extends ht{constructor(s,t,e,r,i){super(s,t,e,r,i),this.type=5;}_$AI(s,t=this){if((s=pt(this,s,t,0)??p)===Y)return;let e=this._$AH,r=s===p&&e!==p||s.capture!==e.capture||s.once!==e.once||s.passive!==e.passive,i=s!==p&&(e===p||r);r&&this.element.removeEventListener(this.name,this,e),i&&this.element.addEventListener(this.name,this,s),this._$AH=s;}handleEvent(s){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,s):this._$AH.handleEvent(s);}},we=class{constructor(s,t,e){this.element=s,this.type=6,this._$AN=void 0,this._$AM=t,this.options=e;}get _$AU(){return this._$AM._$AU}_$AI(s){pt(this,s);}};var qr=kt.litHtmlPolyfillSupport;qr?.(Pt,qt),(kt.litHtmlVersions??(kt.litHtmlVersions=[])).push("3.3.2");var _s=(o,s,t)=>{let e=t?.renderBefore??s,r=e._$litPart$;if(r===void 0){let i=t?.renderBefore??null;e._$litPart$=r=new qt(s.insertBefore(Dt(),i),i,void 0,t??{});}return r._$AI(o),r};var Ut=globalThis,E=class extends j{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0;}createRenderRoot(){var t;let s=super.createRenderRoot();return (t=this.renderOptions).renderBefore??(t.renderBefore=s.firstChild),s}update(s){let t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(s),this._$Do=_s(t,this.renderRoot,this.renderOptions);}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(true);}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(false);}render(){return Y}};E._$litElement$=true,E.finalized=true,Ut.litElementHydrateSupport?.({LitElement:E});var Ur=Ut.litElementPolyfillSupport;Ur?.({LitElement:E});(Ut.litElementVersions??(Ut.litElementVersions=[])).push("4.2.2");var S=o=>(s,t)=>{t!==void 0?t.addInitializer(()=>{customElements.define(o,s);}):customElements.define(o,s);};var Fr={attribute:true,type:String,converter:Nt,reflect:false,hasChanged:te},Gr=(o=Fr,s,t)=>{let{kind:e,metadata:r}=t,i=globalThis.litPropertyMetadata.get(r);if(i===void 0&&globalThis.litPropertyMetadata.set(r,i=new Map),e==="setter"&&((o=Object.create(o)).wrapped=true),i.set(t.name,o),e==="accessor"){let{name:n}=t;return {set(l){let c=s.get.call(this);s.set.call(this,l),this.requestUpdate(n,c,o,true,l);},init(l){return l!==void 0&&this.C(n,void 0,o,l),l}}}if(e==="setter"){let{name:n}=t;return function(l){let c=this[n];s.call(this,l),this.requestUpdate(n,c,o,true,l);}}throw Error("Unsupported decorator location: "+e)};function L(o){return (s,t)=>typeof t=="object"?Gr(o,s,t):((e,r,i)=>{let n=r.hasOwnProperty(i);return r.constructor.createProperty(i,e),n?Object.getOwnPropertyDescriptor(r,i):void 0})(o,s,t)}function b(o){return L({...o,state:true,attribute:false})}var Ft=class extends E{constructor(){super(...arguments);this.method="";}createRenderRoot(){return this}render(){let t=this.method.toUpperCase();return a`<span class="method-badge method-badge-${t}">${t}</span>`}};u([L()],Ft.prototype,"method",2),Ft=u([S("bk-method-badge")],Ft);var P="/__brakit/api",F="/__brakit",w={flows:`${P}/flows`,requests:`${P}/requests`,events:`${P}/events`,clear:`${P}/clear`,fetches:`${P}/fetches`,errors:`${P}/errors`,logs:`${P}/logs`,queries:`${P}/queries`,metricsLive:`${P}/metrics/live`,insights:`${P}/insights`,tab:`${P}/tab`,activity:`${P}/activity`,graph:`${P}/graph`};var ut="polling",re="static",Br="auth-handshake",Wr="auth-check",Qr="middleware",Gt={[Br]:1,[Wr]:1,[Qr]:1};var ie="fetch";var oe="error_event",ne="query",ae="issues";var Ie={overview:"Overview",actions:"Actions",requests:"Requests",fetches:"Server Fetches",queries:"Queries",errors:"Errors",logs:"Logs",performance:"Performance",security:"Security",graph:"Graph"},Ce={overview:"Live summary of your application",actions:"User actions captured as sequences of HTTP requests",requests:"All HTTP requests proxied through brakit",fetches:"Outbound HTTP calls made by your server to external services",queries:"Database queries executed during request handling",errors:"Unhandled exceptions and errors thrown by your application",logs:"Console output from your application",performance:"Endpoint health and response time trends",security:"Security findings and recommendations",graph:"Runtime dependency graph of your application"};var Me=100,mt=300,ft=800,Ne=2e3,Oe=100,ke=50,De=500;var J="__all__",pe={SELECT:"var(--blue)",INSERT:"var(--green)",UPDATE:"var(--amber)",DELETE:"var(--red)",COUNT:"var(--text-muted)"},As={error:"var(--red)",warn:"var(--amber)",info:"var(--blue)",debug:"var(--text-muted)",log:"var(--text-dim)"},qe=["#2563eb","#7c3aed","#16a34a","#d97706","#dc2626","#0891b2","#ea580c","#c026d3","#059669","#db2777"],Bt={green:"#4ade80",amber:"#fbbf24",red:"#f87171"},gt=[{max:Me,label:"Fast",color:"var(--green)",bg:"rgba(22,163,74,0.08)",border:"rgba(22,163,74,0.2)"},{max:mt,label:"Good",color:"var(--green)",bg:"rgba(22,163,74,0.06)",border:"rgba(22,163,74,0.15)"},{max:ft,label:"OK",color:"var(--amber)",bg:"rgba(217,119,6,0.06)",border:"rgba(217,119,6,0.15)"},{max:Ne,label:"Slow",color:"var(--red)",bg:"rgba(220,38,38,0.06)",border:"rgba(220,38,38,0.15)"},{max:1/0,label:"Critical",color:"var(--red)",bg:"rgba(220,38,38,0.08)",border:"rgba(220,38,38,0.2)"}],Is="rgba(228,228,231,0.8)",Ue="rgba(113,113,122,0.7)",Cs="10px monospace",Fe="9px monospace";var Ls={top:16,right:16,bottom:28,left:52},Ms={fetch:"var(--blue)",log:"var(--text-muted)",error:"var(--red)",query:"var(--accent)"},Ns={fetch:"FETCH",log:"LOG",error:"ERROR",query:"QUERY"},Os=new Set(["cookie","set-cookie","authorization","proxy-authorization","x-api-key","x-auth-token"]),ks={400:"Bad Request",401:"Unauthorized",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",408:"Timeout",409:"Conflict",422:"Unprocessable",429:"Too Many Requests",500:"Internal Server Error",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout"},Ds=new Set(["host","connection","accept-encoding"]),Z={critical:{icon:"\u2717",cls:"critical",sort:0},warning:{icon:"\u26A0",cls:"warning",sort:1},info:{icon:"\u2139",cls:"info",sort:2}};function _(o){return o<1e3?o+"ms":(o/1e3).toFixed(1)+"s"}function et(o){return !o||o===0?"":o<1024?o+"b":(o/1024).toFixed(1)+"kb"}function tt(o){return o?o.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;"):""}function bt(o){return o>=500?"status-pill-5xx":o>=400?"status-pill-4xx":o>=300?"status-pill-3xx":"status-pill-2xx"}function Hs(o){return ks[o]||(o>=500?"Server Error":o>=400?"Client Error":"OK")}function jr(o,s){if(Os.has(o.toLowerCase())){let t=String(s);return t.length<=8?"****":t.slice(0,4)+"..."+t.slice(-4)+" ("+t.length+" chars)"}return String(s)}function Et(o){return !o||Object.keys(o).length===0?'<span style="color:var(--text-muted)">No headers</span>':Object.entries(o).map(([s,t])=>'<span class="json-key">'+tt(s)+"</span>: "+tt(jr(s,t))).join(`
4
- `)}function nt(o){if(!o)return '<span style="color:var(--text-muted)">No body</span>';try{let s=JSON.parse(o);return Yr(JSON.stringify(s,null,2))}catch{return tt(o)}}function Yr(o){return tt(o).replace(/("(?:[^"\\]|\\.)*")(\s*:)?|\b(true|false)\b|\bnull\b|(-?\d+\.?\d*(?:[eE][+-]?\d+)?)/g,(s,t,e,r,i)=>t?e?'<span class="json-key">'+t+"</span>"+e:'<span class="json-str">'+t+"</span>":r?'<span class="json-bool">'+s+"</span>":i?'<span class="json-num">'+s+"</span>":s==="null"?'<span class="json-null">null</span>':s)}var Wt=class extends E{constructor(){super(...arguments);this.code=0;}createRenderRoot(){return this}render(){let t=bt(this.code);return a`<span class="status-pill ${t}">${this.code}</span>`}};u([L({type:Number})],Wt.prototype,"code",2),Wt=u([S("bk-status-pill")],Wt);var Qt=class extends E{constructor(){super(...arguments);this.ms=0;}createRenderRoot(){return this}render(){return a`<span class="req-duration">${_(this.ms)}</span>`}};u([L({type:Number})],Qt.prototype,"ms",2),Qt=u([S("bk-duration-label")],Qt);var yt=class extends E{constructor(){super(...arguments);this.title="";this.subtitle="";}createRenderRoot(){return this}render(){return a`
1
+ (function(){'use strict';var Or=Object.defineProperty;var Nr=Object.getOwnPropertyDescriptor;var u=(o,r,t,e)=>{for(var s=e>1?void 0:e?Nr(r,t):r,i=o.length-1,n;i>=0;i--)(n=o[i])&&(s=(e?n(r,t,s):n(s))||s);return e&&s&&Or(r,t,s),s};var oe=globalThis,ae=oe.ShadowRoot&&(oe.ShadyCSS===void 0||oe.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,ms=Symbol(),us=new WeakMap,ne=class{constructor(r,t,e){if(this._$cssResult$=true,e!==ms)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=r,this.t=t;}get styleSheet(){let r=this.o,t=this.t;if(ae&&r===void 0){let e=t!==void 0&&t.length===1;e&&(r=us.get(t)),r===void 0&&((this.o=r=new CSSStyleSheet).replaceSync(this.cssText),e&&us.set(t,r));}return r}toString(){return this.cssText}},fs=o=>new ne(typeof o=="string"?o:o+"",void 0,ms);var vs=(o,r)=>{if(ae)o.adoptedStyleSheets=r.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(let t of r){let e=document.createElement("style"),s=oe.litNonce;s!==void 0&&e.setAttribute("nonce",s),e.textContent=t.cssText,o.appendChild(e);}},Ae=ae?o=>o:o=>o instanceof CSSStyleSheet?(r=>{let t="";for(let e of r.cssRules)t+=e.cssText;return fs(t)})(o):o;var{is:Dr,defineProperty:Pr,getOwnPropertyDescriptor:Hr,getOwnPropertyNames:qr,getOwnPropertySymbols:Ur,getPrototypeOf:Fr}=Object,et=globalThis,gs=et.trustedTypes,Gr=gs?gs.emptyScript:"",Br=et.reactiveElementPolyfillSupport,Pt=(o,r)=>o,Ht={toAttribute(o,r){switch(r){case Boolean:o=o?Gr:null;break;case Object:case Array:o=o==null?o:JSON.stringify(o);}return o},fromAttribute(o,r){let t=o;switch(r){case Boolean:t=o!==null;break;case Number:t=o===null?null:Number(o);break;case Object:case Array:try{t=JSON.parse(o);}catch{t=null;}}return t}},le=(o,r)=>!Dr(o,r),bs={attribute:true,type:String,converter:Ht,reflect:false,useDefault:false,hasChanged:le};Symbol.metadata??(Symbol.metadata=Symbol("metadata")),et.litPropertyMetadata??(et.litPropertyMetadata=new WeakMap);var K=class extends HTMLElement{static addInitializer(r){this._$Ei(),(this.l??(this.l=[])).push(r);}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(r,t=bs){if(t.state&&(t.attribute=false),this._$Ei(),this.prototype.hasOwnProperty(r)&&((t=Object.create(t)).wrapped=true),this.elementProperties.set(r,t),!t.noAccessor){let e=Symbol(),s=this.getPropertyDescriptor(r,e,t);s!==void 0&&Pr(this.prototype,r,s);}}static getPropertyDescriptor(r,t,e){let{get:s,set:i}=Hr(this.prototype,r)??{get(){return this[t]},set(n){this[t]=n;}};return {get:s,set(n){let a=s?.call(this);i?.call(this,n),this.requestUpdate(r,a,e);},configurable:true,enumerable:true}}static getPropertyOptions(r){return this.elementProperties.get(r)??bs}static _$Ei(){if(this.hasOwnProperty(Pt("elementProperties")))return;let r=Fr(this);r.finalize(),r.l!==void 0&&(this.l=[...r.l]),this.elementProperties=new Map(r.elementProperties);}static finalize(){if(this.hasOwnProperty(Pt("finalized")))return;if(this.finalized=true,this._$Ei(),this.hasOwnProperty(Pt("properties"))){let t=this.properties,e=[...qr(t),...Ur(t)];for(let s of e)this.createProperty(s,t[s]);}let r=this[Symbol.metadata];if(r!==null){let t=litPropertyMetadata.get(r);if(t!==void 0)for(let[e,s]of t)this.elementProperties.set(e,s);}this._$Eh=new Map;for(let[t,e]of this.elementProperties){let s=this._$Eu(t,e);s!==void 0&&this._$Eh.set(s,t);}this.elementStyles=this.finalizeStyles(this.styles);}static finalizeStyles(r){let t=[];if(Array.isArray(r)){let e=new Set(r.flat(1/0).reverse());for(let s of e)t.unshift(Ae(s));}else r!==void 0&&t.push(Ae(r));return t}static _$Eu(r,t){let e=t.attribute;return e===false?void 0:typeof e=="string"?e:typeof r=="string"?r.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=false,this.hasUpdated=false,this._$Em=null,this._$Ev();}_$Ev(){this._$ES=new Promise(r=>this.enableUpdating=r),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(r=>r(this));}addController(r){(this._$EO??(this._$EO=new Set)).add(r),this.renderRoot!==void 0&&this.isConnected&&r.hostConnected?.();}removeController(r){this._$EO?.delete(r);}_$E_(){let r=new Map,t=this.constructor.elementProperties;for(let e of t.keys())this.hasOwnProperty(e)&&(r.set(e,this[e]),delete this[e]);r.size>0&&(this._$Ep=r);}createRenderRoot(){let r=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return vs(r,this.constructor.elementStyles),r}connectedCallback(){this.renderRoot??(this.renderRoot=this.createRenderRoot()),this.enableUpdating(true),this._$EO?.forEach(r=>r.hostConnected?.());}enableUpdating(r){}disconnectedCallback(){this._$EO?.forEach(r=>r.hostDisconnected?.());}attributeChangedCallback(r,t,e){this._$AK(r,e);}_$ET(r,t){let e=this.constructor.elementProperties.get(r),s=this.constructor._$Eu(r,e);if(s!==void 0&&e.reflect===true){let i=(e.converter?.toAttribute!==void 0?e.converter:Ht).toAttribute(t,e.type);this._$Em=r,i==null?this.removeAttribute(s):this.setAttribute(s,i),this._$Em=null;}}_$AK(r,t){let e=this.constructor,s=e._$Eh.get(r);if(s!==void 0&&this._$Em!==s){let i=e.getPropertyOptions(s),n=typeof i.converter=="function"?{fromAttribute:i.converter}:i.converter?.fromAttribute!==void 0?i.converter:Ht;this._$Em=s;let a=n.fromAttribute(t,i.type);this[s]=a??this._$Ej?.get(s)??a,this._$Em=null;}}requestUpdate(r,t,e,s=false,i){if(r!==void 0){let n=this.constructor;if(s===false&&(i=this[r]),e??(e=n.getPropertyOptions(r)),!((e.hasChanged??le)(i,t)||e.useDefault&&e.reflect&&i===this._$Ej?.get(r)&&!this.hasAttribute(n._$Eu(r,e))))return;this.C(r,t,e);}this.isUpdatePending===false&&(this._$ES=this._$EP());}C(r,t,{useDefault:e,reflect:s,wrapped:i},n){e&&!(this._$Ej??(this._$Ej=new Map)).has(r)&&(this._$Ej.set(r,n??t??this[r]),i!==true||n!==void 0)||(this._$AL.has(r)||(this.hasUpdated||e||(t=void 0),this._$AL.set(r,t)),s===true&&this._$Em!==r&&(this._$Eq??(this._$Eq=new Set)).add(r));}async _$EP(){this.isUpdatePending=true;try{await this._$ES;}catch(t){Promise.reject(t);}let r=this.scheduleUpdate();return r!=null&&await r,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??(this.renderRoot=this.createRenderRoot()),this._$Ep){for(let[s,i]of this._$Ep)this[s]=i;this._$Ep=void 0;}let e=this.constructor.elementProperties;if(e.size>0)for(let[s,i]of e){let{wrapped:n}=i,a=this[s];n!==true||this._$AL.has(s)||a===void 0||this.C(s,void 0,i,a);}}let r=false,t=this._$AL;try{r=this.shouldUpdate(t),r?(this.willUpdate(t),this._$EO?.forEach(e=>e.hostUpdate?.()),this.update(t)):this._$EM();}catch(e){throw r=false,this._$EM(),e}r&&this._$AE(t);}willUpdate(r){}_$AE(r){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=true,this.firstUpdated(r)),this.updated(r);}_$EM(){this._$AL=new Map,this.isUpdatePending=false;}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(r){return true}update(r){this._$Eq&&(this._$Eq=this._$Eq.forEach(t=>this._$ET(t,this[t]))),this._$EM();}updated(r){}firstUpdated(r){}};K.elementStyles=[],K.shadowRootOptions={mode:"open"},K[Pt("elementProperties")]=new Map,K[Pt("finalized")]=new Map,Br?.({ReactiveElement:K}),(et.reactiveElementVersions??(et.reactiveElementVersions=[])).push("2.1.2");var Ut=globalThis,Es=o=>o,ce=Ut.trustedTypes,ys=ce?ce.createPolicy("lit-html",{createHTML:o=>o}):void 0,ws="$lit$",st=`lit$${Math.random().toFixed(9).slice(2)}$`,Rs="?"+st,Wr=`<${Rs}>`,ct=document,Ft=()=>ct.createComment(""),Gt=o=>o===null||typeof o!="object"&&typeof o!="function",Ne=Array.isArray,jr=o=>Ne(o)||typeof o?.[Symbol.iterator]=="function",Ce=`[
2
+ \f\r]`,qt=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,$s=/-->/g,_s=/>/g,at=RegExp(`>|${Ce}(?:([^\\s"'>=/]+)(${Ce}*=${Ce}*(?:[^
3
+ \f\r"'\`<>=]|("|')|))|$)`,"g"),xs=/'/g,Ss=/"/g,As=/^(?:script|style|textarea|title)$/i,De=o=>(r,...t)=>({_$litType$:o,strings:r,values:t}),l=De(1),O=De(2),z=Symbol.for("lit-noChange"),d=Symbol.for("lit-nothing"),Ts=new WeakMap,lt=ct.createTreeWalker(ct,129);function Cs(o,r){if(!Ne(o)||!o.hasOwnProperty("raw"))throw Error("invalid template strings array");return ys!==void 0?ys.createHTML(r):r}var Qr=(o,r)=>{let t=o.length-1,e=[],s,i=r===2?"<svg>":r===3?"<math>":"",n=qt;for(let a=0;a<t;a++){let c=o[a],p,h,m=-1,f=0;for(;f<c.length&&(n.lastIndex=f,h=n.exec(c),h!==null);)f=n.lastIndex,n===qt?h[1]==="!--"?n=$s:h[1]!==void 0?n=_s:h[2]!==void 0?(As.test(h[2])&&(s=RegExp("</"+h[2],"g")),n=at):h[3]!==void 0&&(n=at):n===at?h[0]===">"?(n=s??qt,m=-1):h[1]===void 0?m=-2:(m=n.lastIndex-h[2].length,p=h[1],n=h[3]===void 0?at:h[3]==='"'?Ss:xs):n===Ss||n===xs?n=at:n===$s||n===_s?n=qt:(n=at,s=void 0);let S=n===at&&o[a+1].startsWith("/>")?" ":"";i+=n===qt?c+Wr:m>=0?(e.push(p),c.slice(0,m)+ws+c.slice(m)+st+S):c+st+(m===-2?a:S);}return [Cs(o,i+(o[t]||"<?>")+(r===2?"</svg>":r===3?"</math>":"")),e]},Bt=class o{constructor({strings:r,_$litType$:t},e){let s;this.parts=[];let i=0,n=0,a=r.length-1,c=this.parts,[p,h]=Qr(r,t);if(this.el=o.createElement(p,e),lt.currentNode=this.el.content,t===2||t===3){let m=this.el.content.firstChild;m.replaceWith(...m.childNodes);}for(;(s=lt.nextNode())!==null&&c.length<a;){if(s.nodeType===1){if(s.hasAttributes())for(let m of s.getAttributeNames())if(m.endsWith(ws)){let f=h[n++],S=s.getAttribute(m).split(st),R=/([.?@])?(.*)/.exec(f);c.push({type:1,index:i,name:R[2],strings:S,ctor:R[1]==="."?Le:R[1]==="?"?Me:R[1]==="@"?ke:gt}),s.removeAttribute(m);}else m.startsWith(st)&&(c.push({type:6,index:i}),s.removeAttribute(m));if(As.test(s.tagName)){let m=s.textContent.split(st),f=m.length-1;if(f>0){s.textContent=ce?ce.emptyScript:"";for(let S=0;S<f;S++)s.append(m[S],Ft()),lt.nextNode(),c.push({type:2,index:++i});s.append(m[f],Ft());}}}else if(s.nodeType===8)if(s.data===Rs)c.push({type:2,index:i});else {let m=-1;for(;(m=s.data.indexOf(st,m+1))!==-1;)c.push({type:7,index:i}),m+=st.length-1;}i++;}}static createElement(r,t){let e=ct.createElement("template");return e.innerHTML=r,e}};function vt(o,r,t=o,e){if(r===z)return r;let s=e!==void 0?t._$Co?.[e]:t._$Cl,i=Gt(r)?void 0:r._$litDirective$;return s?.constructor!==i&&(s?._$AO?.(false),i===void 0?s=void 0:(s=new i(o),s._$AT(o,t,e)),e!==void 0?(t._$Co??(t._$Co=[]))[e]=s:t._$Cl=s),s!==void 0&&(r=vt(o,s._$AS(o,r.values),s,e)),r}var Ie=class{constructor(r,t){this._$AV=[],this._$AN=void 0,this._$AD=r,this._$AM=t;}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(r){let{el:{content:t},parts:e}=this._$AD,s=(r?.creationScope??ct).importNode(t,true);lt.currentNode=s;let i=lt.nextNode(),n=0,a=0,c=e[0];for(;c!==void 0;){if(n===c.index){let p;c.type===2?p=new Wt(i,i.nextSibling,this,r):c.type===1?p=new c.ctor(i,c.name,c.strings,this,r):c.type===6&&(p=new Oe(i,this,r)),this._$AV.push(p),c=e[++a];}n!==c?.index&&(i=lt.nextNode(),n++);}return lt.currentNode=ct,s}p(r){let t=0;for(let e of this._$AV)e!==void 0&&(e.strings!==void 0?(e._$AI(r,e,t),t+=e.strings.length-2):e._$AI(r[t])),t++;}},Wt=class o{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(r,t,e,s){this.type=2,this._$AH=d,this._$AN=void 0,this._$AA=r,this._$AB=t,this._$AM=e,this.options=s,this._$Cv=s?.isConnected??true;}get parentNode(){let r=this._$AA.parentNode,t=this._$AM;return t!==void 0&&r?.nodeType===11&&(r=t.parentNode),r}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(r,t=this){r=vt(this,r,t),Gt(r)?r===d||r==null||r===""?(this._$AH!==d&&this._$AR(),this._$AH=d):r!==this._$AH&&r!==z&&this._(r):r._$litType$!==void 0?this.$(r):r.nodeType!==void 0?this.T(r):jr(r)?this.k(r):this._(r);}O(r){return this._$AA.parentNode.insertBefore(r,this._$AB)}T(r){this._$AH!==r&&(this._$AR(),this._$AH=this.O(r));}_(r){this._$AH!==d&&Gt(this._$AH)?this._$AA.nextSibling.data=r:this.T(ct.createTextNode(r)),this._$AH=r;}$(r){let{values:t,_$litType$:e}=r,s=typeof e=="number"?this._$AC(r):(e.el===void 0&&(e.el=Bt.createElement(Cs(e.h,e.h[0]),this.options)),e);if(this._$AH?._$AD===s)this._$AH.p(t);else {let i=new Ie(s,this),n=i.u(this.options);i.p(t),this.T(n),this._$AH=i;}}_$AC(r){let t=Ts.get(r.strings);return t===void 0&&Ts.set(r.strings,t=new Bt(r)),t}k(r){Ne(this._$AH)||(this._$AH=[],this._$AR());let t=this._$AH,e,s=0;for(let i of r)s===t.length?t.push(e=new o(this.O(Ft()),this.O(Ft()),this,this.options)):e=t[s],e._$AI(i),s++;s<t.length&&(this._$AR(e&&e._$AB.nextSibling,s),t.length=s);}_$AR(r=this._$AA.nextSibling,t){for(this._$AP?.(false,true,t);r!==this._$AB;){let e=Es(r).nextSibling;Es(r).remove(),r=e;}}setConnected(r){this._$AM===void 0&&(this._$Cv=r,this._$AP?.(r));}},gt=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(r,t,e,s,i){this.type=1,this._$AH=d,this._$AN=void 0,this.element=r,this.name=t,this._$AM=s,this.options=i,e.length>2||e[0]!==""||e[1]!==""?(this._$AH=Array(e.length-1).fill(new String),this.strings=e):this._$AH=d;}_$AI(r,t=this,e,s){let i=this.strings,n=false;if(i===void 0)r=vt(this,r,t,0),n=!Gt(r)||r!==this._$AH&&r!==z,n&&(this._$AH=r);else {let a=r,c,p;for(r=i[0],c=0;c<i.length-1;c++)p=vt(this,a[e+c],t,c),p===z&&(p=this._$AH[c]),n||(n=!Gt(p)||p!==this._$AH[c]),p===d?r=d:r!==d&&(r+=(p??"")+i[c+1]),this._$AH[c]=p;}n&&!s&&this.j(r);}j(r){r===d?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,r??"");}},Le=class extends gt{constructor(){super(...arguments),this.type=3;}j(r){this.element[this.name]=r===d?void 0:r;}},Me=class extends gt{constructor(){super(...arguments),this.type=4;}j(r){this.element.toggleAttribute(this.name,!!r&&r!==d);}},ke=class extends gt{constructor(r,t,e,s,i){super(r,t,e,s,i),this.type=5;}_$AI(r,t=this){if((r=vt(this,r,t,0)??d)===z)return;let e=this._$AH,s=r===d&&e!==d||r.capture!==e.capture||r.once!==e.once||r.passive!==e.passive,i=r!==d&&(e===d||s);s&&this.element.removeEventListener(this.name,this,e),i&&this.element.addEventListener(this.name,this,r),this._$AH=r;}handleEvent(r){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,r):this._$AH.handleEvent(r);}},Oe=class{constructor(r,t,e){this.element=r,this.type=6,this._$AN=void 0,this._$AM=t,this.options=e;}get _$AU(){return this._$AM._$AU}_$AI(r){vt(this,r);}};var Yr=Ut.litHtmlPolyfillSupport;Yr?.(Bt,Wt),(Ut.litHtmlVersions??(Ut.litHtmlVersions=[])).push("3.3.2");var Is=(o,r,t)=>{let e=t?.renderBefore??r,s=e._$litPart$;if(s===void 0){let i=t?.renderBefore??null;e._$litPart$=s=new Wt(r.insertBefore(Ft(),i),i,void 0,t??{});}return s._$AI(o),s};var jt=globalThis,E=class extends K{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0;}createRenderRoot(){var t;let r=super.createRenderRoot();return (t=this.renderOptions).renderBefore??(t.renderBefore=r.firstChild),r}update(r){let t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(r),this._$Do=Is(t,this.renderRoot,this.renderOptions);}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(true);}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(false);}render(){return z}};E._$litElement$=true,E.finalized=true,jt.litElementHydrateSupport?.({LitElement:E});var Xr=jt.litElementPolyfillSupport;Xr?.({LitElement:E});(jt.litElementVersions??(jt.litElementVersions=[])).push("4.2.2");var _=o=>(r,t)=>{t!==void 0?t.addInitializer(()=>{customElements.define(o,r);}):customElements.define(o,r);};var Vr={attribute:true,type:String,converter:Ht,reflect:false,hasChanged:le},Kr=(o=Vr,r,t)=>{let{kind:e,metadata:s}=t,i=globalThis.litPropertyMetadata.get(s);if(i===void 0&&globalThis.litPropertyMetadata.set(s,i=new Map),e==="setter"&&((o=Object.create(o)).wrapped=true),i.set(t.name,o),e==="accessor"){let{name:n}=t;return {set(a){let c=r.get.call(this);r.set.call(this,a),this.requestUpdate(n,c,o,true,a);},init(a){return a!==void 0&&this.C(n,void 0,o,a),a}}}if(e==="setter"){let{name:n}=t;return function(a){let c=this[n];r.call(this,a),this.requestUpdate(n,c,o,true,a);}}throw Error("Unsupported decorator location: "+e)};function L(o){return (r,t)=>typeof t=="object"?Kr(o,r,t):((e,s,i)=>{let n=s.hasOwnProperty(i);return s.constructor.createProperty(i,e),n?Object.getOwnPropertyDescriptor(s,i):void 0})(o,r,t)}function b(o){return L({...o,state:true,attribute:false})}var Qt=class extends E{constructor(){super(...arguments);this.method="";}createRenderRoot(){return this}render(){let t=this.method.toUpperCase();return l`<span class="method-badge method-badge-${t}">${t}</span>`}};u([L()],Qt.prototype,"method",2),Qt=u([_("bk-method-badge")],Qt);var q="/__brakit/api",U="/__brakit",T={flows:`${q}/flows`,requests:`${q}/requests`,events:`${q}/events`,clear:`${q}/clear`,fetches:`${q}/fetches`,errors:`${q}/errors`,logs:`${q}/logs`,queries:`${q}/queries`,metricsLive:`${q}/metrics/live`,insights:`${q}/insights`,tab:`${q}/tab`,activity:`${q}/activity`,graph:`${q}/graph`};var bt="polling",pe="static",zr="auth-handshake",Jr="auth-check",Zr="middleware",Yt={[zr]:1,[Jr]:1,[Zr]:1};var he="fetch";var ue="error_event",me="query",fe="issues";var Pe={overview:"Overview",actions:"Actions",insights:"Insights",performance:"Performance",graph:"Graph",explorer:"Explorer",requests:"Requests",fetches:"Server Fetches",queries:"Queries",errors:"Errors",logs:"Logs",security:"Security"},He={overview:"Live summary of your application",actions:"User actions captured as sequences of HTTP requests",insights:"Security findings, error patterns, and issue tracking",performance:"Endpoint health and response time trends",graph:"Runtime dependency graph of your application",explorer:"Browse raw requests, fetches, queries, logs, and errors",requests:"All HTTP requests proxied through brakit",fetches:"Outbound HTTP calls made by your server to external services",queries:"Database queries executed during request handling",errors:"Unhandled exceptions and errors thrown by your application",logs:"Console output from your application",security:"Security findings and recommendations"},ve=[{key:"requests",label:"Requests"},{key:"fetches",label:"Fetches"},{key:"queries",label:"Queries"},{key:"logs",label:"Logs"},{key:"errors",label:"Errors"}];var Ls=new Set(["exposed-secret","token-in-url","stack-trace-leak","error-info-leak","insecure-cookie","sensitive-logs","cors-credentials","response-pii-leak"]),Ms=new Set(["slow-endpoint","n1","high-query-count"]);function Xt(o){let r=o.issue.rule;return Ls.has(r)?"security":Ms.has(r)?"performance":"reliability"}var N={CLEAR_CONFIRM:"This will clear all data including performance metrics history. Continue?",CLEARED_TOAST:"Cleared",EMPTY_TITLE:"Waiting for requests...",EMPTY_SUBTITLE_OVERVIEW:"Start using your app to see your dashboard here",ALL_CLEAR:"All clear",ALL_CLEAR_DETAIL:"No issues detected",NO_ACTIONS:"No actions captured yet",NO_REQUEST_DATA:"No request data yet",ALL_FAST:"All fast",NO_SLOW_ENDPOINTS:"No slow endpoints detected",ZERO_ERRORS:"0 errors",ALL_REQUESTS_OK:"All requests successful",BUILD_GRAPH:"Navigate your app to build the graph",REVIEW_RECOMMENDED:"review recommended"};var Fe=100,yt=300,$t=800,Ge=2e3,Be=100,We=50,je=500;var rt="__all__",ti={SELECT:"var(--blue)",INSERT:"var(--green)",UPDATE:"var(--amber)",DELETE:"var(--red)",OTHER:"var(--text-muted)"},be=ti,ei={error:"var(--red)",warn:"var(--amber)",info:"var(--blue)",debug:"var(--text-muted)",log:"var(--text-dim)"},qs=ei,Xe=["#2563eb","#7c3aed","#16a34a","#d97706","#dc2626","#0891b2","#ea580c","#c026d3","#059669","#db2777"],Vt={green:"#4ade80",amber:"#fbbf24",red:"#f87171"},xt=[{max:Fe,label:"Fast",color:"var(--green)",bg:"var(--green-bg)",border:"var(--green-border)"},{max:yt,label:"Good",color:"var(--green)",bg:"var(--green-bg-subtle)",border:"var(--green-border-subtle)"},{max:$t,label:"OK",color:"var(--amber)",bg:"var(--amber-bg)",border:"var(--amber-border)"},{max:Ge,label:"Slow",color:"var(--red)",bg:"var(--red-bg)",border:"var(--red-border)"},{max:1/0,label:"Critical",color:"var(--red)",bg:"var(--red-bg)",border:"var(--red-border)"}],Us="rgba(228,228,231,0.8)",Ve="rgba(113,113,122,0.7)",Fs="10px monospace",Ke="9px monospace";var Gs={top:16,right:16,bottom:28,left:52},Bs={fetch:"var(--blue)",log:"var(--text-muted)",error:"var(--red)",query:"var(--accent)"},Ws={fetch:"FETCH",log:"LOG",error:"ERROR",query:"QUERY"},js=new Set(["cookie","set-cookie","authorization","proxy-authorization","x-api-key","x-auth-token"]),Qs={400:"Bad Request",401:"Unauthorized",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",408:"Timeout",409:"Conflict",422:"Unprocessable",429:"Too Many Requests",500:"Internal Server Error",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout"},Ys=new Set(["host","connection","accept-encoding"]),Y={critical:{icon:"\u2717",cls:"critical",sort:0},warning:{icon:"\u26A0",cls:"warning",sort:1},info:{icon:"\u2139",cls:"info",sort:2}};function y(o){return o<1e3?o+"ms":(o/1e3).toFixed(1)+"s"}function ot(o){return !o||o===0?"":o<1024?o+"b":(o/1024).toFixed(1)+"kb"}function it(o){return o?o.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;"):""}function St(o){return o>=500?"status-pill-5xx":o>=400?"status-pill-4xx":o>=300?"status-pill-3xx":"status-pill-2xx"}function Xs(o){return Qs[o]||(o>=500?"Server Error":o>=400?"Client Error":"OK")}function si(o,r){if(js.has(o.toLowerCase())){let t=String(r);return t.length<=8?"****":t.slice(0,4)+"..."+t.slice(-4)+" ("+t.length+" chars)"}return String(r)}function Tt(o){return !o||Object.keys(o).length===0?'<span style="color:var(--text-muted)">No headers</span>':Object.entries(o).map(([r,t])=>'<span class="json-key">'+it(r)+"</span>: "+it(si(r,t))).join(`
4
+ `)}function dt(o){if(!o)return '<span style="color:var(--text-muted)">No body</span>';try{let r=JSON.parse(o);return ri(JSON.stringify(r,null,2))}catch{return it(o)}}function ri(o){return it(o).replace(/("(?:[^"\\]|\\.)*")(\s*:)?|\b(true|false)\b|\bnull\b|(-?\d+\.?\d*(?:[eE][+-]?\d+)?)/g,(r,t,e,s,i)=>t?e?'<span class="json-key">'+t+"</span>"+e:'<span class="json-str">'+t+"</span>":s?'<span class="json-bool">'+r+"</span>":i?'<span class="json-num">'+r+"</span>":r==="null"?'<span class="json-null">null</span>':r)}var Kt=class extends E{constructor(){super(...arguments);this.code=0;}createRenderRoot(){return this}render(){let t=St(this.code);return l`<span class="status-pill ${t}">${this.code}</span>`}};u([L({type:Number})],Kt.prototype,"code",2),Kt=u([_("bk-status-pill")],Kt);var zt=class extends E{constructor(){super(...arguments);this.ms=0;}createRenderRoot(){return this}render(){return l`<span class="req-duration">${y(this.ms)}</span>`}};u([L({type:Number})],zt.prototype,"ms",2),zt=u([_("bk-duration-label")],zt);var wt=class extends E{constructor(){super(...arguments);this.title="";this.subtitle="";}createRenderRoot(){return this}render(){return l`
5
5
  <div class="empty">
6
6
  <span class="empty-title">${this.title}</span>
7
7
  <span class="empty-sub">${this.subtitle}</span>
8
8
  </div>
9
- `}};u([L()],yt.prototype,"title",2),u([L()],yt.prototype,"subtitle",2),yt=u([S("bk-empty-state")],yt);var D=class extends E{constructor(){super(...arguments);this.message="";this.visible=false;}createRenderRoot(){return this}static show(t){let e=document.querySelector("bk-toast");e&&e.showMessage(t);}showMessage(t){this.hideTimer&&clearTimeout(this.hideTimer),this.message=t,this.visible=true,this.hideTimer=setTimeout(()=>{this.visible=false;},2e3);}render(){return a`<div class="toast ${this.visible?"show":""}">${this.message}</div>`}};u([b()],D.prototype,"message",2),u([b()],D.prototype,"visible",2),D=u([S("bk-toast")],D);var at=class extends E{constructor(){super(...arguments);this.text="";this.label="Copy";this.toastMessage="Copied";}createRenderRoot(){return this}async copy(t){t.stopPropagation();try{await navigator.clipboard.writeText(this.text),D.show(this.toastMessage);}catch{}}render(){return a`<button class="query-detail-copy" @click=${this.copy}>${this.label}</button>`}};u([L()],at.prototype,"text",2),u([L()],at.prototype,"label",2),u([L({attribute:"toast-message"})],at.prototype,"toastMessage",2),at=u([S("bk-copy-button")],at);var lt=class extends E{constructor(){super(...arguments);this.value="";this.label="";this.color="";}createRenderRoot(){return this}render(){return a`
9
+ `}};u([L()],wt.prototype,"title",2),u([L()],wt.prototype,"subtitle",2),wt=u([_("bk-empty-state")],wt);var D=class extends E{constructor(){super(...arguments);this.message="";this.visible=false;}createRenderRoot(){return this}static show(t){let e=document.querySelector("bk-toast");e&&e.showMessage(t);}showMessage(t){this.hideTimer&&clearTimeout(this.hideTimer),this.message=t,this.visible=true,this.hideTimer=setTimeout(()=>{this.visible=false;},2e3);}render(){return l`<div class="toast ${this.visible?"show":""}">${this.message}</div>`}};u([b()],D.prototype,"message",2),u([b()],D.prototype,"visible",2),D=u([_("bk-toast")],D);var pt=class extends E{constructor(){super(...arguments);this.text="";this.label="Copy";this.toastMessage="Copied";}createRenderRoot(){return this}async copy(t){t.stopPropagation();try{await navigator.clipboard.writeText(this.text),D.show(this.toastMessage);}catch{}}render(){return l`<button class="query-detail-copy" @click=${this.copy}>${this.label}</button>`}};u([L()],pt.prototype,"text",2),u([L()],pt.prototype,"label",2),u([L({attribute:"toast-message"})],pt.prototype,"toastMessage",2),pt=u([_("bk-copy-button")],pt);var ht=class extends E{constructor(){super(...arguments);this.value="";this.label="";this.color="";}createRenderRoot(){return this}render(){return l`
10
10
  <div class="fetch-stat">
11
11
  <span class="fetch-stat-value" style="color:${this.color}">${this.value}</span>
12
12
  <span class="fetch-stat-label">${this.label}</span>
13
13
  </div>
14
- `}};u([L()],lt.prototype,"value",2),u([L()],lt.prototype,"label",2),u([L()],lt.prototype,"color",2),lt=u([S("bk-stat-card")],lt);var st=class extends Event{constructor(s,t,e,r){super("context-request",{bubbles:true,composed:true}),this.context=s,this.contextTarget=t,this.callback=e,this.subscribe=r??false;}};var _t=class{constructor(s,t,e,r){if(this.subscribe=false,this.provided=false,this.value=void 0,this.t=(i,n)=>{this.unsubscribe&&(this.unsubscribe!==n&&(this.provided=false,this.unsubscribe()),this.subscribe||this.unsubscribe()),this.value=i,this.host.requestUpdate(),this.provided&&!this.subscribe||(this.provided=true,this.callback&&this.callback(i,n)),this.unsubscribe=n;},this.host=s,t.context!==void 0){let i=t;this.context=i.context,this.callback=i.callback,this.subscribe=i.subscribe??false;}else this.context=t,this.callback=e,this.subscribe=r??false;this.host.addController(this);}hostConnected(){this.dispatchRequest();}hostDisconnected(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=void 0);}dispatchRequest(){this.host.dispatchEvent(new st(this.context,this.host,this.t,this.subscribe));}};var he=class{get value(){return this.o}set value(s){this.setValue(s);}setValue(s,t=false){let e=t||!Object.is(s,this.o);this.o=s,e&&this.updateObservers();}constructor(s){this.subscriptions=new Map,this.updateObservers=()=>{for(let[t,{disposer:e}]of this.subscriptions)t(this.o,e);},s!==void 0&&(this.value=s);}addCallback(s,t,e){if(!e)return void s(this.value);this.subscriptions.has(s)||this.subscriptions.set(s,{disposer:()=>{this.subscriptions.delete(s);},consumerHost:t});let{disposer:r}=this.subscriptions.get(s);s(this.value,r);}clearCallbacks(){this.subscriptions.clear();}};var Ge=class extends Event{constructor(s,t){super("context-provider",{bubbles:true,composed:true}),this.context=s,this.contextTarget=t;}},$t=class extends he{constructor(s,t,e){super(t.context!==void 0?t.initialValue:e),this.onContextRequest=r=>{if(r.context!==this.context)return;let i=r.contextTarget??r.composedPath()[0];i!==this.host&&(r.stopPropagation(),this.addCallback(r.callback,i,r.subscribe));},this.onProviderRequest=r=>{if(r.context!==this.context||(r.contextTarget??r.composedPath()[0])===this.host)return;let i=new Set;for(let[n,{consumerHost:l}]of this.subscriptions)i.has(n)||(i.add(n),l.dispatchEvent(new st(this.context,l,n,true)));r.stopPropagation();},this.host=s,t.context!==void 0?this.context=t.context:this.context=t,this.attachListeners(),this.host.addController?.(this);}attachListeners(){this.host.addEventListener("context-request",this.onContextRequest),this.host.addEventListener("context-provider",this.onProviderRequest);}hostConnected(){this.host.dispatchEvent(new Ge(this.context,this.host));}};function Be({context:o}){return (s,t)=>{let e=new WeakMap;if(typeof t=="object")return {get(){return s.get.call(this)},set(r){return e.get(this).setValue(r),s.set.call(this,r)},init(r){return e.set(this,new $t(this,{context:o,initialValue:r})),r}};{s.constructor.addInitializer((n=>{e.set(n,new $t(n,{context:o}));}));let r=Object.getOwnPropertyDescriptor(s,t),i;if(r===void 0){let n=new WeakMap;i={get(){return n.get(this)},set(l){e.get(this).setValue(l),n.set(this,l);},configurable:true,enumerable:true};}else {let n=r.set;i={...r,set(l){e.get(this).setValue(l),n?.call(this,l);}};}return void Object.defineProperty(s,t,i)}}}function I({context:o,subscribe:s}){return (t,e)=>{typeof e=="object"?e.addInitializer((function(){new _t(this,{context:o,callback:r=>{t.set.call(this,r);},subscribe:s});})):t.constructor.addInitializer((r=>{new _t(r,{context:o,callback:i=>{r[e]=i;},subscribe:s});}));}}var A="dashboard-store",ue=class extends EventTarget{constructor(){super(...arguments);this._state={flows:[],requests:[],fetches:[],errors:[],logs:[],queries:[],issues:[],metrics:[],viewMode:"simple",activeView:"overview"};}get state(){return this._state}setFlows(t){this._state={...this._state,flows:t},this.notify("flows");}setRequests(t){this._state={...this._state,requests:t},this.notify("requests");}setFetches(t){this._state={...this._state,fetches:t},this.notify("fetches");}setErrors(t){this._state={...this._state,errors:t},this.notify("errors");}setLogs(t){this._state={...this._state,logs:t},this.notify("logs");}setQueries(t){this._state={...this._state,queries:t},this.notify("queries");}setIssues(t){this._state={...this._state,issues:t},this.notify("issues");}setMetrics(t){this._state={...this._state,metrics:t},this.notify("metrics");}prependRequest(t){let e=[t,...this._state.requests.slice(0,999)];this._state={...this._state,requests:e},this.notify("requests");}prependFetch(t){let e=[t,...this._state.fetches.slice(0,999)];this._state={...this._state,fetches:e},this.notify("fetches");}prependError(t){let e=[t,...this._state.errors.slice(0,999)];this._state={...this._state,errors:e},this.notify("errors");}prependLog(t){let e=[t,...this._state.logs.slice(0,999)];this._state={...this._state,logs:e},this.notify("logs");}prependQuery(t){let e=[t,...this._state.queries.slice(0,999)];this._state={...this._state,queries:e},this.notify("queries");}setActiveView(t){this._state={...this._state,activeView:t},this.notify("activeView");}setViewMode(t){this._state={...this._state,viewMode:t},this.notify("viewMode");}clearAll(){this._state={...this._state,flows:[],requests:[],fetches:[],errors:[],logs:[],queries:[],issues:[],metrics:[]},this.notify("all");}notify(t){this.dispatchEvent(new CustomEvent("state-changed",{detail:t}));}};var xt=class extends E{constructor(){super(...arguments);this.expandedIdx=-1;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}toggleError(t){this.expandedIdx=this.expandedIdx===t?-1:t;}renderErrorRow(t,e){let r=new Date(t.timestamp).toLocaleTimeString(),i=this.expandedIdx===e;return a`
14
+ `}};u([L()],ht.prototype,"value",2),u([L()],ht.prototype,"label",2),u([L()],ht.prototype,"color",2),ht=u([_("bk-stat-card")],ht);var nt=class extends Event{constructor(r,t,e,s){super("context-request",{bubbles:true,composed:true}),this.context=r,this.contextTarget=t,this.callback=e,this.subscribe=s??false;}};var Rt=class{constructor(r,t,e,s){if(this.subscribe=false,this.provided=false,this.value=void 0,this.t=(i,n)=>{this.unsubscribe&&(this.unsubscribe!==n&&(this.provided=false,this.unsubscribe()),this.subscribe||this.unsubscribe()),this.value=i,this.host.requestUpdate(),this.provided&&!this.subscribe||(this.provided=true,this.callback&&this.callback(i,n)),this.unsubscribe=n;},this.host=r,t.context!==void 0){let i=t;this.context=i.context,this.callback=i.callback,this.subscribe=i.subscribe??false;}else this.context=t,this.callback=e,this.subscribe=s??false;this.host.addController(this);}hostConnected(){this.dispatchRequest();}hostDisconnected(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=void 0);}dispatchRequest(){this.host.dispatchEvent(new nt(this.context,this.host,this.t,this.subscribe));}};var Ee=class{get value(){return this.o}set value(r){this.setValue(r);}setValue(r,t=false){let e=t||!Object.is(r,this.o);this.o=r,e&&this.updateObservers();}constructor(r){this.subscriptions=new Map,this.updateObservers=()=>{for(let[t,{disposer:e}]of this.subscriptions)t(this.o,e);},r!==void 0&&(this.value=r);}addCallback(r,t,e){if(!e)return void r(this.value);this.subscriptions.has(r)||this.subscriptions.set(r,{disposer:()=>{this.subscriptions.delete(r);},consumerHost:t});let{disposer:s}=this.subscriptions.get(r);r(this.value,s);}clearCallbacks(){this.subscriptions.clear();}};var ze=class extends Event{constructor(r,t){super("context-provider",{bubbles:true,composed:true}),this.context=r,this.contextTarget=t;}},At=class extends Ee{constructor(r,t,e){super(t.context!==void 0?t.initialValue:e),this.onContextRequest=s=>{if(s.context!==this.context)return;let i=s.contextTarget??s.composedPath()[0];i!==this.host&&(s.stopPropagation(),this.addCallback(s.callback,i,s.subscribe));},this.onProviderRequest=s=>{if(s.context!==this.context||(s.contextTarget??s.composedPath()[0])===this.host)return;let i=new Set;for(let[n,{consumerHost:a}]of this.subscriptions)i.has(n)||(i.add(n),a.dispatchEvent(new nt(this.context,a,n,true)));s.stopPropagation();},this.host=r,t.context!==void 0?this.context=t.context:this.context=t,this.attachListeners(),this.host.addController?.(this);}attachListeners(){this.host.addEventListener("context-request",this.onContextRequest),this.host.addEventListener("context-provider",this.onProviderRequest);}hostConnected(){this.host.dispatchEvent(new ze(this.context,this.host));}};function Je({context:o}){return (r,t)=>{let e=new WeakMap;if(typeof t=="object")return {get(){return r.get.call(this)},set(s){return e.get(this).setValue(s),r.set.call(this,s)},init(s){return e.set(this,new At(this,{context:o,initialValue:s})),s}};{r.constructor.addInitializer((n=>{e.set(n,new At(n,{context:o}));}));let s=Object.getOwnPropertyDescriptor(r,t),i;if(s===void 0){let n=new WeakMap;i={get(){return n.get(this)},set(a){e.get(this).setValue(a),n.set(this,a);},configurable:true,enumerable:true};}else {let n=s.set;i={...s,set(a){e.get(this).setValue(a),n?.call(this,a);}};}return void Object.defineProperty(r,t,i)}}}function C({context:o,subscribe:r}){return (t,e)=>{typeof e=="object"?e.addInitializer((function(){new Rt(this,{context:o,callback:s=>{t.set.call(this,s);},subscribe:r});})):t.constructor.addInitializer((s=>{new Rt(s,{context:o,callback:i=>{s[e]=i;},subscribe:r});}));}}var A="dashboard-store",ye=class extends EventTarget{constructor(){super(...arguments);this._state={flows:[],requests:[],fetches:[],errors:[],logs:[],queries:[],issues:[],metrics:[],viewMode:"simple",activeView:"overview"};}get state(){return this._state}setState(t,e){this._state={...this._state,[t]:e},this.notify(t);}setFlows(t){this.setState("flows",t);}setRequests(t){this.setState("requests",t);}setFetches(t){this.setState("fetches",t);}setErrors(t){this.setState("errors",t);}setLogs(t){this.setState("logs",t);}setQueries(t){this.setState("queries",t);}setIssues(t){this.setState("issues",t);}setMetrics(t){this.setState("metrics",t);}prependRequest(t){let e=[t,...this._state.requests.slice(0,999)];this._state={...this._state,requests:e},this.notify("requests");}prependFetch(t){let e=[t,...this._state.fetches.slice(0,999)];this._state={...this._state,fetches:e},this.notify("fetches");}prependError(t){let e=[t,...this._state.errors.slice(0,999)];this._state={...this._state,errors:e},this.notify("errors");}prependLog(t){let e=[t,...this._state.logs.slice(0,999)];this._state={...this._state,logs:e},this.notify("logs");}prependQuery(t){let e=[t,...this._state.queries.slice(0,999)];this._state={...this._state,queries:e},this.notify("queries");}setActiveView(t){this.setState("activeView",t);}setViewMode(t){this.setState("viewMode",t);}clearAll(){this._state={...this._state,flows:[],requests:[],fetches:[],errors:[],logs:[],queries:[],issues:[],metrics:[]},this.notify("all");}notify(t){this.dispatchEvent(new CustomEvent("state-changed",{detail:t}));}};var Ct=class extends E{constructor(){super(...arguments);this.expandedIdx=-1;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}toggleError(t){this.expandedIdx=this.expandedIdx===t?-1:t;}renderErrorRow(t,e){let s=new Date(t.timestamp).toLocaleTimeString(),i=this.expandedIdx===e;return l`
15
15
  <div
16
16
  class="req-row tel-clickable ${i?"expanded":""}"
17
17
  @click=${()=>this.toggleError(e)}
18
18
  >
19
19
  <span class="tel-error-name" title=${t.name}>${t.name}</span>
20
20
  <span class="tel-message" title=${t.message}>${t.message}</span>
21
- <span class="tel-timestamp">${r}</span>
21
+ <span class="tel-timestamp">${s}</span>
22
22
  </div>
23
- ${i&&t.stack?a`<div class="error-stack">${t.stack}</div>`:p}
24
- `}render(){let t=this.store.state.errors;return t.length===0?a`<bk-empty-state
23
+ ${i&&t.stack?l`<div class="error-stack">${t.stack}</div>`:d}
24
+ `}render(){let t=this.store.state.errors;return t.length===0?l`<bk-empty-state
25
25
  title="No errors"
26
26
  subtitle="No errors have been captured yet"
27
- ></bk-empty-state>`:a`
27
+ ></bk-empty-state>`:l`
28
28
  <div class="col-header">
29
29
  <span style="width:180px">Type</span>
30
30
  <span style="flex:1">Message</span>
31
31
  <span style="width:130px;text-align:right">Time</span>
32
32
  </div>
33
33
  <div id="error-list">
34
- ${t.map((e,r)=>this.renderErrorRow(e,r))}
34
+ ${t.map((e,s)=>this.renderErrorRow(e,s))}
35
35
  </div>
36
- `}};u([I({context:A})],xt.prototype,"store",2),u([b()],xt.prototype,"expandedIdx",2),xt=u([S("bk-errors-view")],xt);var jt=class extends E{createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}renderAnalysis(s){if(s.length===0)return p;let t={error:0,warn:0,info:0,debug:0,log:0};for(let e of s)t[e.level]!==void 0&&t[e.level]++;return a`
36
+ `}};u([C({context:A})],Ct.prototype,"store",2),u([b()],Ct.prototype,"expandedIdx",2),Ct=u([_("bk-errors-view")],Ct);var Jt=class extends E{createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}renderAnalysis(r){if(r.length===0)return d;let t={error:0,warn:0,info:0,debug:0,log:0};for(let e of r)t[e.level]!==void 0&&t[e.level]++;return l`
37
37
  <div id="log-analysis">
38
38
  <div class="fetch-summary">
39
- <bk-stat-card value=${String(s.length)} label="Total Logs"></bk-stat-card>
40
- ${t.error>0?a`<bk-stat-card value=${String(t.error)} label="Errors" color="var(--red)"></bk-stat-card>`:p}
41
- ${t.warn>0?a`<bk-stat-card value=${String(t.warn)} label="Warnings" color="var(--amber)"></bk-stat-card>`:p}
39
+ <bk-stat-card value=${String(r.length)} label="Total Logs"></bk-stat-card>
40
+ ${t.error>0?l`<bk-stat-card value=${String(t.error)} label="Errors" color="var(--red)"></bk-stat-card>`:d}
41
+ ${t.warn>0?l`<bk-stat-card value=${String(t.warn)} label="Warnings" color="var(--amber)"></bk-stat-card>`:d}
42
42
  <bk-stat-card value=${String(t.info)} label="Info"></bk-stat-card>
43
- ${t.debug>0?a`<bk-stat-card value=${String(t.debug)} label="Debug"></bk-stat-card>`:p}
44
- ${t.log>0?a`<bk-stat-card value=${String(t.log)} label="Log"></bk-stat-card>`:p}
43
+ ${t.debug>0?l`<bk-stat-card value=${String(t.debug)} label="Debug"></bk-stat-card>`:d}
44
+ ${t.log>0?l`<bk-stat-card value=${String(t.log)} label="Log"></bk-stat-card>`:d}
45
45
  </div>
46
46
  </div>
47
- `}renderLogRow(s){let t=new Date(s.timestamp).toLocaleTimeString();return a`
47
+ `}renderLogRow(r){let t=new Date(r.timestamp).toLocaleTimeString();return l`
48
48
  <div class="req-row">
49
- <span class="tel-level tel-level-${s.level}">${s.level.toUpperCase()}</span>
50
- <span class="tel-message tel-mono" title=${s.message}>${s.message}</span>
49
+ <span class="tel-level tel-level-${r.level}">${r.level.toUpperCase()}</span>
50
+ <span class="tel-message tel-mono" title=${r.message}>${r.message}</span>
51
51
  <span class="tel-timestamp">${t}</span>
52
52
  </div>
53
- `}render(){let s=this.store.state.logs;return s.length===0?a`<bk-empty-state
53
+ `}render(){let r=this.store.state.logs;return r.length===0?l`<bk-empty-state
54
54
  title="No logs"
55
55
  subtitle="No console output has been captured yet"
56
- ></bk-empty-state>`:a`
57
- ${this.renderAnalysis(s)}
56
+ ></bk-empty-state>`:l`
57
+ ${this.renderAnalysis(r)}
58
58
  <div class="col-header">
59
59
  <span style="width:52px">Level</span>
60
60
  <span style="flex:1">Message</span>
61
61
  <span style="width:130px;text-align:right">Time</span>
62
62
  </div>
63
63
  <div id="log-list">
64
- ${s.map(t=>this.renderLogRow(t))}
64
+ ${r.map(t=>this.renderLogRow(t))}
65
65
  </div>
66
- `}};u([I({context:A})],jt.prototype,"store",2),jt=u([S("bk-logs-view")],jt);var Ps={CHILD:2},qs=o=>(...s)=>({_$litDirective$:o,values:s}),me=class{constructor(s){}get _$AU(){return this._$AM._$AU}_$AT(s,t,e){this._$Ct=s,this._$AM=t,this._$Ci=e;}_$AS(s,t){return this.update(s,t)}update(s,t){return this.render(...t)}};var Yt=class extends me{constructor(s){if(super(s),this.it=p,s.type!==Ps.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(s){if(s===p||s==null)return this._t=void 0,this.it=s;if(s===Y)return s;if(typeof s!="string")throw Error(this.constructor.directiveName+"() called with a non-string value");if(s===this.it)return this._t;this.it=s;let t=[s];return t.raw=t,this._t={_$litType$:this.constructor.resultType,strings:t,values:[]}}};Yt.directiveName="unsafeHTML",Yt.resultType=1;var U=qs(Yt);var Vr=new Set(["SELECT","FROM","WHERE","AND","OR","INSERT","INTO","VALUES","UPDATE","SET","DELETE","JOIN","LEFT","RIGHT","INNER","OUTER","ON","GROUP","BY","ORDER","HAVING","LIMIT","OFFSET","AS","IN","NOT","NULL","IS","LIKE","BETWEEN","EXISTS","CASE","WHEN","THEN","ELSE","END","COUNT","SUM","AVG","MIN","MAX","DISTINCT","UNION","ALL","CREATE","TABLE","ALTER","DROP","INDEX","RETURNING","WITH","RECURSIVE","OVER","PARTITION","WINDOW","FETCH","NEXT","ROWS","ONLY","CAST","COALESCE","NULLIF","EXTRACT","INTERVAL","TRUE","FALSE","ASC","DESC","USING","NATURAL","CROSS","FULL","ROLLBACK","COMMIT","BEGIN","TRANSACTION","SAVEPOINT","RELEASE"]);function Us(o){let s=o.trimStart().split(/\s/)[0];return s?s.toUpperCase():"?"}function Fs(o){let s=o.replace(/\s+/g," ").trim(),t=s.match(/\bFROM\s+["'`]?(\w+)["'`]?/i);if(t)return t[1];let e=s.match(/\bINTO\s+["'`]?(\w+)["'`]?/i);if(e)return e[1];let r=s.match(/\bUPDATE\s+["'`]?(\w+)["'`]?/i);return r?r[1]:""}function Gs(o){return tt(o).replace(/\b\w+\b/g,s=>Vr.has(s.toUpperCase())?'<span class="sql-kw">'+s+"</span>":s)}var St=class extends E{constructor(){super(...arguments);this.expandedIdx=-1;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}toggleQuery(t){this.expandedIdx=this.expandedIdx===t?-1:t;}queryDuration(t){return t===0?"<1ms":_(t)}getQueryInfo(t){let e=(t.normalizedOp||t.operation||(t.sql?Us(t.sql):"?")).toUpperCase(),r=t.table||t.model||(t.sql?Fs(t.sql):""),i=t.sql||e+" "+r;return {op:e,table:r,sqlText:i}}renderQueryRow(t,e){let{op:r,table:i,sqlText:n}=this.getQueryInfo(t),l=pe[r]||"var(--text-dim)",c=t.durationMs>Oe,d=t.sql||r+" "+i,h=this.expandedIdx===e;return a`
66
+ `}};u([C({context:A})],Jt.prototype,"store",2),Jt=u([_("bk-logs-view")],Jt);var Vs={CHILD:2},Ks=o=>(...r)=>({_$litDirective$:o,values:r}),$e=class{constructor(r){}get _$AU(){return this._$AM._$AU}_$AT(r,t,e){this._$Ct=r,this._$AM=t,this._$Ci=e;}_$AS(r,t){return this.update(r,t)}update(r,t){return this.render(...t)}};var Zt=class extends $e{constructor(r){if(super(r),this.it=d,r.type!==Vs.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(r){if(r===d||r==null)return this._t=void 0,this.it=r;if(r===z)return r;if(typeof r!="string")throw Error(this.constructor.directiveName+"() called with a non-string value");if(r===this.it)return this._t;this.it=r;let t=[r];return t.raw=t,this._t={_$litType$:this.constructor.resultType,strings:t,values:[]}}};Zt.directiveName="unsafeHTML",Zt.resultType=1;var G=Ks(Zt);var oi=new Set(["SELECT","FROM","WHERE","AND","OR","INSERT","INTO","VALUES","UPDATE","SET","DELETE","JOIN","LEFT","RIGHT","INNER","OUTER","ON","GROUP","BY","ORDER","HAVING","LIMIT","OFFSET","AS","IN","NOT","NULL","IS","LIKE","BETWEEN","EXISTS","CASE","WHEN","THEN","ELSE","END","COUNT","SUM","AVG","MIN","MAX","DISTINCT","UNION","ALL","CREATE","TABLE","ALTER","DROP","INDEX","RETURNING","WITH","RECURSIVE","OVER","PARTITION","WINDOW","FETCH","NEXT","ROWS","ONLY","CAST","COALESCE","NULLIF","EXTRACT","INTERVAL","TRUE","FALSE","ASC","DESC","USING","NATURAL","CROSS","FULL","ROLLBACK","COMMIT","BEGIN","TRANSACTION","SAVEPOINT","RELEASE"]);function zs(o){let r=o.trimStart().split(/\s/)[0];return r?r.toUpperCase():"?"}function Js(o){let r=o.replace(/\s+/g," ").trim(),t=r.match(/\bFROM\s+["'`]?(\w+)["'`]?/i);if(t)return t[1];let e=r.match(/\bINTO\s+["'`]?(\w+)["'`]?/i);if(e)return e[1];let s=r.match(/\bUPDATE\s+["'`]?(\w+)["'`]?/i);return s?s[1]:""}function Zs(o){return it(o).replace(/\b\w+\b/g,r=>oi.has(r.toUpperCase())?'<span class="sql-kw">'+r+"</span>":r)}var It=class extends E{constructor(){super(...arguments);this.expandedIdx=-1;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}toggleQuery(t){this.expandedIdx=this.expandedIdx===t?-1:t;}queryDuration(t){return t===0?"<1ms":y(t)}getQueryInfo(t){let e=(t.normalizedOp||t.operation||(t.sql?zs(t.sql):"?")).toUpperCase(),s=t.table||t.model||(t.sql?Js(t.sql):""),i=t.sql||e+" "+s;return {op:e,table:s,sqlText:i}}renderQueryRow(t,e){let{op:s,table:i,sqlText:n}=this.getQueryInfo(t),a=be[s]||"var(--text-dim)",c=t.durationMs>Be,p=t.sql||s+" "+i,h=this.expandedIdx===e;return l`
67
67
  <div>
68
68
  <div
69
69
  class="req-row query-row tel-clickable ${h?"expanded":""}"
70
70
  @click=${()=>this.toggleQuery(e)}
71
71
  >
72
- <span class="query-op" title=${r} style="color:${l}">${r}</span>
72
+ <span class="query-op" title=${s} style="color:${a}">${s}</span>
73
73
  <span class="query-table" title=${i}>${i}</span>
74
- <span class="query-preview" title=${d}>${d}</span>
74
+ <span class="query-preview" title=${p}>${p}</span>
75
75
  <span class="query-dur${c?" query-slow":""}">${this.queryDuration(t.durationMs)}</span>
76
76
  </div>
77
77
  <div class="query-detail ${h?"open":""}">
78
- ${h?a`
79
- <pre class="query-detail-sql">${U(Gs(n))}</pre>
78
+ ${h?l`
79
+ <pre class="query-detail-sql">${G(Zs(n))}</pre>
80
80
  <bk-copy-button .text=${n} label="Copy"></bk-copy-button>
81
- `:p}
81
+ `:d}
82
82
  </div>
83
83
  </div>
84
- `}render(){let t=this.store.state.queries;return t.length===0?a`<bk-empty-state
84
+ `}render(){let t=this.store.state.queries;return t.length===0?l`<bk-empty-state
85
85
  title="No queries"
86
86
  subtitle="No database queries have been captured yet"
87
- ></bk-empty-state>`:a`
87
+ ></bk-empty-state>`:l`
88
88
  <div class="col-header">
89
89
  <span style="width:70px;border-right:1px solid var(--border);padding-right:16px">Operation</span>
90
90
  <span style="width:170px;border-right:1px solid var(--border);padding-right:16px">Table</span>
@@ -92,37 +92,37 @@
92
92
  <span style="width:60px;text-align:right">Time</span>
93
93
  </div>
94
94
  <div id="query-list">
95
- ${t.map((e,r)=>this.renderQueryRow(e,r))}
95
+ ${t.map((e,s)=>this.renderQueryRow(e,s))}
96
96
  </div>
97
- `}};u([I({context:A})],St.prototype,"store",2),u([b()],St.prototype,"expandedIdx",2),St=u([S("bk-queries-view")],St);function We(o){return o.replaceAll("'","'\\''")}function Kr(o,s){let t=Object.entries(o.headers||{}).filter(([i])=>!Ds.has(i)).map(([i,n])=>`-H '${We(i)}: ${We(n)}'`).join(" "),e=o.requestBody?` -d '${We(o.requestBody)}'`:"",r=s?`http://localhost:${s}`:"";return `curl -X ${o.method} ${t}${e} '${r}${o.url}'`}function Tt(o){let s=window.__BRAKIT_CONFIG__?.port??"",t=Kr(o,s);navigator.clipboard.writeText(t).then(()=>D.show("Copied cURL command"));}var wt=class extends E{constructor(){super(...arguments);this.expandedId=null;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}toggleRequest(t){this.expandedId=this.expandedId===t?null:t;}handleCopyAsCurl(t,e){e.stopPropagation(),Tt(t);}renderDetail(t){return a`
97
+ `}};u([C({context:A})],It.prototype,"store",2),u([b()],It.prototype,"expandedIdx",2),It=u([_("bk-queries-view")],It);function Ze(o){return o.replaceAll("'","'\\''")}function ni(o,r){let t=Object.entries(o.headers||{}).filter(([i])=>!Ys.has(i)).map(([i,n])=>`-H '${Ze(i)}: ${Ze(n)}'`).join(" "),e=o.requestBody?` -d '${Ze(o.requestBody)}'`:"",s=r?`http://localhost:${r}`:"";return `curl -X ${o.method} ${t}${e} '${s}${o.url}'`}function Lt(o){let r=window.__BRAKIT_CONFIG__?.port??"",t=ni(o,r);navigator.clipboard.writeText(t).then(()=>D.show("Copied cURL command"));}var Mt=class extends E{constructor(){super(...arguments);this.expandedId=null;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}toggleRequest(t){this.expandedId=this.expandedId===t?null:t;}handleCopyAsCurl(t,e){e.stopPropagation(),Lt(t);}renderDetail(t){return l`
98
98
  <div class="detail-meta">
99
99
  <span><bk-method-badge .method=${t.method}></bk-method-badge> ${t.url}</span>
100
100
  <span><bk-status-pill .code=${t.statusCode}></bk-status-pill></span>
101
101
  <span>${t.durationMs}ms</span>
102
- ${t.responseSize?a`<span>${et(t.responseSize)}</span>`:p}
102
+ ${t.responseSize?l`<span>${ot(t.responseSize)}</span>`:d}
103
103
  </div>
104
104
  <div class="request-timeline tl-hidden" data-request-id=${t.id} data-request-started=${String(t.startedAt)}></div>
105
105
  <div class="detail-grid">
106
- <div class="detail-section"><h4>Request Headers</h4><pre>${U(Et(t.headers))}</pre></div>
107
- <div class="detail-section"><h4>Response Headers</h4><pre>${U(Et(t.responseHeaders))}</pre></div>
108
- <div class="detail-section"><h4>Request Body</h4><pre>${U(nt(t.requestBody))}</pre></div>
109
- <div class="detail-section"><h4>Response Body</h4><pre>${U(nt(t.responseBody))}</pre></div>
106
+ <div class="detail-section"><h4>Request Headers</h4><pre>${G(Tt(t.headers))}</pre></div>
107
+ <div class="detail-section"><h4>Response Headers</h4><pre>${G(Tt(t.responseHeaders))}</pre></div>
108
+ <div class="detail-section"><h4>Request Body</h4><pre>${G(dt(t.requestBody))}</pre></div>
109
+ <div class="detail-section"><h4>Response Body</h4><pre>${G(dt(t.responseBody))}</pre></div>
110
110
  </div>
111
111
  <div class="detail-actions">
112
112
  <button class="btn btn-curl" @click=${e=>this.handleCopyAsCurl(t,e)}>Copy cURL</button>
113
113
  </div>
114
- `}renderRequestRow(t){let e=this.expandedId===t.id;return a`
114
+ `}renderRequestRow(t){let e=this.expandedId===t.id;return l`
115
115
  <div class="req-row ${e?"expanded":""}" @click=${()=>this.toggleRequest(t.id)}>
116
116
  <div class="req-summary">
117
117
  <bk-method-badge .method=${t.method}></bk-method-badge>
118
118
  <span class="req-url">${t.url}</span>
119
119
  <bk-status-pill .code=${t.statusCode}></bk-status-pill>
120
120
  <bk-duration-label .ms=${t.durationMs}></bk-duration-label>
121
- <span class="req-size">${et(t.responseSize)}</span>
121
+ <span class="req-size">${ot(t.responseSize)}</span>
122
122
  </div>
123
123
  </div>
124
- <div class="req-detail ${e?"open":""}">${e?this.renderDetail(t):p}</div>
125
- `}render(){let t=this.store.state.requests.filter(e=>!e.path?.startsWith(F));return t.length===0?a`<bk-empty-state title="No requests" subtitle="No HTTP requests have been captured yet"></bk-empty-state>`:a`
124
+ <div class="req-detail ${e?"open":""}">${e?this.renderDetail(t):d}</div>
125
+ `}render(){let t=this.store.state.requests.filter(e=>!e.path?.startsWith(U));return t.length===0?l`<bk-empty-state title="No requests" subtitle="No HTTP requests have been captured yet"></bk-empty-state>`:l`
126
126
  <div class="col-header">
127
127
  <span style="width:60px">Method</span>
128
128
  <span style="flex:1">URL</span>
@@ -131,53 +131,53 @@
131
131
  <span style="width:60px;text-align:right">Size</span>
132
132
  </div>
133
133
  <div id="request-list">${t.map(e=>this.renderRequestRow(e))}</div>
134
- `}};u([I({context:A})],wt.prototype,"store",2),u([b()],wt.prototype,"expandedId",2),wt=u([S("bk-requests-view")],wt);var Xt=class extends E{createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}buildGroups(s,t){let e=new Map;for(let i of t)e.set(i.id,i);let r={};for(let i of s){let n=i.method+" "+i.url;r[n]||(r[n]={method:i.method,url:i.url,count:0,totalDur:0,maxDur:0,errors:0,callers:{},statusCodes:{},firstTs:i.timestamp,lastTs:i.timestamp});let l=r[n];if(l.count++,l.totalDur+=i.durationMs,i.durationMs>l.maxDur&&(l.maxDur=i.durationMs),i.statusCode>=400&&l.errors++,l.statusCodes[i.statusCode]=(l.statusCodes[i.statusCode]||0)+1,i.timestamp<l.firstTs&&(l.firstTs=i.timestamp),i.timestamp>l.lastTs&&(l.lastTs=i.timestamp),i.parentRequestId){let c=e.get(i.parentRequestId);c&&(l.callers[c.method+" "+(c.path||c.url)]=1);}}return Object.values(r).sort((i,n)=>n.count-i.count)}renderSummary(s){let t=new Set,e=0,r=0;for(let n of s)t.add(n.url),n.statusCode>=400&&e++,r+=n.durationMs;let i=Math.round(r/s.length);return a`
134
+ `}};u([C({context:A})],Mt.prototype,"store",2),u([b()],Mt.prototype,"expandedId",2),Mt=u([_("bk-requests-view")],Mt);var te=class extends E{createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}buildGroups(r,t){let e=new Map;for(let i of t)e.set(i.id,i);let s={};for(let i of r){let n=i.method+" "+i.url;s[n]||(s[n]={method:i.method,url:i.url,count:0,totalDur:0,maxDur:0,errors:0,callers:{},statusCodes:{},firstTs:i.timestamp,lastTs:i.timestamp});let a=s[n];if(a.count++,a.totalDur+=i.durationMs,i.durationMs>a.maxDur&&(a.maxDur=i.durationMs),i.statusCode>=400&&a.errors++,a.statusCodes[i.statusCode]=(a.statusCodes[i.statusCode]||0)+1,i.timestamp<a.firstTs&&(a.firstTs=i.timestamp),i.timestamp>a.lastTs&&(a.lastTs=i.timestamp),i.parentRequestId){let c=e.get(i.parentRequestId);c&&(a.callers[c.method+" "+(c.path||c.url)]=1);}}return Object.values(s).sort((i,n)=>n.count-i.count)}renderSummary(r){let t=new Set,e=0,s=0;for(let n of r)t.add(n.url),n.statusCode>=400&&e++,s+=n.durationMs;let i=Math.round(s/r.length);return l`
135
135
  <div class="fetch-summary">
136
- <bk-stat-card value=${String(s.length)} label="Total Fetches"></bk-stat-card>
136
+ <bk-stat-card value=${String(r.length)} label="Total Fetches"></bk-stat-card>
137
137
  <bk-stat-card value=${String(t.size)} label="Unique URLs"></bk-stat-card>
138
138
  <bk-stat-card value=${String(e)} label="Errors" color=${e>0?"var(--red)":""}></bk-stat-card>
139
- <bk-stat-card value=${_(i)} label="Avg Duration"></bk-stat-card>
139
+ <bk-stat-card value=${y(i)} label="Avg Duration"></bk-stat-card>
140
140
  </div>
141
- `}formatTime(s){return new Date(s).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}renderGroup(s){let t=Math.round(s.totalDur/s.count),e=s.count>0?Math.round(s.errors/s.count*100):0,r=Object.keys(s.callers),i=Object.entries(s.statusCodes),n=i.length>0?Number(i.sort((l,c)=>c[1]-l[1])[0][0]):0;return a`
141
+ `}formatTime(r){return new Date(r).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}renderGroup(r){let t=Math.round(r.totalDur/r.count),e=r.count>0?Math.round(r.errors/r.count*100):0,s=Object.keys(r.callers),i=Object.entries(r.statusCodes),n=i.length>0?Number(i.sort((a,c)=>c[1]-a[1])[0][0]):0;return l`
142
142
  <div class="fetch-group">
143
143
  <div class="fetch-group-header">
144
- <bk-method-badge .method=${s.method}></bk-method-badge>
145
- <span class="fetch-group-url" title=${s.url}>${s.url}</span>
146
- ${n>0?a`<bk-status-pill .code=${n}></bk-status-pill>`:p}
147
- <span class="fetch-group-count">${s.count}x</span>
144
+ <bk-method-badge .method=${r.method}></bk-method-badge>
145
+ <span class="fetch-group-url" title=${r.url}>${r.url}</span>
146
+ ${n>0?l`<bk-status-pill .code=${n}></bk-status-pill>`:d}
147
+ <span class="fetch-group-count">${r.count}x</span>
148
148
  </div>
149
149
  <div class="fetch-group-meta">
150
- <span>avg ${_(t)}</span>
150
+ <span>avg ${y(t)}</span>
151
151
  <span class="fetch-group-sep">\u00b7</span>
152
- <span>max ${_(s.maxDur)}</span>
152
+ <span>max ${y(r.maxDur)}</span>
153
153
  <span class="fetch-group-sep">\u00b7</span>
154
- ${e>0?a`<span class="fetch-group-err">${e}% errors</span>`:a`<span class="fetch-group-ok">0% errors</span>`}
154
+ ${e>0?l`<span class="fetch-group-err">${e}% errors</span>`:l`<span class="fetch-group-ok">0% errors</span>`}
155
155
  </div>
156
- ${s.firstTs>0?a`
156
+ ${r.firstTs>0?l`
157
157
  <div class="fetch-group-timeline">
158
158
  <span class="fetch-group-timeline-dot"></span>
159
159
  <span class="fetch-group-timeline-range">
160
- ${this.formatTime(s.firstTs)}${s.firstTs!==s.lastTs?a` \u2192 ${this.formatTime(s.lastTs)}`:p}
160
+ ${this.formatTime(r.firstTs)}${r.firstTs!==r.lastTs?l` \u2192 ${this.formatTime(r.lastTs)}`:d}
161
161
  </span>
162
- </div>`:p}
163
- ${r.length>0?a`
162
+ </div>`:d}
163
+ ${s.length>0?l`
164
164
  <div class="fetch-group-callers">
165
165
  <span class="fetch-group-callers-label">Called by</span>
166
- ${r.map(l=>a`<span class="fetch-group-caller-pill">${l}</span>`)}
167
- </div>`:p}
166
+ ${s.map(a=>l`<span class="fetch-group-caller-pill">${a}</span>`)}
167
+ </div>`:d}
168
168
  </div>
169
- `}render(){let s=this.store.state.fetches,t=this.store.state.requests;if(s.length===0)return a`<bk-empty-state title="No fetches" subtitle="No outbound HTTP calls have been captured yet"></bk-empty-state>`;let e=this.buildGroups(s,t);return a`
169
+ `}render(){let r=this.store.state.fetches,t=this.store.state.requests;if(r.length===0)return l`<bk-empty-state title="No fetches" subtitle="No outbound HTTP calls have been captured yet"></bk-empty-state>`;let e=this.buildGroups(r,t);return l`
170
170
  <div class="fetch-analysis" id="fetch-analysis">
171
- ${this.renderSummary(s)}
172
- ${e.length>0?a`
171
+ ${this.renderSummary(r)}
172
+ ${e.length>0?l`
173
173
  <div class="fetch-groups-title">Grouped by URL (${e.length})</div>
174
- <div class="fetch-groups">${e.map(r=>this.renderGroup(r))}</div>
175
- `:p}
174
+ <div class="fetch-groups">${e.map(s=>this.renderGroup(s))}</div>
175
+ `:d}
176
176
  </div>
177
- `}};u([I({context:A})],Xt.prototype,"store",2),Xt=u([S("bk-fetches-view")],Xt);function Bs(o,s){if(s>=400)return "var(--red)";switch(o){case "GET":return "var(--green)";case "POST":return "var(--blue)";case "PUT":case "PATCH":return "var(--amber)";case "DELETE":return "var(--red)";default:return "var(--text-muted)"}}function Qe(o){return o==="query"?"var(--accent)":"var(--cyan)"}function ti(o){return o.type==="query"||o.type==="fetch"}function ei(o){let s=(o.normalizedOp||o.operation||"QUERY").toUpperCase(),t=o.table||o.model||"";return {label:`${s} ${t}`,tooltip:o.sql||`${s} ${t}`}}function si(o){return {label:`${o.method} ${o.url}`,tooltip:`${o.method} ${o.url}`}}function ri(o,s,t,e,r,i){let n=o.data.durationMs||0,l,c;if(i){let d=Math.max(o.timestamp-e,0);l=Math.min(d/r*100,95),c=Math.max(n/r*100,1.5);}else {let d=t[0].timestamp,m=t[t.length-1].timestamp-d;l=m>0?(o.timestamp-d)/m*85:s/Math.max(t.length-1,1)*85,c=Math.max(n/r*100,1.5);}return l+c>100&&(c=Math.max(100-l,1.5)),{leftPct:l,widthPct:c}}function ii(o,s){let t=o.timeline.filter(ti);if(t.length===0)return [];let e=s.startedAt,r=s.durationMs||1,i=Math.abs(t[0].timestamp-e)<r*10;return t.map((n,l)=>{let c=n.data.durationMs||0,{leftPct:d,widthPct:h}=ri(n,l,t,e,r,i),m=n.type==="query"?ei(n.data):si(n.data);return {type:n.type,label:m.label,durMs:c,durLabel:_(c),tooltip:m.tooltip,leftPct:d,widthPct:h}})}function Qs(o,s){let t=o.requests.filter(l=>!l.isStrictModeDupe);if(t.length===0)return {rows:[],totalMs:0};let e=Math.min(...t.map(l=>l.startedAt)),i=Math.max(...t.map(l=>l.startedAt+l.durationMs))-e;return i===0?{rows:[],totalMs:0}:{rows:t.map(l=>{let c=(l.startedAt-e)/i*100,d=Math.max(l.durationMs/i*100,.5),h=s?.activities?.[l.id],m=h?ii(h,l):[];return {label:`${l.method} ${l.label}`,leftPct:c,widthPct:d,color:Bs(l.method,l.statusCode),durMs:l.durationMs,durLabel:_(l.durationMs),tooltip:`${l.method} ${l.label} (${_(l.durationMs)})`,subEvents:m}}),totalMs:i}}function js(o){let s=o.requests,t=[],e=[],r=[],i=[],n=new Map;for(let d of s){let h=d.label,m=d.pollingDurationMs||d.durationMs;if(!Gt[d.category||""]){if(d.isDuplicate){let v=n.get(h);v?(v.count++,v.wastedMs+=m):n.set(h,{name:h,count:2,wastedMs:m});continue}if(d.statusCode>=400){e.push(h+" ("+Hs(d.statusCode)+")");continue}d.responseSize>51200&&r.push("Large response: "+h+" returned "+et(d.responseSize)),t.push(h);}}for(let d of n.values())i.push(d);let l="";if(i.length>0){let d=i.map(m=>m.name).join(", "),h=i.reduce((m,v)=>m+v.wastedMs,0);l="Your app fetches "+d+" multiple times on this page. This wastes ~"+_(h)+". Try caching these calls, deduplicating with React Query/SWR, or moving them to a shared layout.";}else e.length>0&&(l="Some requests are failing. Check your API routes and make sure the endpoints exist.");let c=s.filter(d=>d.durationMs>2e3&&d.category!==ut);return c.length>0&&!l&&(l=c.map(d=>d.label).join(", ")+` is taking over ${_(2e3)}. Consider adding caching or optimizing the backend query.`),{successes:t,errors:e,warnings:r,duplicates:i,tip:l}}var W=class extends E{constructor(){super(...arguments);this.expandedFlowIdx=-1;this.expandedSubReqIdx=-1;this.flowDetailTab="insights";this.flowTimeline=null;this.flowTimelineLoading=false;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}get flows(){return this.store.state.flows}get viewMode(){return this.store.state.viewMode}flowDotClass(t){return t.hasErrors?"dot-error":t.redundancyPct>0?"dot-warn":"dot-clean"}flowBadgeInfo(t){if(t.hasErrors){let e=t.requests.filter(r=>r.statusCode>=400).length;return {text:e+" error"+(e!==1?"s":""),cls:"badge-error"}}return t.redundancyPct>0?{text:t.redundancyPct+"% redundant",cls:"badge-warn"}:{text:"clean",cls:"badge-clean"}}toggleFlow(t){this.expandedFlowIdx===t?this.expandedFlowIdx=-1:(this.expandedFlowIdx=t,this.expandedSubReqIdx=-1,this.flowDetailTab="insights",this.flowTimeline=null);}toggleSubReq(t,e){e.stopPropagation(),this.expandedSubReqIdx=this.expandedSubReqIdx===t?-1:t;}toggleBodyBlock(t){t.stopPropagation();let e=t.currentTarget,r=e.parentElement;if(!r)return;e.classList.toggle("open");let i=r.querySelector("pre");i&&i.classList.toggle("open");}switchTab(t,e,r){r.stopPropagation(),this.flowDetailTab=t,t==="timeline"&&!this.flowTimeline&&this.loadFlowTimeline(e);}async loadFlowTimeline(t){if(this.flowTimelineLoading)return;let e=t.requests.map(r=>r.id).filter(Boolean);if(e.length!==0){this.flowTimelineLoading=true;try{let r=await fetch(`${w.activity}?requestIds=${e.join(",")}`);if(!r.ok){this.flowTimelineLoading=!1;return}this.flowTimeline=await r.json();}catch{}this.flowTimelineLoading=false;}}loadTimelineForContainer(t){let e=t.querySelectorAll(".request-timeline");for(let r of e){let i=r.getAttribute("data-request-id");if(i&&!r.hasAttribute("data-loaded")){r.setAttribute("data-loaded","1");let n=document.createElement("bk-timeline-panel");n.setAttribute("request-id",i),n.setAttribute("request-started",r.getAttribute("data-request-started")||"0"),r.appendChild(n),r.classList.remove("tl-hidden");}}}updated(){if(this.expandedFlowIdx>=0&&this.flowDetailTab==="insights"){let t=this.querySelector(".flow-expand.open");t&&this.loadTimelineForContainer(t);}}render(){let t=this.flows;return t.length===0?a`<bk-empty-state
177
+ `}};u([C({context:A})],te.prototype,"store",2),te=u([_("bk-fetches-view")],te);function tr(o,r){if(r>=400)return "var(--red)";switch(o){case "GET":return "var(--green)";case "POST":return "var(--blue)";case "PUT":case "PATCH":return "var(--amber)";case "DELETE":return "var(--red)";default:return "var(--text-muted)"}}function ts(o){return o==="query"?"var(--accent)":"var(--cyan)"}function di(o){return o.type==="query"||o.type==="fetch"}function pi(o){let r=(o.normalizedOp||o.operation||"QUERY").toUpperCase(),t=o.table||o.model||"";return {label:`${r} ${t}`,tooltip:o.sql||`${r} ${t}`}}function hi(o){return {label:`${o.method} ${o.url}`,tooltip:`${o.method} ${o.url}`}}function ui(o,r,t,e,s,i){let n=o.data.durationMs||0,a,c;if(i){let p=Math.max(o.timestamp-e,0);a=Math.min(p/s*100,95),c=Math.max(n/s*100,1.5);}else {let p=t[0].timestamp,m=t[t.length-1].timestamp-p;a=m>0?(o.timestamp-p)/m*85:r/Math.max(t.length-1,1)*85,c=Math.max(n/s*100,1.5);}return a+c>100&&(c=Math.max(100-a,1.5)),{leftPct:a,widthPct:c}}function mi(o,r){let t=o.timeline.filter(di);if(t.length===0)return [];let e=r.startedAt,s=r.durationMs||1,i=Math.abs(t[0].timestamp-e)<s*10;return t.map((n,a)=>{let c=n.data.durationMs||0,{leftPct:p,widthPct:h}=ui(n,a,t,e,s,i),m=n.type==="query"?pi(n.data):hi(n.data);return {type:n.type,label:m.label,durMs:c,durLabel:y(c),tooltip:m.tooltip,leftPct:p,widthPct:h}})}function sr(o,r){let t=o.requests.filter(a=>!a.isStrictModeDupe);if(t.length===0)return {rows:[],totalMs:0};let e=Math.min(...t.map(a=>a.startedAt)),i=Math.max(...t.map(a=>a.startedAt+a.durationMs))-e;return i===0?{rows:[],totalMs:0}:{rows:t.map(a=>{let c=(a.startedAt-e)/i*100,p=Math.max(a.durationMs/i*100,.5),h=r?.activities?.[a.id],m=h?mi(h,a):[];return {label:`${a.method} ${a.label}`,leftPct:c,widthPct:p,color:tr(a.method,a.statusCode),durMs:a.durationMs,durLabel:y(a.durationMs),tooltip:`${a.method} ${a.label} (${y(a.durationMs)})`,subEvents:m}}),totalMs:i}}function rr(o){let r=o.requests,t=[],e=[],s=[],i=[],n=new Map;for(let p of r){let h=p.label,m=p.pollingDurationMs||p.durationMs;if(!Yt[p.category||""]){if(p.isDuplicate){let f=n.get(h);f?(f.count++,f.wastedMs+=m):n.set(h,{name:h,count:2,wastedMs:m});continue}if(p.statusCode>=400){e.push(h+" ("+Xs(p.statusCode)+")");continue}p.responseSize>51200&&s.push("Large response: "+h+" returned "+ot(p.responseSize)),t.push(h);}}for(let p of n.values())i.push(p);let a="";if(i.length>0){let p=i.map(m=>m.name).join(", "),h=i.reduce((m,f)=>m+f.wastedMs,0);a="Your app fetches "+p+" multiple times on this page. This wastes ~"+y(h)+". Try caching these calls, deduplicating with React Query/SWR, or moving them to a shared layout.";}else e.length>0&&(a="Some requests are failing. Check your API routes and make sure the endpoints exist.");let c=r.filter(p=>p.durationMs>2e3&&p.category!==bt);return c.length>0&&!a&&(a=c.map(p=>p.label).join(", ")+` is taking over ${y(2e3)}. Consider adding caching or optimizing the backend query.`),{successes:t,errors:e,warnings:s,duplicates:i,tip:a}}var X=class extends E{constructor(){super(...arguments);this.expandedFlowIdx=-1;this.expandedSubReqIdx=-1;this.flowDetailTab="insights";this.flowTimeline=null;this.flowTimelineLoading=false;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}get flows(){return this.store.state.flows}get viewMode(){return this.store.state.viewMode}flowDotClass(t){return t.hasErrors?"dot-error":t.redundancyPct>0?"dot-warn":"dot-clean"}flowBadgeInfo(t){if(t.hasErrors){let e=t.requests.filter(s=>s.statusCode>=400).length;return {text:e+" error"+(e!==1?"s":""),cls:"badge-error"}}return t.redundancyPct>0?{text:t.redundancyPct+"% redundant",cls:"badge-warn"}:{text:"clean",cls:"badge-clean"}}toggleFlow(t){this.expandedFlowIdx===t?this.expandedFlowIdx=-1:(this.expandedFlowIdx=t,this.expandedSubReqIdx=-1,this.flowDetailTab="insights",this.flowTimeline=null);}toggleSubReq(t,e){e.stopPropagation(),this.expandedSubReqIdx=this.expandedSubReqIdx===t?-1:t;}toggleBodyBlock(t){t.stopPropagation();let e=t.currentTarget,s=e.parentElement;if(!s)return;e.classList.toggle("open");let i=s.querySelector("pre");i&&i.classList.toggle("open");}switchTab(t,e,s){s.stopPropagation(),this.flowDetailTab=t,t==="timeline"&&!this.flowTimeline&&this.loadFlowTimeline(e);}async loadFlowTimeline(t){if(this.flowTimelineLoading)return;let e=t.requests.map(s=>s.id).filter(Boolean);if(e.length!==0){this.flowTimelineLoading=true;try{let s=await fetch(`${T.activity}?requestIds=${e.join(",")}`);if(!s.ok){this.flowTimelineLoading=!1;return}this.flowTimeline=await s.json();}catch{}this.flowTimelineLoading=false;}}loadTimelineForContainer(t){let e=t.querySelectorAll(".request-timeline");for(let s of e){let i=s.getAttribute("data-request-id");if(i&&!s.hasAttribute("data-loaded")){s.setAttribute("data-loaded","1");let n=document.createElement("bk-timeline-panel");n.setAttribute("request-id",i),n.setAttribute("request-started",s.getAttribute("data-request-started")||"0"),s.appendChild(n),s.classList.remove("tl-hidden");}}}updated(){if(this.expandedFlowIdx>=0&&this.flowDetailTab==="insights"){let t=this.querySelector(".flow-expand.open");t&&this.loadTimelineForContainer(t);}}render(){let t=this.flows;return t.length===0?l`<bk-empty-state
178
178
  title="No actions yet"
179
179
  subtitle="Start using your app to see user action flows here"
180
- ></bk-empty-state>`:a`
180
+ ></bk-empty-state>`:l`
181
181
  <div id="flow-col-header" class="col-header">
182
182
  <span style="width:8px"></span>
183
183
  <span style="flex:1">Action</span>
@@ -186,11 +186,11 @@
186
186
  <span style="width:70px;text-align:right">Time</span>
187
187
  </div>
188
188
  <div id="flow-list">
189
- ${t.map((e,r)=>this.renderFlowRow(e,r))}
189
+ ${t.map((e,s)=>this.renderFlowRow(e,s))}
190
190
  </div>
191
- `}renderFlowRow(t,e){let r=this.expandedFlowIdx===e,i=this.flowDotClass(t),n=this.flowBadgeInfo(t);return a`
191
+ `}renderFlowRow(t,e){let s=this.expandedFlowIdx===e,i=this.flowDotClass(t),n=this.flowBadgeInfo(t);return l`
192
192
  <div
193
- class="flow-row ${r?"expanded":""}"
193
+ class="flow-row ${s?"expanded":""}"
194
194
  @click=${()=>this.toggleFlow(e)}
195
195
  >
196
196
  <div class="flow-summary-row">
@@ -202,39 +202,39 @@
202
202
  >
203
203
  <span class="flow-badge-pill ${n.cls}">${n.text}</span>
204
204
  <span class="flow-duration"
205
- >${_(t.totalDurationMs)}</span
205
+ >${y(t.totalDurationMs)}</span
206
206
  >
207
207
  </div>
208
208
  </div>
209
- <div class="flow-expand ${r?"open":""}">
210
- ${r?this.renderFlowDetail(t):p}
209
+ <div class="flow-expand ${s?"open":""}">
210
+ ${s?this.renderFlowDetail(t):d}
211
211
  </div>
212
- `}renderFlowDetail(t){let e=this.viewMode==="simple"?"Insights":"Details";return a`
212
+ `}renderFlowDetail(t){let e=this.viewMode==="simple"?"Insights":"Details";return l`
213
213
  <div class="flow-detail-tabs">
214
214
  <button
215
215
  class="flow-tab ${this.flowDetailTab==="insights"?"active":""}"
216
- @click=${r=>this.switchTab("insights",t,r)}
216
+ @click=${s=>this.switchTab("insights",t,s)}
217
217
  >
218
218
  ${e}
219
219
  </button>
220
220
  <button
221
221
  class="flow-tab ${this.flowDetailTab==="timeline"?"active":""}"
222
- @click=${r=>this.switchTab("timeline",t,r)}
222
+ @click=${s=>this.switchTab("timeline",t,s)}
223
223
  >
224
224
  Timeline
225
225
  </button>
226
226
  </div>
227
227
  ${this.flowDetailTab==="insights"?this.viewMode==="simple"?this.renderFlowInsights(t):this.renderFlowSubReqs(t):this.renderFlowWaterfall(t)}
228
- `}renderFlowWaterfall(t){if(this.flowTimelineLoading)return a`<div class="wf-loading">Loading timeline...</div>`;let{rows:e,totalMs:r}=Qs(t,this.flowTimeline);if(e.length===0)return p;let i=[];for(let n=0;n<=5;n++)i.push(_(r/5*n));return a`
228
+ `}renderFlowWaterfall(t){if(this.flowTimelineLoading)return l`<div class="wf-loading">Loading timeline...</div>`;let{rows:e,totalMs:s}=sr(t,this.flowTimeline);if(e.length===0)return d;let i=[];for(let n=0;n<=5;n++)i.push(y(s/5*n));return l`
229
229
  <div class="flow-waterfall">
230
230
  <div class="wf-time-axis">
231
- ${i.map(n=>a`<span>${n}</span>`)}
231
+ ${i.map(n=>l`<span>${n}</span>`)}
232
232
  </div>
233
233
  <div class="wf-rows">
234
234
  ${e.map(n=>this.renderWaterfallGroup(n))}
235
235
  </div>
236
236
  </div>
237
- `}renderWaterfallGroup(t){return a`
237
+ `}renderWaterfallGroup(t){return l`
238
238
  <div class="wf-request-group">
239
239
  <div class="wf-req-row" title="${t.tooltip}">
240
240
  <div class="wf-req-label">${t.label}</div>
@@ -246,48 +246,48 @@
246
246
  </div>
247
247
  <div class="wf-req-dur">${t.durLabel}</div>
248
248
  </div>
249
- ${t.subEvents.length>0?t.subEvents.map(e=>a`
249
+ ${t.subEvents.length>0?t.subEvents.map(e=>l`
250
250
  <div class="wf-sub-row" title="${e.tooltip}">
251
251
  <div class="wf-sub-label">
252
252
  <span
253
253
  class="wf-sub-dot"
254
- style="background:${Qe(e.type)}"
254
+ style="background:${ts(e.type)}"
255
255
  ></span>
256
256
  ${e.label}
257
257
  </div>
258
258
  <div class="wf-bar-track">
259
259
  <div
260
260
  class="wf-bar wf-sub-bar-sized"
261
- style="left:${t.leftPct+e.leftPct/100*t.widthPct}%;width:${e.widthPct/100*t.widthPct}%;background:${Qe(e.type)}"
261
+ style="left:${t.leftPct+e.leftPct/100*t.widthPct}%;width:${e.widthPct/100*t.widthPct}%;background:${ts(e.type)}"
262
262
  ></div>
263
263
  </div>
264
264
  <div class="wf-sub-dur">${e.durLabel}</div>
265
265
  </div>
266
- `):p}
266
+ `):d}
267
267
  </div>
268
- `}renderFlowInsights(t){let e=js(t),r=e.errors.length>0||e.duplicates.length>0||e.warnings.length>0||!!e.tip;return a`
268
+ `}renderFlowInsights(t){let e=rr(t),s=e.errors.length>0||e.duplicates.length>0||e.warnings.length>0||!!e.tip;return l`
269
269
  <div>
270
270
  <div class="flow-traffic">
271
271
  ${t.requests.map(i=>this.renderTrafficCard(i))}
272
272
  </div>
273
- ${r?a`
273
+ ${s?l`
274
274
  <div class="flow-divider"></div>
275
275
  <div class="flow-insights">
276
- ${e.errors.map(i=>a`<div class="insight-line insight-error">
276
+ ${e.errors.map(i=>l`<div class="insight-line insight-error">
277
277
  ✗ ${i}
278
278
  </div>`)}
279
- ${e.duplicates.map(i=>a`<div class="insight-line insight-warn">
279
+ ${e.duplicates.map(i=>l`<div class="insight-line insight-warn">
280
280
  ⚠ ${i.name} — loaded ${i.count}x (wasting
281
- ~${_(i.wastedMs)})
281
+ ~${y(i.wastedMs)})
282
282
  </div>`)}
283
- ${e.warnings.map(i=>a`<div class="insight-line insight-warn">⚠ ${i}</div>`)}
284
- ${e.tip?a`<div class="insight-line insight-tip">
283
+ ${e.warnings.map(i=>l`<div class="insight-line insight-warn">⚠ ${i}</div>`)}
284
+ ${e.tip?l`<div class="insight-line insight-tip">
285
285
  Tip: ${e.tip}
286
- </div>`:p}
286
+ </div>`:d}
287
287
  </div>
288
- `:p}
288
+ `:d}
289
289
  </div>
290
- `}renderTrafficCard(t){if(Gt[t.category||""])return p;let e=bt(t.statusCode),r=_(t.pollingDurationMs||t.durationMs),i=!t.isDuplicate&&t.category!==re&&t.category!==ut||t.requestBody&&t.method!=="GET"||!!t.responseBody;return a`
290
+ `}renderTrafficCard(t){if(Yt[t.category||""])return d;let e=St(t.statusCode),s=y(t.pollingDurationMs||t.durationMs),i=!t.isDuplicate&&t.category!==pe&&t.category!==bt||t.requestBody&&t.method!=="GET"||!!t.responseBody;return l`
291
291
  <div
292
292
  class="traffic-card ${t.isStrictModeDupe?"strict-mode-dupe":""}"
293
293
  >
@@ -297,58 +297,58 @@
297
297
  >${t.label}</span
298
298
  >
299
299
  <span class="status-pill ${e}">${t.statusCode}</span>
300
- <span class="traffic-card-dur">${r}</span>
301
- ${t.isDuplicate?a`<span class="traffic-card-dup">duplicate</span>`:a`<span class="traffic-card-size"
302
- >${et(t.responseSize)}</span
300
+ <span class="traffic-card-dur">${s}</span>
301
+ ${t.isDuplicate?l`<span class="traffic-card-dup">duplicate</span>`:l`<span class="traffic-card-size"
302
+ >${ot(t.responseSize)}</span
303
303
  >`}
304
304
  </div>
305
- ${t.isStrictModeDupe?a`<div class="strict-mode-banner">
305
+ ${t.isStrictModeDupe?l`<div class="strict-mode-banner">
306
306
  React Strict Mode duplicate — does not happen in production
307
- </div>`:p}
308
- ${!t.isDuplicate&&t.category!==re&&t.category!==ut?a`<div
307
+ </div>`:d}
308
+ ${!t.isDuplicate&&t.category!==pe&&t.category!==bt?l`<div
309
309
  class="request-timeline tl-hidden"
310
310
  data-request-id=${t.id}
311
311
  data-request-started=${String(t.startedAt)}
312
- ></div>`:p}
313
- ${t.requestBody&&t.method!=="GET"?this.renderBodyToggle("out","Request Body",t.requestBody):p}
314
- ${t.responseBody?this.renderBodyToggle("in","Response Body",t.responseBody):p}
312
+ ></div>`:d}
313
+ ${t.requestBody&&t.method!=="GET"?this.renderBodyToggle("out","Request Body",t.requestBody):d}
314
+ ${t.responseBody?this.renderBodyToggle("in","Response Body",t.responseBody):d}
315
315
  </div>
316
- `}renderBodyToggle(t,e,r){let i=t==="out"?"\u2192":"\u2190";return a`
316
+ `}renderBodyToggle(t,e,s){let i=t==="out"?"\u2192":"\u2190";return l`
317
317
  <div class="traffic-body">
318
318
  <button class="traffic-body-toggle" @click=${this.toggleBodyBlock}>
319
319
  <span class="chevron">▸</span
320
320
  ><span class="arrow-${t}">${i}</span> ${e}
321
321
  </button>
322
- <pre>${U(nt(r))}</pre>
322
+ <pre>${G(dt(s))}</pre>
323
323
  </div>
324
- `}renderFlowSubReqs(t){return a`<div class="flow-subreqs">
325
- ${t.requests.map((e,r)=>this.renderSubReqRow(e,r))}
326
- </div>`}renderSubReqRow(t,e){let r=this.expandedSubReqIdx===e,i=bt(t.statusCode),n=t.pollingDurationMs?_(t.pollingDurationMs):_(t.durationMs);return a`
324
+ `}renderFlowSubReqs(t){return l`<div class="flow-subreqs">
325
+ ${t.requests.map((e,s)=>this.renderSubReqRow(e,s))}
326
+ </div>`}renderSubReqRow(t,e){let s=this.expandedSubReqIdx===e,i=St(t.statusCode),n=t.pollingDurationMs?y(t.pollingDurationMs):y(t.durationMs);return l`
327
327
  <div
328
- class="flow-subreq ${r?"expanded":""}"
329
- @click=${l=>this.toggleSubReq(e,l)}
328
+ class="flow-subreq ${s?"expanded":""}"
329
+ @click=${a=>this.toggleSubReq(e,a)}
330
330
  >
331
331
  <bk-method-badge .method=${t.method}></bk-method-badge>
332
332
  <span class="subreq-label ${t.isDuplicate?"is-dup":""}"
333
333
  >${t.path||t.url}</span
334
334
  >
335
- ${t.isDuplicate?a`<span class="subreq-dup-tag">duplicate</span>`:p}
335
+ ${t.isDuplicate?l`<span class="subreq-dup-tag">duplicate</span>`:d}
336
336
  <span class="status-pill ${i}">${t.statusCode}</span>
337
337
  <span class="subreq-dur">${n}</span>
338
338
  </div>
339
- <div class="flow-subreq-detail ${r?"open":""}">
340
- ${r?this.renderSubReqDetail(t):p}
339
+ <div class="flow-subreq-detail ${s?"open":""}">
340
+ ${s?this.renderSubReqDetail(t):d}
341
341
  </div>
342
- `}renderSubReqDetail(t){let e=bt(t.statusCode);return a`
342
+ `}renderSubReqDetail(t){let e=St(t.statusCode);return l`
343
343
  <div class="detail-meta">
344
344
  <span
345
- ><bk-method-badge .method=${t.method}></bk-method-badge> ${tt(t.url)}</span
345
+ ><bk-method-badge .method=${t.method}></bk-method-badge> ${it(t.url)}</span
346
346
  >
347
347
  <span
348
348
  ><span class="status-pill ${e}">${t.statusCode}</span></span
349
349
  >
350
350
  <span>${t.durationMs}ms</span>
351
- ${t.responseSize?a`<span>${et(t.responseSize)}</span>`:p}
351
+ ${t.responseSize?l`<span>${ot(t.responseSize)}</span>`:d}
352
352
  </div>
353
353
  <div
354
354
  class="request-timeline tl-hidden"
@@ -358,30 +358,30 @@
358
358
  <div class="detail-grid">
359
359
  <div class="detail-section">
360
360
  <h4>Request Headers</h4>
361
- <pre>${U(Et(t.headers))}</pre>
361
+ <pre>${G(Tt(t.headers))}</pre>
362
362
  </div>
363
363
  <div class="detail-section">
364
364
  <h4>Response Headers</h4>
365
- <pre>${U(Et(t.responseHeaders))}</pre>
365
+ <pre>${G(Tt(t.responseHeaders))}</pre>
366
366
  </div>
367
367
  <div class="detail-section">
368
368
  <h4>Request Body</h4>
369
- <pre>${U(nt(t.requestBody))}</pre>
369
+ <pre>${G(dt(t.requestBody))}</pre>
370
370
  </div>
371
371
  <div class="detail-section">
372
372
  <h4>Response Body</h4>
373
- <pre>${U(nt(t.responseBody))}</pre>
373
+ <pre>${G(dt(t.responseBody))}</pre>
374
374
  </div>
375
375
  </div>
376
376
  <div class="detail-actions">
377
377
  <button
378
378
  class="btn btn-curl"
379
- @click=${r=>{r.stopPropagation(),Tt(t);}}
379
+ @click=${s=>{s.stopPropagation(),Lt(t);}}
380
380
  >
381
381
  Copy cURL
382
382
  </button>
383
383
  </div>
384
- `}};u([I({context:A})],W.prototype,"store",2),u([b()],W.prototype,"expandedFlowIdx",2),u([b()],W.prototype,"expandedSubReqIdx",2),u([b()],W.prototype,"flowDetailTab",2),u([b()],W.prototype,"flowTimeline",2),u([b()],W.prototype,"flowTimelineLoading",2),W=u([S("bk-flows-view")],W);var Vt=class extends E{createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}render(){let s=(this.store.state.issues||[]).slice(),t=s.filter(l=>l.state==="open"||l.state==="fixing"||l.state==="regressed"),e=s.filter(l=>l.state==="resolved");if(t.length===0&&e.length===0)return this.store.state.requests.length>0||this.store.state.logs.length>0||this.store.state.queries.length>0?a`
384
+ `}};u([C({context:A})],X.prototype,"store",2),u([b()],X.prototype,"expandedFlowIdx",2),u([b()],X.prototype,"expandedSubReqIdx",2),u([b()],X.prototype,"flowDetailTab",2),u([b()],X.prototype,"flowTimeline",2),u([b()],X.prototype,"flowTimelineLoading",2),X=u([_("bk-flows-view")],X);var ee=class extends E{createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}render(){let r=(this.store.state.issues||[]).slice(),t=r.filter(a=>a.state==="open"||a.state==="fixing"||a.state==="regressed"),e=r.filter(a=>a.state==="resolved");if(t.length===0&&e.length===0)return this.store.state.requests.length>0||this.store.state.logs.length>0||this.store.state.queries.length>0?l`
385
385
  <div class="sec-clear">
386
386
  <span class="sec-clear-icon">\u2713</span>
387
387
  <div class="sec-clear-text">
@@ -389,10 +389,10 @@
389
389
  <div class="sec-clear-sub">No security or quality issues detected this session</div>
390
390
  </div>
391
391
  </div>
392
- `:a`<bk-empty-state title="Waiting for requests..." subtitle="Start using your app to see security findings here"></bk-empty-state>`;let r=0,i=0,n=0;for(let l of t){let c=l.issue.severity;c==="critical"?r++:c==="info"?n++:i++;}return a`
392
+ `:l`<bk-empty-state title="Waiting for requests..." subtitle="Start using your app to see security findings here"></bk-empty-state>`;let s=0,i=0,n=0;for(let a of t){let c=a.issue.severity;c==="critical"?s++:c==="info"?n++:i++;}return l`
393
393
  <div id="security-content">
394
- ${this.renderSummary(t.length,e.length,r,i,n)}
395
- ${t.length===0&&e.length>0?a`
394
+ ${this.renderSummary(t.length,e.length,s,i,n)}
395
+ ${t.length===0&&e.length>0?l`
396
396
  <div class="sec-clear">
397
397
  <span class="sec-clear-icon">\u2713</span>
398
398
  <div class="sec-clear-text">
@@ -400,152 +400,114 @@
400
400
  <div class="sec-clear-sub">${e.length} finding${e.length!==1?"s were":" was"} detected and fixed</div>
401
401
  </div>
402
402
  </div>
403
- `:p}
404
- ${t.length>0?this.renderOpenGroups(t):p}
405
- ${e.length>0?this.renderResolved(e):p}
403
+ `:d}
404
+ ${t.length>0?this.renderOpenGroups(t):d}
405
+ ${e.length>0?this.renderResolved(e):d}
406
406
  </div>
407
- `}renderSummary(s,t,e,r,i){return a`
407
+ `}renderSummary(r,t,e,s,i){return l`
408
408
  <div class="sec-summary">
409
409
  <div class="sec-summary-left">
410
- <span class="sec-summary-count">${s}</span>
411
- <span class="sec-summary-label">open issue${s!==1?"s":""}</span>
412
- ${t>0?a`<span class="sec-resolved-badge">${t} resolved</span>`:p}
410
+ <span class="sec-summary-count">${r}</span>
411
+ <span class="sec-summary-label">open issue${r!==1?"s":""}</span>
412
+ ${t>0?l`<span class="sec-resolved-badge">${t} resolved</span>`:d}
413
413
  </div>
414
414
  <div class="sec-summary-right">
415
- ${e>0?a`<span class="sec-badge critical">${e} critical</span>`:p}
416
- ${r>0?a`<span class="sec-badge warning">${r} warning</span>`:p}
417
- ${i>0?a`<span class="sec-badge info">${i} info</span>`:p}
415
+ ${e>0?l`<span class="sec-badge critical">${e} critical</span>`:d}
416
+ ${s>0?l`<span class="sec-badge warning">${s} warning</span>`:d}
417
+ ${i>0?l`<span class="sec-badge info">${i} info</span>`:d}
418
418
  </div>
419
419
  </div>
420
- `}renderOpenGroups(s){let t={},e=[];for(let r of s){let i=r.issue,n=i.rule||i.type;t[n]||(t[n]={rule:n,title:i.title,severity:i.severity,hint:i.hint,items:[]},e.push(n)),t[n].items.push(r);}return e.sort((r,i)=>{let n=Z[t[r].severity]?.sort??2,l=Z[t[i].severity]?.sort??2;return n!==l?n-l:t[i].items.length-t[r].items.length}),a`${e.map(r=>this.renderGroup(t[r]))}`}renderGroup(s){let t=Z[s.severity]||Z.info;return a`
420
+ `}renderOpenGroups(r){let t={},e=[];for(let s of r){let i=s.issue,n=i.rule;t[n]||(t[n]={rule:n,title:i.title,severity:i.severity,hint:i.hint,items:[]},e.push(n)),t[n].items.push(s);}return e.sort((s,i)=>{let n=Y[t[s].severity]?.sort??2,a=Y[t[i].severity]?.sort??2;return n!==a?n-a:t[i].items.length-t[s].items.length}),l`${e.map(s=>this.renderGroup(t[s]))}`}renderGroup(r){let t=Y[r.severity]||Y.info;return l`
421
421
  <div class="sec-group">
422
422
  <div class="sec-group-header">
423
423
  <span class="sec-group-icon ${t.cls}">${t.icon}</span>
424
- <span class="sec-group-title">${s.title}</span>
425
- <span class="sec-group-count">${s.items.length}</span>
424
+ <span class="sec-group-title">${r.title}</span>
425
+ <span class="sec-group-count">${r.items.length}</span>
426
426
  </div>
427
- ${s.hint?a`<div class="sec-hint">${s.hint}</div>`:p}
428
- <div class="sec-items">${s.items.map(e=>this.renderIssueItem(e))}</div>
427
+ ${r.hint?l`<div class="sec-hint">${r.hint}</div>`:d}
428
+ <div class="sec-items">${r.items.map(e=>this.renderIssueItem(e))}</div>
429
429
  </div>
430
- `}renderIssueItem(s){let t=s.issue;return a`
430
+ `}renderIssueItem(r){let t=r.issue;return l`
431
431
  <div class="sec-item">
432
432
  <div class="sec-item-desc">${t.desc}</div>
433
- ${s.occurrences>1?a`<span class="sec-item-count">${s.occurrences}x</span>`:p}
434
- ${s.state==="fixing"&&s.aiStatus==="fixed"?a`<span class="sec-ai-badge sec-ai-fixing">AI fixed \u2014 awaiting verification</span>`:s.aiStatus==="wont_fix"?a`<span class="sec-ai-badge sec-ai-wontfix">AI: won\u2019t fix</span>`:s.state==="regressed"?a`<span class="sec-ai-badge sec-ai-fixing" style="background:var(--red)">regressed</span>`:p}
435
- ${s.aiNotes?a`<div class="sec-ai-notes">${s.aiNotes}</div>`:p}
433
+ ${r.occurrences>1?l`<span class="sec-item-count">${r.occurrences}x</span>`:d}
434
+ ${r.state==="fixing"&&r.aiStatus==="fixed"?l`<span class="sec-ai-badge sec-ai-fixing">AI fixed \u2014 awaiting verification</span>`:r.aiStatus==="wont_fix"?l`<span class="sec-ai-badge sec-ai-wontfix">AI: won\u2019t fix</span>`:r.state==="regressed"?l`<span class="sec-ai-badge sec-ai-fixing" style="background:var(--red)">regressed</span>`:d}
435
+ ${r.aiNotes?l`<div class="sec-ai-notes">${r.aiNotes}</div>`:d}
436
436
  </div>
437
- `}renderResolved(s){return a`
437
+ `}renderResolved(r){return l`
438
438
  <div class="sec-resolved-title">
439
439
  <span class="sec-resolved-check">\u2713</span> Resolved
440
- <span class="sec-resolved-count">${s.length}</span>
440
+ <span class="sec-resolved-count">${r.length}</span>
441
441
  </div>
442
442
  <div class="sec-group sec-group-resolved">
443
443
  <div class="sec-items">
444
- ${s.map(t=>a`
444
+ ${r.map(t=>l`
445
445
  <div class="sec-item sec-item-resolved">
446
446
  <span class="sec-resolved-item-icon">\u2713</span>
447
447
  <div class="sec-item-desc">${t.issue.title} \u2014 ${t.issue.endpoint||"global"}</div>
448
- ${t.aiStatus==="fixed"?a`<span class="sec-ai-badge sec-ai-verified">Verified fix</span>`:p}
449
- ${t.aiNotes?a`<div class="sec-ai-notes">${t.aiNotes}</div>`:p}
448
+ ${t.aiStatus==="fixed"?l`<span class="sec-ai-badge sec-ai-verified">Verified fix</span>`:d}
449
+ ${t.aiNotes?l`<div class="sec-ai-notes">${t.aiNotes}</div>`:d}
450
450
  </div>
451
451
  `)}
452
452
  </div>
453
453
  </div>
454
- `}};u([I({context:A})],Vt.prototype,"store",2),Vt=u([S("bk-security-view")],Vt);var Rt=class extends E{constructor(){super(...arguments);this.expandedCardIdx=-1;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}toggleCard(t){this.expandedCardIdx=this.expandedCardIdx===t?-1:t;}render(){let t=this.store.state,e=t.requests.filter(y=>!y.isStatic&&!y.isHealthCheck&&(!y.path||y.path.indexOf(F)!==0));if(!(e.length>0||t.queries.length>0||t.errors.length>0))return a`<bk-empty-state
455
- title="Waiting for requests..."
456
- subtitle="Start using your app to see insights here"
457
- ></bk-empty-state>`;let i=e.filter(y=>y.statusCode>=400).length,n=new Set(["data-fetch","api-call","server-action","page-load"]),l=e.filter(y=>y.category&&n.has(y.category)),c=l.length>0?l:e,d=c.length>0?Math.round(c.reduce((y,k)=>y+k.durationMs,0)/c.length):0,h=t.issues||[],m=h.filter(y=>y.state==="open"||y.state==="regressed"),v=h.filter(y=>y.state==="fixing"),x=h.filter(y=>y.state==="resolved");return a`
458
- <div class="ov-container" id="overview-content">
459
- ${this.renderSummary(e.length,t.flows.length,d,t.queries.length,i,t.fetches.length)}
460
- ${m.length===0&&v.length===0&&x.length===0?a`<div class="ov-clear">
461
- <span class="ov-clear-icon">\u2713</span>All clear \u2014 no issues detected
462
- </div>`:p}
463
- ${m.length===0&&x.length>0?a`<div class="ov-clear">
464
- <span class="ov-clear-icon">\u2713</span>All issues resolved \u2014
465
- ${x.length} finding${x.length!==1?"s were":" was"} detected and
466
- fixed
467
- </div>`:p}
468
- ${m.length>0?this.renderOpenIssues(m):p}
469
- ${v.length>0?this.renderVerifying(v):p}
470
- ${x.length>0?this.renderResolvedIssues(x):p}
471
- </div>
472
- `}renderSummary(t,e,r,i,n,l){return a`
473
- <div class="ov-summary">
474
- <div class="ov-stat"><span class="ov-stat-value">${t}</span><span class="ov-stat-label">Requests</span></div>
475
- <div class="ov-stat"><span class="ov-stat-value">${e}</span><span class="ov-stat-label">Actions</span></div>
476
- <div class="ov-stat"><span class="ov-stat-value">${_(r)}</span><span class="ov-stat-label">Avg Response</span></div>
477
- <div class="ov-stat"><span class="ov-stat-value">${i}</span><span class="ov-stat-label">Queries</span></div>
478
- <div class="ov-stat"><span class="ov-stat-value" style="color:${n>0?"var(--red)":"var(--green)"}">${n}</span><span class="ov-stat-label">Errors</span></div>
479
- <div class="ov-stat"><span class="ov-stat-value">${l}</span><span class="ov-stat-label">Fetches</span></div>
480
- </div>
481
- `}renderOpenIssues(t){return a`
482
- <div class="ov-section-title">Issues Found <span class="ov-issue-count">${t.length}</span></div>
483
- <div class="ov-cards">${t.map((e,r)=>this.renderIssueCard(e,r))}</div>
484
- `}renderIssueCard(t,e){let r=t.issue,i=Z[r.severity]||Z.info,n=this.expandedCardIdx===e,l=t.aiStatus==="wont_fix"?a`<span class="sec-ai-badge sec-ai-wontfix">AI: won\u2019t fix</span>`:t.state==="regressed"?a`<span class="sec-ai-badge sec-ai-fixing" style="background:var(--red)">regressed</span>`:p,c=t.cleanHitsSinceLastSeen>0?a`<div class="ov-card-resolving">Resolving\u2026 ${t.cleanHitsSinceLastSeen}/${5} clean requests</div>`:p;return a`
485
- <div class="ov-card ${n?"expanded":""}" @click=${()=>this.toggleCard(e)}>
486
- <span class="ov-card-icon ${i.cls}">${i.icon}</span>
487
- <div class="ov-card-body">
488
- <div class="ov-card-title">${r.title}${l}</div>
489
- <div class="ov-card-desc">${r.desc}</div>
490
- ${r.detail?a`<div class="ov-card-detail">${r.detail}</div>`:p}
491
- ${c}
492
- ${n&&r.hint?a`<div class="ov-card-hint">${r.hint}</div>`:p}
454
+ `}};u([C({context:A})],ee.prototype,"store",2),ee=u([_("bk-security-view")],ee);var J=class extends E{constructor(){super(...arguments);this.handleStateChanged=()=>this.requestUpdate();}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",this.handleStateChanged);}disconnectedCallback(){super.disconnectedCallback(),this.store.removeEventListener("state-changed",this.handleStateChanged);}};u([C({context:A})],J.prototype,"store",2);async function j(o){let r=await fetch(o);if(!r.ok)throw new Error(`HTTP ${r.status}: ${o}`);return r.json()}function B(o,r,t){return o===1?r:t??`${r}s`}function ir(o){return o.state!=="stale"}function _e(o){return (o.state==="open"||o.state==="regressed")&&o.aiStatus!=="wont_fix"}var se=class extends J{constructor(){super(...arguments);this.graphSummary=null;}connectedCallback(){super.connectedCallback(),this.loadGraphSummary();}async loadGraphSummary(){try{let e=(await j(`${T.graph}?level=endpoints`)).nodes||[];this.graphSummary={endpoints:e.filter(s=>s.type==="endpoint").length,tables:e.filter(s=>s.type==="table").length,externals:e.filter(s=>s.type==="external").length};}catch{}}navigateTo(t){this.store.setActiveView(t);}navigateToExplorerErrors(){this.store.setActiveView("explorer"),window.dispatchEvent(new CustomEvent("navigate-explorer",{detail:"errors"}));}render(){let t=this.store.state,e=t.requests.filter(i=>!i.isStatic&&!i.isHealthCheck&&(!i.path||i.path.indexOf(U)!==0));return e.length>0||t.queries.length>0?l`
455
+ <div class="ov-container">
456
+ <div class="ov-grid">
457
+ ${this.renderActionsCard(t.flows)}
458
+ ${this.renderInsightsCard(t.issues)}
459
+ ${this.renderPerformanceCard(e)}
460
+ ${this.renderErrorsCard(e)}
461
+ ${this.renderGraphCard()}
493
462
  </div>
494
- ${r.hint?a`<span class="ov-card-arrow">${n?"\u2193":"\u2192"}</span>`:p}
495
- </div>
496
- `}renderVerifying(t){return a`
497
- <div class="ov-section-title ov-resolved-title">
498
- <span style="color:var(--yellow,#f5a623)">\u29d7</span> Awaiting Verification
499
- <span class="ov-issue-count">${t.length}</span>
500
- </div>
501
- <div class="ov-cards">
502
- ${t.map(e=>{let r=e.issue,i=e.cleanHitsSinceLastSeen>0?a`<div class="ov-card-resolving">Verifying\u2026 ${e.cleanHitsSinceLastSeen}/${5} clean requests</div>`:p;return a`
503
- <div class="ov-card ov-card-resolved">
504
- <span class="ov-card-icon resolved">\u29d7</span>
505
- <div class="ov-card-body">
506
- <div class="ov-card-title" style="color:var(--text-muted)">
507
- ${r.title}
508
- <span class="sec-ai-badge sec-ai-fixing">AI fixed \u2014 awaiting verification</span>
509
- </div>
510
- <div class="ov-card-desc">${r.desc}</div>
511
- ${i}
512
- </div>
513
- </div>
514
- `})}
515
463
  </div>
516
- `}renderResolvedIssues(t){return a`
517
- <div class="ov-section-title ov-resolved-title">
518
- <span style="color:var(--green)">\u2713</span> Resolved
519
- <span class="ov-issue-count">${t.length}</span>
520
- </div>
521
- <div class="ov-cards">
522
- ${t.map(e=>a`
523
- <div class="ov-card ov-card-resolved">
524
- <span class="ov-card-icon resolved">\u2713</span>
525
- <div class="ov-card-body">
526
- <div class="ov-card-title" style="text-decoration:line-through;color:var(--text-muted)">${e.issue.title}</div>
527
- <div class="ov-card-desc">${e.issue.desc}</div>
528
- </div>
529
- </div>
530
- `)}
464
+ `:l`<bk-empty-state
465
+ title="${N.EMPTY_TITLE}"
466
+ subtitle="${N.EMPTY_SUBTITLE_OVERVIEW}"
467
+ ></bk-empty-state>`}renderActionsCard(t){let e=t.length;if(e===0)return this.renderEmptyCard("\u25B6","Actions",N.NO_ACTIONS,"actions");let s=Math.round(t.reduce((n,a)=>n+a.totalDurationMs,0)/e),i=t[0]?.label||"";return this.renderCard("\u25B6",`${e} ${B(e,"action")}`,`avg ${y(s)}${i?` \xB7 "${i}"`:""}`,"actions","var(--accent)")}renderInsightsCard(t){let e=(t||[]).filter(_e);if(e.length===0)return this.renderCard("\u2713",N.ALL_CLEAR,N.ALL_CLEAR_DETAIL,"insights","var(--green)");let s=e.filter(a=>a.issue.severity==="critical").length,i=e.filter(a=>a.issue.severity==="warning").length,n=[];return s>0&&n.push(`${s} critical`),i>0&&n.push(`${i} warning`),this.renderCard("\u{1F4A1}",`${e.length} ${B(e.length,"issue")}`,n.join(" \xB7 ")||N.REVIEW_RECOMMENDED,"insights","var(--amber)")}renderPerformanceCard(t){if(t.length===0)return this.renderEmptyCard("\u26A1","Performance",N.NO_REQUEST_DATA,"performance");let e=new Map;for(let n of t){let a=`${n.method} ${n.path}`,c=e.get(a);c||(c=[],e.set(a,c)),c.push(n.durationMs);}let s=[];for(let[n,a]of e){let c=Math.round(a.reduce((p,h)=>p+h,0)/a.length);c>2e3&&s.push({key:n,avg:c});}if(s.sort((n,a)=>a.avg-n.avg),s.length===0)return this.renderCard("\u26A1",N.ALL_FAST,N.NO_SLOW_ENDPOINTS,"performance","var(--green)");let i=s[0];return this.renderCard("\u26A1",`${s.length} slow ${B(s.length,"endpoint")}`,`worst: ${i.key} \xB7 ${y(i.avg)}`,"performance","var(--amber)")}renderErrorsCard(t){let e=t.filter(n=>n.statusCode>=400);if(e.length===0)return this.renderCard("\u2713",N.ZERO_ERRORS,N.ALL_REQUESTS_OK,"explorer","var(--green)");let s=new Map;for(let n of e)s.set(n.statusCode,(s.get(n.statusCode)||0)+1);let i=[...s.entries()].sort((n,a)=>a[1]-n[1]).slice(0,3).map(([n,a])=>`${a}\xD7 ${n}`);return l`
468
+ <div class="ov-card-nav" @click=${()=>this.navigateToExplorerErrors()}>
469
+ <div class="ov-card-icon-lg" style="color:var(--red)">\u2715</div>
470
+ <div class="ov-card-content">
471
+ <div class="ov-card-headline">${e.length} ${B(e.length,"error")}</div>
472
+ <div class="ov-card-context">${i.join(" \xB7 ")}</div>
473
+ </div>
474
+ <span class="ov-card-arrow">\u2192</span>
475
+ </div>
476
+ `}renderGraphCard(){let t=this.graphSummary;if(!t||t.endpoints===0&&t.tables===0)return this.renderEmptyCard("\u25CE","Graph",N.BUILD_GRAPH,"graph");let e=[];t.endpoints>0&&e.push(`${t.endpoints} ${B(t.endpoints,"endpoint")}`),t.tables>0&&e.push(`${t.tables} ${B(t.tables,"table")}`);let s=t.externals>0?`${t.externals} external ${B(t.externals,"service")}`:"";return this.renderCard("\u25CE",e.join(" \xB7 "),s,"graph","var(--accent)")}renderCard(t,e,s,i,n){return l`
477
+ <div class="ov-card-nav" @click=${()=>this.navigateTo(i)}>
478
+ <div class="ov-card-icon-lg" style="color:${n}">${t}</div>
479
+ <div class="ov-card-content">
480
+ <div class="ov-card-headline">${e}</div>
481
+ ${s?l`<div class="ov-card-context">${s}</div>`:d}
482
+ </div>
483
+ <span class="ov-card-arrow">\u2192</span>
484
+ </div>
485
+ `}renderEmptyCard(t,e,s,i){return l`
486
+ <div class="ov-card-nav ov-card-empty" @click=${()=>this.navigateTo(i)}>
487
+ <div class="ov-card-icon-lg">${t}</div>
488
+ <div class="ov-card-content">
489
+ <div class="ov-card-headline">${e}</div>
490
+ <div class="ov-card-context">${s}</div>
491
+ </div>
492
+ <span class="ov-card-arrow">\u2192</span>
531
493
  </div>
532
- `}};u([I({context:A})],Rt.prototype,"store",2),u([b()],Rt.prototype,"expandedCardIdx",2),Rt=u([S("bk-overview-view")],Rt);function Ys(o){return o<1?"<1ms":o<1e3?Math.round(o)+"ms":(o/1e3).toFixed(1)+"s"}function oi(o){return o<mt?Bt.green:o<ft?Bt.amber:Bt.red}function ni(o){return o.statusCode>=400?Bt.red:oi(o.durationMs)}function Xs(o){return [parseInt(o.slice(1,3),16),parseInt(o.slice(3,5),16),parseInt(o.slice(5,7),16)]}function ai(o){let s=o.getContext("2d");if(!s)return null;let t=window.devicePixelRatio||1,e=o.clientWidth,r=o.clientHeight;return o.width=e*t,o.height=r*t,s.scale(t,t),{ctx:s,w:e,h:r}}function li(o,s,t,e,r){let[i,n,l]=Xs(r);o.beginPath(),o.arc(s,t,e+2,0,Math.PI*2),o.fillStyle=`rgba(${i},${n},${l},0.25)`,o.fill(),o.beginPath(),o.arc(s,t,e,0,Math.PI*2),o.fillStyle=r,o.fill();}function ci(o,s,t,e,r,i){let[n,l,c]=Xs(r);o.strokeStyle=`rgba(${n},${l},${c},0.3)`,o.lineWidth=i+2,o.beginPath(),o.moveTo(s-e,t-e),o.lineTo(s+e,t+e),o.moveTo(s+e,t-e),o.lineTo(s-e,t+e),o.stroke(),o.strokeStyle=r,o.lineWidth=i,o.beginPath(),o.moveTo(s-e,t-e),o.lineTo(s+e,t+e),o.moveTo(s+e,t-e),o.lineTo(s-e,t+e),o.stroke();}function Vs(o,s){let t=[],e=ai(o);if(!e||s.length===0)return t;let{ctx:r,w:i,h:n}=e,l=Ls,c=i-l.left-l.right,d=n-l.top-l.bottom,h=0,m=s[0].timestamp,v=s[0].timestamp;for(let $ of s)$.durationMs>h&&(h=$.durationMs),$.timestamp<m&&(m=$.timestamp),$.timestamp>v&&(v=$.timestamp);h=Math.max(h,10),h=Math.ceil(h*1.15/10)*10;let x=v-m||1;r.strokeStyle=Is,r.lineWidth=1;let y=4;for(let $=0;$<=y;$++){let f=l.top+d-$/y*d;r.beginPath(),r.moveTo(l.left,f),r.lineTo(l.left+c,f),r.stroke(),r.fillStyle=Ue,r.font=Cs,r.textAlign="right",r.fillText(Ys(Math.round($/y*h)),l.left-8,f+3);}for(let $ of [{ms:mt},{ms:ft}]){if($.ms>=h)continue;let f=l.top+d-$.ms/h*d;r.beginPath(),r.setLineDash([4,4]),r.strokeStyle="rgba(113,113,122,0.3)",r.lineWidth=1,r.moveTo(l.left,f),r.lineTo(l.left+c,f),r.stroke(),r.setLineDash([]),r.fillStyle="rgba(113,113,122,0.5)",r.font=Fe,r.textAlign="left",r.fillText(Ys($.ms),l.left+c+2,f+3);}for(let $=0;$<s.length;$++){let f=s[$],g=s.length===1?l.left+c/2:l.left+(f.timestamp-m)/x*c,T=l.top+d-f.durationMs/h*d,R=ni(f);t.push({x:g,y:T,idx:$,r:f}),f.statusCode>=400?ci(r,g,T,4,R,2):li(r,g,T,4,R);}r.fillStyle=Ue,r.font=Fe,r.textAlign="center";let k=[m,m+x/2,v];for(let $=0;$<k.length;$++){let f=l.left+$/2*c,g=new Date(k[$]);r.fillText(g.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),f,l.top+d+14);}return t}var fi={max:1/0,label:"Pending",color:"var(--text-muted)",bg:"var(--bg-muted)",border:"var(--border)"};function Ks(o,s,t){return t>=20?o:s}function Ye(o,s){if(!s||s<=0)return fi;let t=o/s;return t<.7?gt[0]:t<1.2?gt[1]:t<2?gt[2]:t<3?gt[3]:gt[4]}var Q=class extends E{constructor(){super(...arguments);this.selectedEndpoint=J;this.graphData=[];this.loadError=false;this.queryBreakdown=[];this.queryBreakdownLoading=false;this.scatterDots=[];}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate()),this.loadMetrics();}async loadMetrics(){try{let e=await(await fetch(w.metricsLive)).json();this.graphData=e.endpoints||[],this.loadError=!1,(!this.selectedEndpoint||this.selectedEndpoint===J)&&(this.selectedEndpoint=J);}catch{this.loadError=true;}}healthGradeForEndpoint(t){let e=Ks(t.summary.p95Ms,t.summary.medianMs,t.summary.totalRequests);return Ye(e,t.baselineP95Ms)}healthGradeForDuration(t,e){return Ye(t,e)}getCallers(t){let e=this.store.state.flows,r=new Map;for(let i of e)for(let n of i.requests)if(`${n.method} ${n.path}`===t||this.normalizeEndpoint(n)===t){let c=r.get(i.label);c?(c.count++,c.totalMs+=n.durationMs):r.set(i.label,{count:1,totalMs:n.durationMs});}return [...r.entries()].map(([i,n])=>({label:i,count:n.count,avgMs:Math.round(n.totalMs/n.count)})).sort((i,n)=>n.count-i.count)}normalizeEndpoint(t){let r=t.path.split("?")[0].split("/").map(i=>{if(!i)return i;let n=i.length>0;for(let l=0;l<i.length;l++){let c=i.charCodeAt(l);if(c<48||c>57){n=false;break}}return n||i.length===36&&i[8]==="-"&&i[13]==="-"&&i[18]==="-"&&i[23]==="-"?":id":i}).join("/");return `${t.method} ${r}`}async loadQueryBreakdown(t){if(this.queryBreakdownLoading)return;let r=this.store.state.requests.filter(i=>`${i.method} ${i.path}`===t||this.normalizeEndpoint(i)===t).slice(-20).map(i=>i.id).filter(Boolean);if(r.length===0){this.queryBreakdown=[];return}this.queryBreakdownLoading=true;try{let i=await fetch(`${w.activity}?requestIds=${r.join(",")}`);if(!i.ok){this.queryBreakdownLoading=!1;return}let n=await i.json(),l=new Map;for(let c of Object.values(n.activities))for(let d of c.timeline){if(d.type!=="query")continue;let h=d.data,m=(h.normalizedOp||h.operation||"QUERY").toUpperCase(),v=h.table||h.model||"",x=`${m} ${v}`.trim(),y=l.get(x);y?(y.totalMs+=h.durationMs,y.count++):l.set(x,{label:x,totalMs:h.durationMs,count:1});}this.queryBreakdown=[...l.values()].map(c=>({...c,avgMs:Math.round(c.totalMs/c.count)})).sort((c,d)=>d.totalMs-c.totalMs);}catch{}this.queryBreakdownLoading=false;}renderScatterChart(t,e){this.scatterDots=Vs(t,e),t.style.cursor="pointer",t.onclick=r=>{let i=t.getBoundingClientRect(),n=r.clientX-i.left,l=r.clientY-i.top,c=null,d=1/0;for(let h of this.scatterDots){let m=Math.sqrt((h.x-n)**2+(h.y-l)**2);m<d&&(d=m,c=h);}c&&d<16&&this.highlightRow(c.idx);};}highlightRow(t){let e=this.querySelector(".perf-hist-row-hl");e&&e.classList.remove("perf-hist-row-hl");let r=this.querySelector(`[data-req-idx="${t}"]`);r&&(r.classList.add("perf-hist-row-hl"),r.scrollIntoView({behavior:"smooth",block:"center"}));}updated(){if(this.selectedEndpoint===J)return;let t=this.querySelector("#perf-detail-canvas");if(t){let e=this.graphData.find(r=>r.endpoint===this.selectedEndpoint);e&&this.renderScatterChart(t,e.requests);}}render(){return !this.graphData||this.graphData.length===0?a`<bk-empty-state title="No performance data yet" subtitle="Hit some endpoints and data will appear here"></bk-empty-state>`:a`
494
+ `}};u([b()],se.prototype,"graphSummary",2),se=u([_("bk-overview-view")],se);function or(o){return o<1?"<1ms":o<1e3?Math.round(o)+"ms":(o/1e3).toFixed(1)+"s"}function fi(o){return o<yt?Vt.green:o<$t?Vt.amber:Vt.red}function vi(o){return o.statusCode>=400?Vt.red:fi(o.durationMs)}function nr(o){return [parseInt(o.slice(1,3),16),parseInt(o.slice(3,5),16),parseInt(o.slice(5,7),16)]}function gi(o){let r=o.getContext("2d");if(!r)return null;let t=window.devicePixelRatio||1,e=o.clientWidth,s=o.clientHeight;return o.width=e*t,o.height=s*t,r.scale(t,t),{ctx:r,w:e,h:s}}function bi(o,r,t,e,s){let[i,n,a]=nr(s);o.beginPath(),o.arc(r,t,e+2,0,Math.PI*2),o.fillStyle=`rgba(${i},${n},${a},0.25)`,o.fill(),o.beginPath(),o.arc(r,t,e,0,Math.PI*2),o.fillStyle=s,o.fill();}function Ei(o,r,t,e,s,i){let[n,a,c]=nr(s);o.strokeStyle=`rgba(${n},${a},${c},0.3)`,o.lineWidth=i+2,o.beginPath(),o.moveTo(r-e,t-e),o.lineTo(r+e,t+e),o.moveTo(r+e,t-e),o.lineTo(r-e,t+e),o.stroke(),o.strokeStyle=s,o.lineWidth=i,o.beginPath(),o.moveTo(r-e,t-e),o.lineTo(r+e,t+e),o.moveTo(r+e,t-e),o.lineTo(r-e,t+e),o.stroke();}function ar(o,r){let t=[],e=gi(o);if(!e||r.length===0)return t;let{ctx:s,w:i,h:n}=e,a=Gs,c=i-a.left-a.right,p=n-a.top-a.bottom,h=0,m=r[0].timestamp,f=r[0].timestamp;for(let $ of r)$.durationMs>h&&(h=$.durationMs),$.timestamp<m&&(m=$.timestamp),$.timestamp>f&&(f=$.timestamp);h=Math.max(h,10),h=Math.ceil(h*1.15/10)*10;let S=f-m||1;s.strokeStyle=Us,s.lineWidth=1;let R=4;for(let $=0;$<=R;$++){let v=a.top+p-$/R*p;s.beginPath(),s.moveTo(a.left,v),s.lineTo(a.left+c,v),s.stroke(),s.fillStyle=Ve,s.font=Fs,s.textAlign="right",s.fillText(or(Math.round($/R*h)),a.left-8,v+3);}for(let $ of [{ms:yt},{ms:$t}]){if($.ms>=h)continue;let v=a.top+p-$.ms/h*p;s.beginPath(),s.setLineDash([4,4]),s.strokeStyle="rgba(113,113,122,0.3)",s.lineWidth=1,s.moveTo(a.left,v),s.lineTo(a.left+c,v),s.stroke(),s.setLineDash([]),s.fillStyle="rgba(113,113,122,0.5)",s.font=Ke,s.textAlign="left",s.fillText(or($.ms),a.left+c+2,v+3);}for(let $=0;$<r.length;$++){let v=r[$],g=r.length===1?a.left+c/2:a.left+(v.timestamp-m)/S*c,x=a.top+p-v.durationMs/h*p,w=vi(v);t.push({x:g,y:x,idx:$,r:v}),v.statusCode>=400?Ei(s,g,x,4,w,2):bi(s,g,x,4,w);}s.fillStyle=Ve,s.font=Ke,s.textAlign="center";let P=[m,m+S/2,f];for(let $=0;$<P.length;$++){let v=a.left+$/2*c,g=new Date(P[$]);s.fillText(g.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),v,a.top+p+14);}return t}var Ti={max:1/0,label:"Pending",color:"var(--text-muted)",bg:"var(--bg-muted)",border:"var(--border)"};function lr(o,r,t){return t>=20?o:r}function ss(o,r){if(!r||r<=0)return Ti;let t=o/r;return t<.7?xt[0]:t<1.2?xt[1]:t<2?xt[2]:t<3?xt[3]:xt[4]}var V=class extends E{constructor(){super(...arguments);this.selectedEndpoint=rt;this.graphData=[];this.loadError=false;this.queryBreakdown=[];this.queryBreakdownLoading=false;this.scatterDots=[];}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate()),this.loadMetrics();}async loadMetrics(){try{let e=await(await fetch(T.metricsLive)).json();this.graphData=e.endpoints||[],this.loadError=!1,(!this.selectedEndpoint||this.selectedEndpoint===rt)&&(this.selectedEndpoint=rt);}catch{this.loadError=true;}}healthGradeForEndpoint(t){let e=lr(t.summary.p95Ms,t.summary.medianMs,t.summary.totalRequests);return ss(e,t.baselineP95Ms)}healthGradeForDuration(t,e){return ss(t,e)}getCallers(t){let e=this.store.state.flows,s=new Map;for(let i of e)for(let n of i.requests)if(`${n.method} ${n.path}`===t||this.normalizeEndpoint(n)===t){let c=s.get(i.label);c?(c.count++,c.totalMs+=n.durationMs):s.set(i.label,{count:1,totalMs:n.durationMs});}return [...s.entries()].map(([i,n])=>({label:i,count:n.count,avgMs:Math.round(n.totalMs/n.count)})).sort((i,n)=>n.count-i.count)}normalizeEndpoint(t){let s=t.path.split("?")[0].split("/").map(i=>{if(!i)return i;let n=i.length>0;for(let a=0;a<i.length;a++){let c=i.charCodeAt(a);if(c<48||c>57){n=false;break}}return n||i.length===36&&i[8]==="-"&&i[13]==="-"&&i[18]==="-"&&i[23]==="-"?":id":i}).join("/");return `${t.method} ${s}`}async loadQueryBreakdown(t){if(this.queryBreakdownLoading)return;let s=this.store.state.requests.filter(i=>`${i.method} ${i.path}`===t||this.normalizeEndpoint(i)===t).slice(-20).map(i=>i.id).filter(Boolean);if(s.length===0){this.queryBreakdown=[];return}this.queryBreakdownLoading=true;try{let i=await fetch(`${T.activity}?requestIds=${s.join(",")}`);if(!i.ok){this.queryBreakdownLoading=!1;return}let n=await i.json(),a=new Map;for(let c of Object.values(n.activities))for(let p of c.timeline){if(p.type!=="query")continue;let h=p.data,m=(h.normalizedOp||h.operation||"QUERY").toUpperCase(),f=h.table||h.model||"",S=`${m} ${f}`.trim(),R=a.get(S);R?(R.totalMs+=h.durationMs,R.count++):a.set(S,{label:S,totalMs:h.durationMs,count:1});}this.queryBreakdown=[...a.values()].map(c=>({...c,avgMs:Math.round(c.totalMs/c.count)})).sort((c,p)=>p.totalMs-c.totalMs);}catch{}this.queryBreakdownLoading=false;}renderScatterChart(t,e){this.scatterDots=ar(t,e),t.style.cursor="pointer",t.onclick=s=>{let i=t.getBoundingClientRect(),n=s.clientX-i.left,a=s.clientY-i.top,c=null,p=1/0;for(let h of this.scatterDots){let m=Math.sqrt((h.x-n)**2+(h.y-a)**2);m<p&&(p=m,c=h);}c&&p<16&&this.highlightRow(c.idx);};}highlightRow(t){let e=this.querySelector(".perf-hist-row-hl");e&&e.classList.remove("perf-hist-row-hl");let s=this.querySelector(`[data-req-idx="${t}"]`);s&&(s.classList.add("perf-hist-row-hl"),s.scrollIntoView({behavior:"smooth",block:"center"}));}updated(){if(this.selectedEndpoint===rt)return;let t=this.querySelector("#perf-detail-canvas");if(t){let e=this.graphData.find(s=>s.endpoint===this.selectedEndpoint);e&&this.renderScatterChart(t,e.requests);}}render(){return !this.graphData||this.graphData.length===0?l`<bk-empty-state title="No performance data yet" subtitle="Hit some endpoints and data will appear here"></bk-empty-state>`:l`
533
495
  <div id="graph-content">
534
496
  ${this.renderSelector()}
535
- ${this.selectedEndpoint===J?this.renderOverview():this.renderDetail()}
497
+ ${this.selectedEndpoint===rt?this.renderOverview():this.renderDetail()}
536
498
  </div>
537
- `}renderSelector(){return a`
499
+ `}renderSelector(){return l`
538
500
  <div class="perf-selector">
539
- <button class="perf-selector-btn ${this.selectedEndpoint===J?"active":""}"
540
- @click=${()=>{this.selectedEndpoint=J;}}>Overview</button>
541
- ${this.graphData.map((t,e)=>a`
501
+ <button class="perf-selector-btn ${this.selectedEndpoint===rt?"active":""}"
502
+ @click=${()=>{this.selectedEndpoint=rt;}}>Overview</button>
503
+ ${this.graphData.map((t,e)=>l`
542
504
  <button class="perf-selector-btn ${t.endpoint===this.selectedEndpoint?"active":""}"
543
505
  @click=${()=>{this.selectedEndpoint=t.endpoint,this.queryBreakdown=[],this.loadQueryBreakdown(t.endpoint);}}>
544
- <span class="perf-dot" style="background:${qe[e%qe.length]}"></span>${t.endpoint}
506
+ <span class="perf-dot" style="background:${Xe[e%Xe.length]}"></span>${t.endpoint}
545
507
  </button>
546
508
  `)}
547
509
  </div>
548
- `}renderOverview(){let t=this.graphData.filter(c=>c.requests.length>0);if(t.length===0)return p;let e=t.reduce((c,d)=>c+d.summary.totalRequests,0),r=e>0?Math.round(t.reduce((c,d)=>c+d.summary.p95Ms*d.summary.totalRequests,0)/e):0,i=t.reduce((c,d)=>c+Math.round(d.summary.errorRate*d.summary.totalRequests),0),n=e>0?i/e:0,l=t[0];return a`
510
+ `}renderOverview(){let t=this.graphData.filter(c=>c.requests.length>0);if(t.length===0)return d;let e=t.reduce((c,p)=>c+p.summary.totalRequests,0),s=e>0?Math.round(t.reduce((c,p)=>c+p.summary.p95Ms*p.summary.totalRequests,0)/e):0,i=t.reduce((c,p)=>c+Math.round(p.summary.errorRate*p.summary.totalRequests),0),n=e>0?i/e:0,a=t[0];return l`
549
511
  <div class="perf-overview">
550
512
  <div class="perf-summary-row">
551
513
  <div class="perf-summary-card">
@@ -554,7 +516,7 @@
554
516
  </div>
555
517
  <div class="perf-summary-card">
556
518
  <span class="perf-summary-label">Avg P95</span>
557
- <span class="perf-summary-value" style="color:${this.healthGradeForDuration(r).color}">${_(r)}</span>
519
+ <span class="perf-summary-value" style="color:${this.healthGradeForDuration(s).color}">${y(s)}</span>
558
520
  </div>
559
521
  <div class="perf-summary-card">
560
522
  <span class="perf-summary-label">Error Rate</span>
@@ -562,7 +524,7 @@
562
524
  </div>
563
525
  <div class="perf-summary-card">
564
526
  <span class="perf-summary-label">Slowest</span>
565
- <span class="perf-summary-value perf-summary-value-sm">${l?.endpoint??"-"}</span>
527
+ <span class="perf-summary-value perf-summary-value-sm">${a?.endpoint??"-"}</span>
566
528
  </div>
567
529
  </div>
568
530
 
@@ -582,50 +544,50 @@
582
544
  </tbody>
583
545
  </table>
584
546
  </div>
585
- `}renderHeatmapRow(t){let e=t.summary,r=this.healthGradeForEndpoint(t),i=Math.round(e.errorRate*e.totalRequests),n=(e.avgQueryTimeMs||0)+(e.avgFetchTimeMs||0)+(e.avgAppTimeMs||0),l=0,c=0,d=100;return n>0&&(l=Math.round((e.avgQueryTimeMs||0)/n*100),c=Math.round((e.avgFetchTimeMs||0)/n*100),d=Math.max(0,100-l-c)),a`
547
+ `}renderHeatmapRow(t){let e=t.summary,s=this.healthGradeForEndpoint(t),i=Math.round(e.errorRate*e.totalRequests),n=(e.avgQueryTimeMs||0)+(e.avgFetchTimeMs||0)+(e.avgAppTimeMs||0),a=0,c=0,p=100;return n>0&&(a=Math.round((e.avgQueryTimeMs||0)/n*100),c=Math.round((e.avgFetchTimeMs||0)/n*100),p=Math.max(0,100-a-c)),l`
586
548
  <tr class="perf-table-row" @click=${()=>{this.selectedEndpoint=t.endpoint,this.queryBreakdown=[],this.loadQueryBreakdown(t.endpoint);}}>
587
549
  <td class="perf-td-name">${t.endpoint}</td>
588
550
  <td class="perf-td-right">${e.totalRequests}</td>
589
551
  <td class="perf-td-center">
590
- <span class="perf-hm-p95" style="color:${r.color};background:${r.bg};border-color:${r.border}">${_(e.p95Ms)}</span>
552
+ <span class="perf-hm-p95" style="color:${s.color};background:${s.bg};border-color:${s.border}">${y(e.p95Ms)}</span>
591
553
  </td>
592
554
  <td class="perf-td-center" style="color:${i>0?"var(--red)":"var(--text-muted)"}">${i>0?i:"-"}</td>
593
555
  <td class="perf-td-center" style="color:${e.avgQueryCount>5?"var(--amber)":"var(--text-muted)"}">${e.avgQueryCount}</td>
594
556
  <td>
595
557
  <span class="perf-hm-split-bar">
596
- ${l>0?a`<span class="perf-breakdown-seg perf-breakdown-db" style="width:${l}%"></span>`:p}
597
- ${c>0?a`<span class="perf-breakdown-seg perf-breakdown-fetch" style="width:${c}%"></span>`:p}
598
- ${d>0?a`<span class="perf-breakdown-seg perf-breakdown-app" style="width:${d}%"></span>`:p}
558
+ ${a>0?l`<span class="perf-breakdown-seg perf-breakdown-db" style="width:${a}%"></span>`:d}
559
+ ${c>0?l`<span class="perf-breakdown-seg perf-breakdown-fetch" style="width:${c}%"></span>`:d}
560
+ ${p>0?l`<span class="perf-breakdown-seg perf-breakdown-app" style="width:${p}%"></span>`:d}
599
561
  </span>
600
562
  </td>
601
563
  </tr>
602
- `}renderDetail(){let t=this.graphData.find(n=>n.endpoint===this.selectedEndpoint);if(!t?.requests?.length)return a`<bk-empty-state subtitle="No data for this endpoint"></bk-empty-state>`;let e=t.summary,r=this.healthGradeForEndpoint(t),i=Math.round(e.errorRate*e.totalRequests);return a`
603
- ${this.renderDetailHeader(t,r)}
604
- ${this.renderDetailMetrics(e,r,i)}
564
+ `}renderDetail(){let t=this.graphData.find(n=>n.endpoint===this.selectedEndpoint);if(!t?.requests?.length)return l`<bk-empty-state subtitle="No data for this endpoint"></bk-empty-state>`;let e=t.summary,s=this.healthGradeForEndpoint(t),i=Math.round(e.errorRate*e.totalRequests);return l`
565
+ ${this.renderDetailHeader(t,s)}
566
+ ${this.renderDetailMetrics(e,s,i)}
605
567
  ${this.renderDetailBreakdown(e)}
606
568
  ${this.renderCallers(t.endpoint)}
607
569
  ${this.renderQueryBreakdown()}
608
570
  ${this.renderTrends(t)}
609
571
  ${this.renderDetailChart()}
610
572
  ${this.renderDetailHistory(t)}
611
- `}renderDetailHeader(t,e){return a`
573
+ `}renderDetailHeader(t,e){return l`
612
574
  <div class="perf-detail-header">
613
575
  <div class="perf-detail-title">
614
576
  <span class="perf-badge perf-badge-lg" style="color:${e.color};background:${e.bg};border-color:${e.border}">${e.label}</span>
615
577
  <span>${t.endpoint}</span>
616
- ${t.baselineP95Ms?a`<span class="perf-baseline-hint">Baseline: ${_(t.baselineP95Ms)}</span>`:p}
578
+ ${t.baselineP95Ms?l`<span class="perf-baseline-hint">Baseline: ${y(t.baselineP95Ms)}</span>`:d}
617
579
  </div>
618
580
  </div>
619
- `}renderDetailMetrics(t,e,r){return a`
581
+ `}renderDetailMetrics(t,e,s){return l`
620
582
  <div class="perf-metric-row">
621
583
  <div class="perf-metric-card">
622
584
  <span class="perf-metric-label">P95</span>
623
- <span class="perf-metric-value" style="color:${e.color}">${_(t.p95Ms)}</span>
585
+ <span class="perf-metric-value" style="color:${e.color}">${y(t.p95Ms)}</span>
624
586
  </div>
625
587
  <div class="perf-metric-card">
626
588
  <span class="perf-metric-label">Errors</span>
627
- <span class="perf-metric-value" style="color:${r>0?"var(--red)":"var(--green)"}">
628
- ${r>0?r+" ("+Math.round(t.errorRate*100)+"%)":"0"}
589
+ <span class="perf-metric-value" style="color:${s>0?"var(--red)":"var(--green)"}">
590
+ ${s>0?s+" ("+Math.round(t.errorRate*100)+"%)":"0"}
629
591
  </span>
630
592
  </div>
631
593
  <div class="perf-metric-card">
@@ -633,71 +595,71 @@
633
595
  <span class="perf-metric-value" style="color:${t.avgQueryCount>5?"var(--amber)":"var(--text)"}">${t.avgQueryCount}</span>
634
596
  </div>
635
597
  </div>
636
- `}renderDetailBreakdown(t){let e=(t.avgQueryTimeMs||0)+(t.avgFetchTimeMs||0)+(t.avgAppTimeMs||0);if(e<=0)return p;let r=Math.round((t.avgQueryTimeMs||0)/e*100),i=Math.round((t.avgFetchTimeMs||0)/e*100),n=Math.max(0,100-r-i);return a`
598
+ `}renderDetailBreakdown(t){let e=(t.avgQueryTimeMs||0)+(t.avgFetchTimeMs||0)+(t.avgAppTimeMs||0);if(e<=0)return d;let s=Math.round((t.avgQueryTimeMs||0)/e*100),i=Math.round((t.avgFetchTimeMs||0)/e*100),n=Math.max(0,100-s-i);return l`
637
599
  <div class="perf-breakdown">
638
600
  <div class="perf-section-title">Time Breakdown</div>
639
601
  <div class="perf-breakdown-bar">
640
- ${r>0?a`<div class="perf-breakdown-seg perf-breakdown-db" style="width:${r}%"></div>`:p}
641
- ${i>0?a`<div class="perf-breakdown-seg perf-breakdown-fetch" style="width:${i}%"></div>`:p}
642
- ${n>0?a`<div class="perf-breakdown-seg perf-breakdown-app" style="width:${n}%"></div>`:p}
602
+ ${s>0?l`<div class="perf-breakdown-seg perf-breakdown-db" style="width:${s}%"></div>`:d}
603
+ ${i>0?l`<div class="perf-breakdown-seg perf-breakdown-fetch" style="width:${i}%"></div>`:d}
604
+ ${n>0?l`<div class="perf-breakdown-seg perf-breakdown-app" style="width:${n}%"></div>`:d}
643
605
  </div>
644
606
  <div class="perf-breakdown-legend">
645
- <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-db"></span>DB ${_(t.avgQueryTimeMs||0)} (${r}%)</span>
646
- <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-fetch"></span>Fetch ${_(t.avgFetchTimeMs||0)} (${i}%)</span>
647
- <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-app"></span>App ${_(t.avgAppTimeMs||0)} (${n}%)</span>
607
+ <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-db"></span>DB ${y(t.avgQueryTimeMs||0)} (${s}%)</span>
608
+ <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-fetch"></span>Fetch ${y(t.avgFetchTimeMs||0)} (${i}%)</span>
609
+ <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-app"></span>App ${y(t.avgAppTimeMs||0)} (${n}%)</span>
648
610
  </div>
649
611
  </div>
650
- `}renderCallers(t){let e=this.getCallers(t);return e.length===0?p:a`
612
+ `}renderCallers(t){let e=this.getCallers(t);return e.length===0?d:l`
651
613
  <div class="perf-callers">
652
614
  <div class="perf-section-title">Called By</div>
653
615
  <div class="perf-callers-list">
654
- ${e.map(r=>a`
616
+ ${e.map(s=>l`
655
617
  <div class="perf-caller-row">
656
- <span class="perf-caller-name">${r.label}</span>
657
- <span class="perf-caller-count">${r.count} call${r.count!==1?"s":""}</span>
658
- <span class="perf-caller-avg">avg ${_(r.avgMs)}</span>
618
+ <span class="perf-caller-name">${s.label}</span>
619
+ <span class="perf-caller-count">${s.count} call${s.count!==1?"s":""}</span>
620
+ <span class="perf-caller-avg">avg ${y(s.avgMs)}</span>
659
621
  </div>
660
622
  `)}
661
623
  </div>
662
624
  </div>
663
- `}renderQueryBreakdown(){return this.queryBreakdownLoading?a`<div class="perf-queries"><div class="perf-section-title">DB Queries</div><div class="perf-queries-loading">Loading...</div></div>`:this.queryBreakdown.length===0?p:a`
625
+ `}renderQueryBreakdown(){return this.queryBreakdownLoading?l`<div class="perf-queries"><div class="perf-section-title">DB Queries</div><div class="perf-queries-loading">Loading...</div></div>`:this.queryBreakdown.length===0?d:l`
664
626
  <div class="perf-queries">
665
627
  <div class="perf-section-title">DB Queries</div>
666
628
  <div class="perf-queries-list">
667
- ${this.queryBreakdown.map(t=>a`
629
+ ${this.queryBreakdown.map(t=>l`
668
630
  <div class="perf-query-row">
669
631
  <span class="perf-query-label">${t.label}</span>
670
- <span class="perf-query-avg">avg ${_(t.avgMs)}</span>
632
+ <span class="perf-query-avg">avg ${y(t.avgMs)}</span>
671
633
  <span class="perf-query-count">${t.count} call${t.count!==1?"s":""}</span>
672
634
  </div>
673
635
  `)}
674
636
  </div>
675
637
  </div>
676
- `}renderTrends(t){let e=t.sessions;if(!e||e.length===0)return p;let r=e.slice(-10);return a`
638
+ `}renderTrends(t){let e=t.sessions;if(!e||e.length===0)return d;let s=e.slice(-10);return l`
677
639
  <div class="perf-trends">
678
640
  <div class="perf-section-title">Session Trend</div>
679
641
  <div class="perf-trends-list">
680
- ${r.map((i,n)=>{let l=n>0?r[n-1].p95DurationMs:null,c=l!==null?i.p95DurationMs>l*1.2?"slower":i.p95DurationMs<l*.8?"faster":"":"",d=this.formatTimeAgo(i.startedAt),h=n===r.length-1,m=this.healthGradeForDuration(i.p95DurationMs,t.baselineP95Ms);return a`
642
+ ${s.map((i,n)=>{let a=n>0?s[n-1].p95DurationMs:null,c=a!==null?i.p95DurationMs>a*1.2?"slower":i.p95DurationMs<a*.8?"faster":"":"",p=this.formatTimeAgo(i.startedAt),h=n===s.length-1,m=this.healthGradeForDuration(i.p95DurationMs,t.baselineP95Ms);return l`
681
643
  <div class="perf-trend-row ${h?"perf-trend-current":""}">
682
- <span class="perf-trend-time">${h?"Current":d}</span>
644
+ <span class="perf-trend-time">${h?"Current":p}</span>
683
645
  <span class="perf-trend-p95">
684
646
  <span class="perf-hm-p95" style="color:${m.color};background:${m.bg};border-color:${m.border}">
685
- p95: ${_(i.p95DurationMs)}
647
+ p95: ${y(i.p95DurationMs)}
686
648
  </span>
687
649
  </span>
688
650
  <span class="perf-trend-reqs">${i.requestCount} req${i.requestCount!==1?"s":""}</span>
689
651
  <span class="perf-trend-errs" style="color:${i.errorCount>0?"var(--red)":"var(--text-dim)"}">${i.errorCount} err${i.errorCount!==1?"s":""}</span>
690
- ${c?a`<span class="perf-trend-arrow ${c==="slower"?"perf-trend-slower":"perf-trend-faster"}">${c==="slower"?"\u2191 slower":"\u2193 faster"}</span>`:p}
652
+ ${c?l`<span class="perf-trend-arrow ${c==="slower"?"perf-trend-slower":"perf-trend-faster"}">${c==="slower"?"\u2191 slower":"\u2193 faster"}</span>`:d}
691
653
  </div>
692
654
  `})}
693
655
  </div>
694
656
  </div>
695
- `}formatTimeAgo(t){let e=Date.now()-t,r=Math.round(e/6e4);if(r<1)return "just now";if(r<60)return `${r}m ago`;let i=Math.round(r/60);return i<24?`${i}h ago`:`${Math.round(i/24)}d ago`}renderDetailChart(){return a`
657
+ `}formatTimeAgo(t){let e=Date.now()-t,s=Math.round(e/6e4);if(s<1)return "just now";if(s<60)return `${s}m ago`;let i=Math.round(s/60);return i<24?`${i}h ago`:`${Math.round(i/24)}d ago`}renderDetailChart(){return l`
696
658
  <div class="perf-chart-wrap">
697
659
  <div class="perf-section-title">Response Time</div>
698
660
  <canvas id="perf-detail-canvas" class="perf-canvas" style="width:100%;height:240px"></canvas>
699
661
  </div>
700
- `}renderDetailHistory(t){if(t.requests.length===0)return p;let e=[];for(let r=t.requests.length-1;r>=0&&e.length<50;r--)e.push({point:t.requests[r],originalIndex:r});return a`
662
+ `}renderDetailHistory(t){if(t.requests.length===0)return d;let e=[];for(let s=t.requests.length-1;s>=0&&e.length<50;s--)e.push({point:t.requests[s],originalIndex:s});return l`
701
663
  <div class="perf-history-wrap">
702
664
  <table class="perf-table">
703
665
  <thead>
@@ -711,39 +673,39 @@
711
673
  </tr>
712
674
  </thead>
713
675
  <tbody>
714
- ${e.map(r=>this.renderHistoryRow(r.point,r.originalIndex,t.baselineP95Ms))}
676
+ ${e.map(s=>this.renderHistoryRow(s.point,s.originalIndex,t.baselineP95Ms))}
715
677
  </tbody>
716
678
  </table>
717
679
  </div>
718
- `}renderHistoryRow(t,e,r){let i=this.healthGradeForDuration(t.durationMs,r),n=new Date(t.timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),l=t.statusCode>=400,c=t.queryTimeMs||0,d=t.fetchTimeMs||0,h=Math.max(0,t.durationMs-c-d);return a`
719
- <tr class="perf-table-row ${l?"perf-row-err":""}" data-req-idx=${e}>
680
+ `}renderHistoryRow(t,e,s){let i=this.healthGradeForDuration(t.durationMs,s),n=new Date(t.timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),a=t.statusCode>=400,c=t.queryTimeMs||0,p=t.fetchTimeMs||0,h=Math.max(0,t.durationMs-c-p);return l`
681
+ <tr class="perf-table-row ${a?"perf-row-err":""}" data-req-idx=${e}>
720
682
  <td class="perf-td-muted">${n}</td>
721
683
  <td>
722
684
  <span class="perf-badge perf-badge-sm" style="color:${i.color};background:${i.bg};border-color:${i.border}">${i.label}</span>
723
685
  </td>
724
- <td>${_(t.durationMs)}</td>
686
+ <td>${y(t.durationMs)}</td>
725
687
  <td>
726
- ${c>0?a`<span class="perf-bd-tag perf-bd-tag-db">DB ${_(c)}</span>`:p}
727
- ${d>0?a`<span class="perf-bd-tag perf-bd-tag-fetch">Fetch ${_(d)}</span>`:p}
728
- <span class="perf-bd-tag perf-bd-tag-app">App ${_(h)}</span>
688
+ ${c>0?l`<span class="perf-bd-tag perf-bd-tag-db">DB ${y(c)}</span>`:d}
689
+ ${p>0?l`<span class="perf-bd-tag perf-bd-tag-fetch">Fetch ${y(p)}</span>`:d}
690
+ <span class="perf-bd-tag perf-bd-tag-app">App ${y(h)}</span>
729
691
  </td>
730
- <td class="perf-td-center" style="color:${l?"var(--red)":"var(--text-muted)"}">${t.statusCode}</td>
692
+ <td class="perf-td-center" style="color:${a?"var(--red)":"var(--text-muted)"}">${t.statusCode}</td>
731
693
  <td class="perf-td-right perf-td-muted">${t.queryCount}</td>
732
694
  </tr>
733
- `}};u([I({context:A})],Q.prototype,"store",2),u([b()],Q.prototype,"selectedEndpoint",2),u([b()],Q.prototype,"graphData",2),u([b()],Q.prototype,"loadError",2),u([b()],Q.prototype,"queryBreakdown",2),u([b()],Q.prototype,"queryBreakdownLoading",2),Q=u([S("bk-performance-view")],Q);var Xe={auth:{label:"Auth",color:"#059669",icon:"\u{1F6E1}",tooltip:"Highlight which endpoints require authentication and which are unprotected"},security:{label:"Security",color:"#dc2626",icon:"\u26A0",tooltip:"Show security findings like exposed secrets, token leaks, and PII exposure"},performance:{label:"Perf",color:"#2563eb",icon:"\u26A1",tooltip:"Color endpoints by P95 latency \u2014 green (fast) to red (slow)"},issues:{label:"Issues",color:"#d97706",icon:"\u25CF",tooltip:"Badge endpoints with open issues like N+1 queries or redundant calls"},heat:{label:"Heat",color:"#ef4444",icon:"\u{1F525}",tooltip:"Color nodes and edges by traffic volume \u2014 blue (low) to red (hot)"}},At={action:{fill:"#faf5ff",stroke:"#a855f7",icon:"\u25B6",columnHeader:"ACTIONS"},endpoint:{fill:"#f8fafc",stroke:"#6366f1",icon:"\u26A1",columnHeader:"ENDPOINTS"},table:{fill:"#f0fdf4",stroke:"#16a34a",icon:"\u229E",columnHeader:"TABLES"},external:{fill:"#fffbeb",stroke:"#d97706",icon:"\u25C6",columnHeader:"EXTERNAL"}},fe={triggers:"#a855f7",reads:"#6366f1",writes:"#ef4444",fetches:"#f59e0b",calls:"#22c55e"},yi=100,_i=300,$i=800;function It(o){return o<yi?"#22c55e":o<_i?"#3b82f6":o<$i?"#eab308":"#ef4444"}var xi=.25,Si=.5,Ti=.75;function Ve(o){return o<xi?"#3b82f6":o<Si?"#22c55e":o<Ti?"#eab308":"#ef4444"}var zs="#4338ca",Js="#e0e7ff",Zs="#818cf8",tr="#eef2ff",Ke="#7c3aed",er="#6366f1",ve="#f97316",sr="#ecfdf5",ze="#059669",rr="#fef2f2",Je="#dc2626",ir="#fffbeb",Ze="#d97706",ct="#ef4444",or=.2,nr=3,ts=1.2,Kt=40;var ar=800,lr=500;function Ci(o){return Math.max(140,o.length*7.2+36)}function es(o,s){return Math.round(36+o.stats.requestCount/s*28)}function Li(o){return o.length>0?Math.max(140,...o.map(s=>Ci(s.label))):0}function dr(o,s,t){let e=[];for(let r of s){let i=r.source===o?r.target:r.target===o?r.source:null;if(i){let n=t.get(i);n&&e.push(n.y+n.h/2);}}return e.length>0?e.reduce((r,i)=>r+i,0)/e.length:1/0}function hr(o,s){let t=f=>o.filter(g=>g.type===f).sort((g,T)=>T.stats.requestCount-g.stats.requestCount),e=t("action"),r=t("endpoint"),i=t("table"),n=t("external"),l=Math.max(1,...o.map(f=>f.stats.requestCount)),c=new Map,d=[],h=[],m=50,v=[{type:"action",items:e},{type:"endpoint",items:r},{type:"table",items:i},{type:"external",items:n}];for(let f of v)if(f.items.length>0){let g=Li(f.items);h.push({type:f.type,items:f.items,width:g,x:m}),m+=g+160;}let x=h[0];if(x){let f=74;for(let g of x.items){let T=es(g,l),R={id:g.id,x:x.x,y:f,w:x.width,h:T,label:g.label,type:g.type,stats:g.stats,annotations:g.annotations};d.push(R),c.set(g.id,R),f+=T+10;}}for(let f=1;f<h.length;f++){let g=h[f],T=[...g.items].sort((C,q)=>dr(C.id,s,c)-dr(q.id,s,c)),R=d.filter(C=>C.x===h[f-1].x),H=Math.min(...R.map(C=>C.y)),B=Math.max(...R.map(C=>C.y+C.h))-H,V=T.reduce((C,q)=>C+es(q,l)+10,-10),G=H+Math.max(0,(B-V)/2);for(let C of T){let q=es(C,l),rs={id:C.id,x:g.x,y:G,w:g.width,h:q,label:C.label,type:C.type,stats:C.stats,annotations:C.annotations};d.push(rs),c.set(C.id,rs),G+=q+10;}}let y=[];for(let f of s){let g=c.get(f.source),T=c.get(f.target);if(!g||!T)continue;let R=g.x<T.x,H=R?g.x+g.w:g.x,X=g.y+g.h/2,B=R?T.x:T.x+T.w,V=T.y+T.h/2,G=[];f.stats.frequency>1&&G.push(`${f.stats.frequency}\xD7`),G.push(f.type),f.stats.avgLatencyMs>0&&G.push(`${f.stats.avgLatencyMs}ms`),y.push({key:f.id,sx:H,sy:X,tx:B,ty:V,label:G.join(" \xB7 "),color:fe[f.type]||"#94a3b8",thickness:Math.min(.75+Math.log2(f.stats.frequency+1)*.35,2.5),dashed:f.type==="reads"||f.type==="writes",data:f});}let k=d.reduce((f,g)=>Math.max(f,g.x+g.w),0),$=d.reduce((f,g)=>Math.max(f,g.y+g.h),0);return {nodes:d,edges:y,width:k+100,height:Math.max($+50,250)}}function ur(o){let s=o.charCodeAt(0);return s>=48&&s<=57||s>=65&&s<=70||s>=97&&s<=102}function Mi(o){if(o.length!==36)return false;for(let s=0;s<o.length;s++)if(s===8||s===13||s===18||s===23){if(o[s]!=="-")return false}else if(!ur(o[s]))return false;return true}function Ni(o){if(!o.length)return false;for(let s=0;s<o.length;s++){let t=o.charCodeAt(s);if(t<48||t>57)return false}return true}function Oi(o){if(o.length<12)return false;for(let s=0;s<o.length;s++)if(!ur(o[s]))return false;return true}function ki(o){if(o.length<8)return false;let s=false,t=false;for(let e=0;e<o.length;e++){let r=o.charCodeAt(e);if(r>=65&&r<=90||r>=97&&r<=122)s=true;else if(r>=48&&r<=57)t=true;else if(r!==95&&r!==45)return false}return s&&t}var Di=":id";function Hi(o){return Mi(o)||Ni(o)||Oi(o)||ki(o)?Di:o}function ss(o,s){let t=s.split("?")[0];return `${o} ${t.split("/").map(e=>e&&Hi(e)).join("/")}`}function mr(o,s,t){let e=[...o],r=[...s],i=new Set(e.map(l=>l.id)),n=new Map;for(let l of t){let c=l.label||"Unknown",d=n.get(c);d||(d={endpointKeys:new Set,count:0,totalMs:0},n.set(c,d)),d.count++,d.totalMs+=l.totalDurationMs;for(let h of l.requests)h.path?.startsWith(F)||d.endpointKeys.add(ss(h.method,h.path));}for(let[l,c]of n){let d=`action:${l}`;i.has(d)||(e.push({id:d,type:"action",label:l,stats:{requestCount:c.count,avgLatencyMs:c.count>0?Math.round(c.totalMs/c.count):0,errorRate:0,avgQueryCount:0}}),i.add(d));for(let h of c.endpointKeys){let m=`endpoint:${h}`;if(i.has(m)){let v=`${d} -> ${m}`;r.find(x=>x.id===v)||r.push({id:v,source:d,target:m,type:"triggers",stats:{frequency:c.count,avgLatencyMs:0}});}}}return {nodes:e,edges:r}}function fr(o){let s=new Map;for(let t of o){let e=t.label||"Unknown",r=s.get(e);r||(r={keys:new Set,count:0,totalMs:0},s.set(e,r)),r.count++,r.totalMs+=t.totalDurationMs;for(let i of t.requests)i.path?.startsWith(F)||r.keys.add(ss(i.method,i.path));}return [...s.entries()].map(([t,e])=>({label:t,occurrences:e.count,endpointKeys:e.keys,avgDurationMs:e.count>0?Math.round(e.totalMs/e.count):0}))}function be(o,s){let t=`event=${encodeURIComponent(o)}${s?`&detail=${encodeURIComponent(s)}`:""}`;fetch(`${w.tab}?${t}`).catch(()=>{});}var M=class extends E{constructor(){super(...arguments);this.graphNodes=[];this.graphEdges=[];this.locked=null;this.hovered=null;this.loading=true;this.activeLayers=new Set;this.searchQuery="";this.viewTransform={x:0,y:0,scale:1};this.isPanning=false;this.panStart={x:0,y:0,vtx:0,vty:0};this.dragging=null;this.wasDragging=false;this.nodePositionOverrides=new Map;this.detailTab="overview";this.consolidatedFlows=[];this.activeFlowIdx=-1;this.focusIdx=-1;this.refreshTimer=null;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.loadData(),this.refreshTimer=setInterval(()=>this.loadData(),4e3);}disconnectedCallback(){super.disconnectedCallback(),this.refreshTimer&&clearInterval(this.refreshTimer);}async loadData(){try{let[t,e]=await Promise.all([fetch(`${w.graph}?level=endpoints`),fetch(w.flows)]),r=await t.json(),i=await e.json(),n=mr(r.nodes||[],r.edges||[],i.flows||[]);this.graphNodes=n.nodes,this.graphEdges=n.edges,this.consolidatedFlows=fr(i.flows||[]),this.nodePositionOverrides.size===0&&this.graphNodes.length>0&&this.tryLoadPersistedPositions(),this.loading=!1;}catch{this.loading=false;}}getPositionStorageKey(){let t=this.graphNodes.map(r=>r.id).sort().join(","),e=0;for(let r=0;r<t.length;r++)e=(e<<5)-e+t.charCodeAt(r)|0;return `bk-graph-pos-${e}`}persistPositions(){if(this.nodePositionOverrides.size!==0)try{let t=Object.fromEntries(this.nodePositionOverrides);localStorage.setItem(this.getPositionStorageKey(),JSON.stringify(t));}catch{}}tryLoadPersistedPositions(){try{let t=localStorage.getItem(this.getPositionStorageKey());if(t){let e=JSON.parse(t);this.nodePositionOverrides=new Map(Object.entries(e));}}catch{}}get activeNodeId(){return this.locked??this.hovered}getHighlightedNodeIds(){let t=this.activeNodeId;if(!t)return null;let e=new Set([t]),r=true;for(;r;){r=false;for(let i of this.graphEdges)e.has(i.source)&&!e.has(i.target)&&(e.add(i.target),r=true);}return e}getFlowTraceNodeIds(){if(this.activeFlowIdx<0||this.activeFlowIdx>=this.consolidatedFlows.length)return null;let t=this.consolidatedFlows[this.activeFlowIdx],e=new Set;e.add(`action:${t.label}`);for(let r of t.endpointKeys)e.add(`endpoint:${r}`);for(let r of this.graphEdges)e.has(r.source)&&e.add(r.target);return e}getFlowTraceEdgeIds(){let t=this.getFlowTraceNodeIds();if(!t)return null;let e=new Set;for(let r of this.graphEdges)t.has(r.source)&&t.has(r.target)&&e.add(r.id);return e}matchesSearch(t){return this.searchQuery?t.toLowerCase().includes(this.searchQuery.toLowerCase()):true}handlePanStart(t){t.button===0&&(t.target.closest(".graph-g")||(this.isPanning=true,this.panStart={x:t.clientX,y:t.clientY,vtx:this.viewTransform.x,vty:this.viewTransform.y}));}handlePanMove(t){if(this.dragging){let e=t.currentTarget.getBoundingClientRect(),r=(t.clientX-e.left-this.viewTransform.x)/this.viewTransform.scale,i=(t.clientY-e.top-this.viewTransform.y)/this.viewTransform.scale;this.nodePositionOverrides.set(this.dragging.nodeId,{x:r-this.dragging.offsetX,y:i-this.dragging.offsetY}),this.requestUpdate();return}this.isPanning&&(this.viewTransform={...this.viewTransform,x:this.panStart.vtx+(t.clientX-this.panStart.x),y:this.panStart.vty+(t.clientY-this.panStart.y)});}handlePanEnd(){this.dragging&&(this.persistPositions(),this.dragging=null,this.wasDragging=true,requestAnimationFrame(()=>{this.wasDragging=false;})),this.isPanning=false;}resetView(){this.viewTransform={x:0,y:0,scale:1};}zoomIn(){this.viewTransform={...this.viewTransform,scale:Math.min(nr,this.viewTransform.scale*ts)};}zoomOut(){this.viewTransform={...this.viewTransform,scale:Math.max(or,this.viewTransform.scale/ts)};}resetLayout(){this.nodePositionOverrides.clear();try{localStorage.removeItem(this.getPositionStorageKey());}catch{}this.viewTransform={x:0,y:0,scale:1},this.requestUpdate(),be("layout_reset");}startNodeDrag(t,e,r){t.stopPropagation();let i=t.currentTarget.closest("svg").getBoundingClientRect(),n=(t.clientX-i.left-this.viewTransform.x)/this.viewTransform.scale,l=(t.clientY-i.top-this.viewTransform.y)/this.viewTransform.scale;this.dragging={nodeId:e,offsetX:n-r.x,offsetY:l-r.y};}handleKeyDown(t){let e=this.graphNodes;if(t.key==="/"){t.preventDefault(),this.querySelector(".graph-search-input")?.focus();return}if(t.key==="Escape"){this.locked=null,this.searchQuery="",this.focusIdx=-1,this.activeFlowIdx=-1;return}if(t.key==="Tab"){t.preventDefault(),this.focusIdx=t.shiftKey?this.focusIdx<=0?e.length-1:this.focusIdx-1:(this.focusIdx+1)%e.length,this.hovered=e[this.focusIdx]?.id??null;return}if(t.key==="Enter"&&this.focusIdx>=0){let r=e[this.focusIdx];r&&(this.locked=this.locked===r.id?null:r.id);return}if(t.key==="+"||t.key==="="){this.zoomIn();return}if(t.key==="-"){this.zoomOut();return}if(t.key==="ArrowUp"){this.viewTransform={...this.viewTransform,y:this.viewTransform.y+Kt};return}if(t.key==="ArrowDown"){this.viewTransform={...this.viewTransform,y:this.viewTransform.y-Kt};return}if(t.key==="ArrowLeft"){this.viewTransform={...this.viewTransform,x:this.viewTransform.x+Kt};return}if(t.key==="ArrowRight"){this.viewTransform={...this.viewTransform,x:this.viewTransform.x-Kt};return}}render(){if(this.loading&&this.graphNodes.length===0)return a`<div class="graph-loading">Loading graph…</div>`;if(this.graphNodes.length===0)return a`
695
+ `}};u([C({context:A})],V.prototype,"store",2),u([b()],V.prototype,"selectedEndpoint",2),u([b()],V.prototype,"graphData",2),u([b()],V.prototype,"loadError",2),u([b()],V.prototype,"queryBreakdown",2),u([b()],V.prototype,"queryBreakdownLoading",2),V=u([_("bk-performance-view")],V);var rs={auth:{label:"Auth",color:"#059669",icon:"\u{1F6E1}",tooltip:"Highlight which endpoints require authentication and which are unprotected"},security:{label:"Security",color:"#dc2626",icon:"\u26A0",tooltip:"Show security findings like exposed secrets, token leaks, and PII exposure"},performance:{label:"Perf",color:"#2563eb",icon:"\u26A1",tooltip:"Color endpoints by P95 latency \u2014 green (fast) to red (slow)"},issues:{label:"Issues",color:"#d97706",icon:"\u25CF",tooltip:"Badge endpoints with open issues like N+1 queries or redundant calls"},heat:{label:"Heat",color:"#ef4444",icon:"\u{1F525}",tooltip:"Color nodes and edges by traffic volume \u2014 blue (low) to red (hot)"}},kt={action:{fill:"#faf5ff",stroke:"#a855f7",icon:"\u25B6",columnHeader:"ACTIONS"},endpoint:{fill:"#f8fafc",stroke:"#6366f1",icon:"\u26A1",columnHeader:"ENDPOINTS"},table:{fill:"#f0fdf4",stroke:"#16a34a",icon:"\u229E",columnHeader:"TABLES"},external:{fill:"#fffbeb",stroke:"#d97706",icon:"\u25C6",columnHeader:"EXTERNAL"}},xe={triggers:"#a855f7",reads:"#6366f1",writes:"#ef4444",fetches:"#f59e0b",calls:"#22c55e"},Ii=100,Li=300,Mi=800;function Ot(o){return o<Ii?"#22c55e":o<Li?"#3b82f6":o<Mi?"#eab308":"#ef4444"}var ki=.25,Oi=.5,Ni=.75;function is(o){return o<ki?"#3b82f6":o<Oi?"#22c55e":o<Ni?"#eab308":"#ef4444"}var cr="#4338ca",dr="#e0e7ff",pr="#818cf8",hr="#eef2ff",os="#7c3aed",ur="#6366f1",Se="#f97316",mr="#ecfdf5",ns="#059669",fr="#fef2f2",as="#dc2626",vr="#fffbeb",ls="#d97706",ut="#ef4444",gr=.2,br=3,cs=1.2,re=40;var Er=800,yr=500;function Ui(o){return Math.max(140,o.length*7.2+36)}function ds(o,r){return Math.round(36+o.stats.requestCount/r*28)}function Fi(o){return o.length>0?Math.max(140,...o.map(r=>Ui(r.label))):0}function _r(o,r,t){let e=[];for(let s of r){let i=s.source===o?s.target:s.target===o?s.source:null;if(i){let n=t.get(i);n&&e.push(n.y+n.h/2);}}return e.length>0?e.reduce((s,i)=>s+i,0)/e.length:1/0}function Sr(o,r){let t=v=>o.filter(g=>g.type===v).sort((g,x)=>x.stats.requestCount-g.stats.requestCount),e=t("action"),s=t("endpoint"),i=t("table"),n=t("external"),a=Math.max(1,...o.map(v=>v.stats.requestCount)),c=new Map,p=[],h=[],m=50,f=[{type:"action",items:e},{type:"endpoint",items:s},{type:"table",items:i},{type:"external",items:n}];for(let v of f)if(v.items.length>0){let g=Fi(v.items);h.push({type:v.type,items:v.items,width:g,x:m}),m+=g+160;}let S=h[0];if(S){let v=74;for(let g of S.items){let x=ds(g,a),w={id:g.id,x:S.x,y:v,w:S.width,h:x,label:g.label,type:g.type,stats:g.stats,annotations:g.annotations};p.push(w),c.set(g.id,w),v+=x+10;}}for(let v=1;v<h.length;v++){let g=h[v],x=[...g.items].sort((I,F)=>_r(I.id,r,c)-_r(F.id,r,c)),w=p.filter(I=>I.x===h[v-1].x),H=Math.min(...w.map(I=>I.y)),Q=Math.max(...w.map(I=>I.y+I.h))-H,tt=x.reduce((I,F)=>I+ds(F,a)+10,-10),W=H+Math.max(0,(Q-tt)/2);for(let I of x){let F=ds(I,a),hs={id:I.id,x:g.x,y:W,w:g.width,h:F,label:I.label,type:I.type,stats:I.stats,annotations:I.annotations};p.push(hs),c.set(I.id,hs),W+=F+10;}}let R=[];for(let v of r){let g=c.get(v.source),x=c.get(v.target);if(!g||!x)continue;let w=g.x<x.x,H=w?g.x+g.w:g.x,Z=g.y+g.h/2,Q=w?x.x:x.x+x.w,tt=x.y+x.h/2,W=[];v.stats.frequency>1&&W.push(`${v.stats.frequency}\xD7`),W.push(v.type),v.stats.avgLatencyMs>0&&W.push(`${v.stats.avgLatencyMs}ms`),R.push({key:v.id,sx:H,sy:Z,tx:Q,ty:tt,label:W.join(" \xB7 "),color:xe[v.type]||"#94a3b8",thickness:Math.min(.75+Math.log2(v.stats.frequency+1)*.35,2.5),dashed:v.type==="reads"||v.type==="writes",data:v});}let P=p.reduce((v,g)=>Math.max(v,g.x+g.w),0),$=p.reduce((v,g)=>Math.max(v,g.y+g.h),0);return {nodes:p,edges:R,width:P+100,height:Math.max($+50,250)}}function Tr(o){let r=o.charCodeAt(0);return r>=48&&r<=57||r>=65&&r<=70||r>=97&&r<=102}function Gi(o){if(o.length!==36)return false;for(let r=0;r<o.length;r++)if(r===8||r===13||r===18||r===23){if(o[r]!=="-")return false}else if(!Tr(o[r]))return false;return true}function Bi(o){if(!o.length)return false;for(let r=0;r<o.length;r++){let t=o.charCodeAt(r);if(t<48||t>57)return false}return true}function Wi(o){if(o.length<12)return false;for(let r=0;r<o.length;r++)if(!Tr(o[r]))return false;return true}function ji(o){if(o.length<8)return false;let r=false,t=false;for(let e=0;e<o.length;e++){let s=o.charCodeAt(e);if(s>=65&&s<=90||s>=97&&s<=122)r=true;else if(s>=48&&s<=57)t=true;else if(s!==95&&s!==45)return false}return r&&t}var Qi=":id";function Yi(o){return Gi(o)||Bi(o)||Wi(o)||ji(o)?Qi:o}function ps(o,r){let t=r.split("?")[0];return `${o} ${t.split("/").map(e=>e&&Yi(e)).join("/")}`}function wr(o,r,t){let e=[...o],s=[...r],i=new Set(e.map(a=>a.id)),n=new Map;for(let a of t){let c=a.label||"Unknown",p=n.get(c);p||(p={endpointKeys:new Set,count:0,totalMs:0},n.set(c,p)),p.count++,p.totalMs+=a.totalDurationMs;for(let h of a.requests)h.path?.startsWith(U)||p.endpointKeys.add(ps(h.method,h.path));}for(let[a,c]of n){let p=`action:${a}`;i.has(p)||(e.push({id:p,type:"action",label:a,stats:{requestCount:c.count,avgLatencyMs:c.count>0?Math.round(c.totalMs/c.count):0,errorRate:0,avgQueryCount:0}}),i.add(p));for(let h of c.endpointKeys){let m=`endpoint:${h}`;if(i.has(m)){let f=`${p} -> ${m}`;s.find(S=>S.id===f)||s.push({id:f,source:p,target:m,type:"triggers",stats:{frequency:c.count,avgLatencyMs:0}});}}}return {nodes:e,edges:s}}function Rr(o){let r=new Map;for(let t of o){let e=t.label||"Unknown",s=r.get(e);s||(s={keys:new Set,count:0,totalMs:0},r.set(e,s)),s.count++,s.totalMs+=t.totalDurationMs;for(let i of t.requests)i.path?.startsWith(U)||s.keys.add(ps(i.method,i.path));}return [...r.entries()].map(([t,e])=>({label:t,occurrences:e.count,endpointKeys:e.keys,avgDurationMs:e.count>0?Math.round(e.totalMs/e.count):0}))}function we(o,r){let t=`event=${encodeURIComponent(o)}${r?`&detail=${encodeURIComponent(r)}`:""}`;fetch(`${T.tab}?${t}`).catch(()=>{});}var M=class extends E{constructor(){super(...arguments);this.graphNodes=[];this.graphEdges=[];this.locked=null;this.hovered=null;this.loading=true;this.activeLayers=new Set;this.searchQuery="";this.viewTransform={x:0,y:0,scale:1};this.isPanning=false;this.panStart={x:0,y:0,vtx:0,vty:0};this.dragging=null;this.wasDragging=false;this.nodePositionOverrides=new Map;this.detailTab="overview";this.consolidatedFlows=[];this.activeFlowIdx=-1;this.focusIdx=-1;this.refreshTimer=null;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.loadData(),this.refreshTimer=setInterval(()=>this.loadData(),4e3);}disconnectedCallback(){super.disconnectedCallback(),this.refreshTimer&&clearInterval(this.refreshTimer);}async loadData(){try{let[t,e]=await Promise.all([fetch(`${T.graph}?level=endpoints`),fetch(T.flows)]),s=await t.json(),i=await e.json(),n=wr(s.nodes||[],s.edges||[],i.flows||[]);this.graphNodes=n.nodes,this.graphEdges=n.edges,this.consolidatedFlows=Rr(i.flows||[]),this.nodePositionOverrides.size===0&&this.graphNodes.length>0&&this.tryLoadPersistedPositions(),this.loading=!1;}catch{this.loading=false;}}getPositionStorageKey(){let t=this.graphNodes.map(s=>s.id).sort().join(","),e=0;for(let s=0;s<t.length;s++)e=(e<<5)-e+t.charCodeAt(s)|0;return `bk-graph-pos-${e}`}persistPositions(){if(this.nodePositionOverrides.size!==0)try{let t=Object.fromEntries(this.nodePositionOverrides);localStorage.setItem(this.getPositionStorageKey(),JSON.stringify(t));}catch{}}tryLoadPersistedPositions(){try{let t=localStorage.getItem(this.getPositionStorageKey());if(t){let e=JSON.parse(t);this.nodePositionOverrides=new Map(Object.entries(e));}}catch{}}get activeNodeId(){return this.locked??this.hovered}getHighlightedNodeIds(){let t=this.activeNodeId;if(!t)return null;let e=new Set([t]),s=true;for(;s;){s=false;for(let i of this.graphEdges)e.has(i.source)&&!e.has(i.target)&&(e.add(i.target),s=true);}return e}getFlowTraceNodeIds(){if(this.activeFlowIdx<0||this.activeFlowIdx>=this.consolidatedFlows.length)return null;let t=this.consolidatedFlows[this.activeFlowIdx],e=new Set;e.add(`action:${t.label}`);for(let s of t.endpointKeys)e.add(`endpoint:${s}`);for(let s of this.graphEdges)e.has(s.source)&&e.add(s.target);return e}getFlowTraceEdgeIds(){let t=this.getFlowTraceNodeIds();if(!t)return null;let e=new Set;for(let s of this.graphEdges)t.has(s.source)&&t.has(s.target)&&e.add(s.id);return e}matchesSearch(t){return this.searchQuery?t.toLowerCase().includes(this.searchQuery.toLowerCase()):true}handlePanStart(t){t.button===0&&(t.target.closest(".graph-g")||(this.isPanning=true,this.panStart={x:t.clientX,y:t.clientY,vtx:this.viewTransform.x,vty:this.viewTransform.y}));}handlePanMove(t){if(this.dragging){let e=t.currentTarget.getBoundingClientRect(),s=(t.clientX-e.left-this.viewTransform.x)/this.viewTransform.scale,i=(t.clientY-e.top-this.viewTransform.y)/this.viewTransform.scale;this.nodePositionOverrides.set(this.dragging.nodeId,{x:s-this.dragging.offsetX,y:i-this.dragging.offsetY}),this.requestUpdate();return}this.isPanning&&(this.viewTransform={...this.viewTransform,x:this.panStart.vtx+(t.clientX-this.panStart.x),y:this.panStart.vty+(t.clientY-this.panStart.y)});}handlePanEnd(){this.dragging&&(this.persistPositions(),this.dragging=null,this.wasDragging=true,requestAnimationFrame(()=>{this.wasDragging=false;})),this.isPanning=false;}resetView(){this.viewTransform={x:0,y:0,scale:1};}zoomIn(){this.viewTransform={...this.viewTransform,scale:Math.min(br,this.viewTransform.scale*cs)};}zoomOut(){this.viewTransform={...this.viewTransform,scale:Math.max(gr,this.viewTransform.scale/cs)};}resetLayout(){this.nodePositionOverrides.clear();try{localStorage.removeItem(this.getPositionStorageKey());}catch{}this.viewTransform={x:0,y:0,scale:1},this.requestUpdate(),we("layout_reset");}startNodeDrag(t,e,s){t.stopPropagation();let i=t.currentTarget.closest("svg").getBoundingClientRect(),n=(t.clientX-i.left-this.viewTransform.x)/this.viewTransform.scale,a=(t.clientY-i.top-this.viewTransform.y)/this.viewTransform.scale;this.dragging={nodeId:e,offsetX:n-s.x,offsetY:a-s.y};}handleKeyDown(t){let e=this.graphNodes;if(t.key==="/"){t.preventDefault(),this.querySelector(".graph-search-input")?.focus();return}if(t.key==="Escape"){this.locked=null,this.searchQuery="",this.focusIdx=-1,this.activeFlowIdx=-1;return}if(t.key==="Tab"){t.preventDefault(),this.focusIdx=t.shiftKey?this.focusIdx<=0?e.length-1:this.focusIdx-1:(this.focusIdx+1)%e.length,this.hovered=e[this.focusIdx]?.id??null;return}if(t.key==="Enter"&&this.focusIdx>=0){let s=e[this.focusIdx];s&&(this.locked=this.locked===s.id?null:s.id);return}if(t.key==="+"||t.key==="="){this.zoomIn();return}if(t.key==="-"){this.zoomOut();return}if(t.key==="ArrowUp"){this.viewTransform={...this.viewTransform,y:this.viewTransform.y+re};return}if(t.key==="ArrowDown"){this.viewTransform={...this.viewTransform,y:this.viewTransform.y-re};return}if(t.key==="ArrowLeft"){this.viewTransform={...this.viewTransform,x:this.viewTransform.x+re};return}if(t.key==="ArrowRight"){this.viewTransform={...this.viewTransform,x:this.viewTransform.x-re};return}}render(){if(this.loading&&this.graphNodes.length===0)return l`<div class="graph-loading">Loading graph…</div>`;if(this.graphNodes.length===0)return l`
734
696
  <div class="graph-empty">
735
697
  <div class="graph-empty-icon">◎</div>
736
698
  <div class="graph-empty-title">No data yet</div>
737
699
  <div class="graph-empty-desc">Navigate your app to build the dependency graph.</div>
738
700
  </div>
739
- `;let t=hr(this.graphNodes,this.graphEdges);this.applyPositionOverrides(t);let e=this.getSelectedNodeDetail(),r=this.getHighlightedNodeIds(),i=this.getFlowTraceNodeIds(),n=this.getFlowTraceEdgeIds(),l=this.deduplicateColumnHeaders(t.nodes),c=Math.max(1,...this.graphNodes.map(h=>h.stats.requestCount)),d=this.viewTransform;return a`
701
+ `;let t=Sr(this.graphNodes,this.graphEdges);this.applyPositionOverrides(t);let e=this.getSelectedNodeDetail(),s=this.getHighlightedNodeIds(),i=this.getFlowTraceNodeIds(),n=this.getFlowTraceEdgeIds(),a=this.deduplicateColumnHeaders(t.nodes),c=Math.max(1,...this.graphNodes.map(h=>h.stats.requestCount)),p=this.viewTransform;return l`
740
702
  <div class="graph-wrapper" tabindex="0" @keydown=${this.handleKeyDown}
741
703
  @click=${h=>{let m=h.target;m.closest(".graph-detail")||m.closest(".graph-toolbar")||m.closest(".graph-float")||m.closest(".graph-g")||(this.locked=null);}}>
742
704
  ${this.renderToolbar()}
743
705
  <div class="graph-body">
744
706
  <div class="graph-canvas" style="position:relative">
745
707
  <svg width="100%" height="100%"
746
- viewBox="0 0 ${Math.max(t.width,ar)} ${Math.max(t.height,lr)}"
708
+ viewBox="0 0 ${Math.max(t.width,Er)} ${Math.max(t.height,yr)}"
747
709
  class="graph-svg"
748
710
  style="cursor:${this.isPanning?"grabbing":"grab"}"
749
711
  @mousedown=${this.handlePanStart}
@@ -751,26 +713,26 @@
751
713
  @mouseup=${this.handlePanEnd}
752
714
  @mouseleave=${this.handlePanEnd}>
753
715
 
754
- <g transform="translate(${d.x},${d.y}) scale(${d.scale})">
755
- ${O`${l.map(h=>O`
716
+ <g transform="translate(${p.x},${p.y}) scale(${p.scale})">
717
+ ${O`${a.map(h=>O`
756
718
  <text x="${h.x}" y="${58}" class="graph-col-header">${h.label}</text>
757
719
  `)}`}
758
720
 
759
- ${t.edges.map(h=>this.renderEdge(h,r,n,c))}
760
- ${t.nodes.map(h=>this.renderNode(h,r,i,c))}
721
+ ${t.edges.map(h=>this.renderEdge(h,s,n,c))}
722
+ ${t.nodes.map(h=>this.renderNode(h,s,i,c))}
761
723
  </g>
762
724
  </svg>
763
725
  ${this.renderFloatingControls()}
764
726
  </div>
765
- ${e?this.renderDetailPanel(e):p}
727
+ ${e?this.renderDetailPanel(e):d}
766
728
  </div>
767
729
  </div>
768
- `}applyPositionOverrides(t){for(let r of t.nodes){let i=this.nodePositionOverrides.get(r.id);i&&(r.x=i.x,r.y=i.y);}let e=new Map(t.nodes.map(r=>[r.id,r]));for(let r of t.edges){let i=e.get(r.data.source),n=e.get(r.data.target);if(i&&n){let l=i.x<n.x;r.sx=l?i.x+i.w:i.x,r.sy=i.y+i.h/2,r.tx=l?n.x:n.x+n.w,r.ty=n.y+n.h/2;}}}deduplicateColumnHeaders(t){let e=[],r=new Set;for(let i of t)r.has(i.type)||(r.add(i.type),e.push({x:i.x,label:At[i.type]?.columnHeader||i.type.toUpperCase()}));return e}renderToolbar(){return a`
730
+ `}applyPositionOverrides(t){for(let s of t.nodes){let i=this.nodePositionOverrides.get(s.id);i&&(s.x=i.x,s.y=i.y);}let e=new Map(t.nodes.map(s=>[s.id,s]));for(let s of t.edges){let i=e.get(s.data.source),n=e.get(s.data.target);if(i&&n){let a=i.x<n.x;s.sx=a?i.x+i.w:i.x,s.sy=i.y+i.h/2,s.tx=a?n.x:n.x+n.w,s.ty=n.y+n.h/2;}}}deduplicateColumnHeaders(t){let e=[],s=new Set;for(let i of t)s.has(i.type)||(s.add(i.type),e.push({x:i.x,label:kt[i.type]?.columnHeader||i.type.toUpperCase()}));return e}renderToolbar(){return l`
769
731
  <div class="graph-toolbar">
770
732
  <div class="graph-layer-toggles">
771
- ${Object.keys(Xe).map(t=>{let e=Xe[t],r=this.activeLayers.has(t);return a`
772
- <button class="graph-layer-btn ${r?"active":""}"
773
- style="${r?`border-color:${e.color};color:${e.color}`:""}"
733
+ ${Object.keys(rs).map(t=>{let e=rs[t],s=this.activeLayers.has(t);return l`
734
+ <button class="graph-layer-btn ${s?"active":""}"
735
+ style="${s?`border-color:${e.color};color:${e.color}`:""}"
774
736
  @click=${()=>this.toggleLayer(t)}
775
737
  title="${e.tooltip}">
776
738
  ${e.icon} ${e.label}
@@ -783,382 +745,479 @@
783
745
  <input class="graph-search-input" type="text" placeholder="Search nodes… ( / )"
784
746
  .value=${this.searchQuery}
785
747
  @input=${t=>{this.searchQuery=t.target.value;}}>
786
- ${this.searchQuery?a`
748
+ ${this.searchQuery?l`
787
749
  <button class="graph-search-clear" @click=${()=>{this.searchQuery="";}}>✕</button>
788
- `:p}
750
+ `:d}
789
751
  </div>
790
752
 
791
- ${this.consolidatedFlows.length>0?a`
792
- <select class="graph-flow-picker" @change=${t=>{this.activeFlowIdx=parseInt(t.target.value,10),this.activeFlowIdx>=0&&be("flow_traced");}}>
753
+ ${this.consolidatedFlows.length>0?l`
754
+ <select class="graph-flow-picker" @change=${t=>{this.activeFlowIdx=parseInt(t.target.value,10),this.activeFlowIdx>=0&&we("flow_traced");}}>
793
755
  <option value="-1">Trace flow…</option>
794
- ${this.consolidatedFlows.map((t,e)=>a`
756
+ ${this.consolidatedFlows.map((t,e)=>l`
795
757
  <option value="${e}" ?selected=${this.activeFlowIdx===e}>${t.label} → ${t.endpointKeys.size} ep · ${t.occurrences}×</option>
796
758
  `)}
797
759
  </select>
798
- `:p}
760
+ `:d}
799
761
 
800
- ${this.activeLayers.has("auth")?a`
762
+ ${this.activeLayers.has("auth")?l`
801
763
  <div class="graph-auth-legend">
802
- <span class="graph-auth-legend-item"><span style="color:${ze}">🛡</span> protected</span>
803
- <span class="graph-auth-legend-item"><span style="color:${ve};font-weight:700">!</span> no auth</span>
764
+ <span class="graph-auth-legend-item"><span style="color:${ns}">🛡</span> protected</span>
765
+ <span class="graph-auth-legend-item"><span style="color:${Se};font-weight:700">!</span> no auth</span>
804
766
  </div>
805
- `:p}
767
+ `:d}
806
768
  </div>
807
- `}renderFloatingControls(){let t=this.nodePositionOverrides.size>0,e=Math.round(this.viewTransform.scale*100);return a`
769
+ `}renderFloatingControls(){let t=this.nodePositionOverrides.size>0,e=Math.round(this.viewTransform.scale*100);return l`
808
770
  <div class="graph-float">
809
771
  <button class="graph-float-btn" @click=${this.zoomOut} title="Zoom out (-)">−</button>
810
772
  <span class="graph-float-zoom">${e}%</span>
811
773
  <button class="graph-float-btn" @click=${this.zoomIn} title="Zoom in (+)">+</button>
812
774
  <span class="graph-float-sep"></span>
813
775
  <button class="graph-float-btn" @click=${this.resetView} title="Reset pan & zoom">⊙</button>
814
- ${t?a`
776
+ ${t?l`
815
777
  <span class="graph-float-sep"></span>
816
778
  <button class="graph-float-btn graph-float-btn-accent" @click=${()=>this.resetLayout()} title="Reset layout to auto-arrange">
817
779
  ⟲ Reformat
818
780
  </button>
819
- `:p}
781
+ `:d}
820
782
  <span class="graph-float-sep"></span>
821
783
  <button class="graph-float-btn" @click=${()=>this.captureScreenshot()} title="Save graph as PNG">
822
784
  📷
823
785
  </button>
824
786
  </div>
825
- `}async captureScreenshot(){be("screenshot_captured");let t=this.querySelector(".graph-svg");if(!t)return;let e=t.cloneNode(true);e.setAttribute("xmlns","http://www.w3.org/2000/svg"),e.style.cssText="",e.removeAttribute("class");let r=document.createElement("style");r.textContent=`
787
+ `}async captureScreenshot(){we("screenshot_captured");let t=this.querySelector(".graph-svg");if(!t)return;let e=t.cloneNode(true);e.setAttribute("xmlns","http://www.w3.org/2000/svg"),e.style.cssText="",e.removeAttribute("class");let s=document.createElement("style");s.textContent=`
826
788
  text { font-family: 'Inter', system-ui, -apple-system, sans-serif; }
827
789
  .graph-col-header { fill: #c4c4cc; font-size: 9px; font-weight: 600; letter-spacing: 1.5px; }
828
790
  .graph-flow-edge { stroke-dasharray: 6,4; }
829
791
  .graph-pulse { }
830
- `,e.insertBefore(r,e.firstChild);let n=document.createElementNS("http://www.w3.org/2000/svg","rect");n.setAttribute("width","100%"),n.setAttribute("height","100%"),n.setAttribute("fill","#ffffff"),e.insertBefore(n,e.firstChild);let l=e.getAttribute("viewBox")||"0 0 800 500",[,,c,d]=l.split(" ").map(Number),h=2,m=c*h,v=d*h,x=new XMLSerializer().serializeToString(e),y=new Blob([x],{type:"image/svg+xml;charset=utf-8"}),k=URL.createObjectURL(y),$=new Image;$.onload=()=>{let f=document.createElement("canvas");f.width=m,f.height=v;let g=f.getContext("2d");g.fillStyle="#ffffff",g.fillRect(0,0,m,v),g.drawImage($,0,0,m,v),URL.revokeObjectURL(k),f.toBlob(T=>{if(!T)return;let R=document.createElement("a");R.href=URL.createObjectURL(T),R.download=`brakit-graph-${new Date().toISOString().slice(0,19).replace(/[T:]/g,"-")}.png`,document.body.appendChild(R),R.click(),document.body.removeChild(R),URL.revokeObjectURL(R.href);},"image/png");},$.src=k;}toggleLayer(t){let e=new Set(this.activeLayers);e.has(t)?e.delete(t):(e.add(t),be("layer_toggled",t)),this.activeLayers=e;}renderNode(t,e,r,i){let n=this.activeNodeId,l=e===null||e.has(t.id),c=n===t.id,d=this.locked===t.id,h=r?.has(t.id)??false,m=this.matchesSearch(t.label),v=At[t.type]||At.endpoint,x=d?zs:c?Zs:v.stroke,y=d?Js:c?tr:v.fill,k=d?2:c?1.5:.75,$=l?1:.08;this.searchQuery&&!m&&($=.05),r&&!h&&($=Math.min($,.08)),h&&($=1,x=Ke);let f=this.searchQuery&&m,g=t.annotations,T=this.activeLayers;T.has("performance")&&g?.p95Ms!==void 0&&t.type==="endpoint"&&(y=It(g.p95Ms)+"18"),T.has("heat")&&(y=Ve(t.stats.requestCount/i)+"20");let R=T.has("auth")&&t.type==="endpoint"&&!g?.hasAuth,H=T.has("auth")&&g?.hasAuth,X=T.has("security")?g?.securityFindings?.length??0:0,B=g?.securityFindings?.some(q=>q.severity==="critical"),V=T.has("issues")?g?.openIssueCount??0:0,G=this.nodeSubtitle(t),C=T.has("performance")&&g?.p95Ms!==void 0&&t.type==="endpoint";return O`
792
+ `,e.insertBefore(s,e.firstChild);let n=document.createElementNS("http://www.w3.org/2000/svg","rect");n.setAttribute("width","100%"),n.setAttribute("height","100%"),n.setAttribute("fill","#ffffff"),e.insertBefore(n,e.firstChild);let a=e.getAttribute("viewBox")||"0 0 800 500",[,,c,p]=a.split(" ").map(Number),h=2,m=c*h,f=p*h,S=new XMLSerializer().serializeToString(e),R=new Blob([S],{type:"image/svg+xml;charset=utf-8"}),P=URL.createObjectURL(R),$=new Image;$.onload=()=>{let v=document.createElement("canvas");v.width=m,v.height=f;let g=v.getContext("2d");g.fillStyle="#ffffff",g.fillRect(0,0,m,f),g.drawImage($,0,0,m,f),URL.revokeObjectURL(P),v.toBlob(x=>{if(!x)return;let w=document.createElement("a");w.href=URL.createObjectURL(x),w.download=`brakit-graph-${new Date().toISOString().slice(0,19).replace(/[T:]/g,"-")}.png`,document.body.appendChild(w),w.click(),document.body.removeChild(w),URL.revokeObjectURL(w.href);},"image/png");},$.src=P;}toggleLayer(t){let e=new Set(this.activeLayers);e.has(t)?e.delete(t):(e.add(t),we("layer_toggled",t)),this.activeLayers=e;}renderNode(t,e,s,i){let n=this.activeNodeId,a=e===null||e.has(t.id),c=n===t.id,p=this.locked===t.id,h=s?.has(t.id)??false,m=this.matchesSearch(t.label),f=kt[t.type]||kt.endpoint,S=p?cr:c?pr:f.stroke,R=p?dr:c?hr:f.fill,P=p?2:c?1.5:.75,$=a?1:.08;this.searchQuery&&!m&&($=.05),s&&!h&&($=Math.min($,.08)),h&&($=1,S=os);let v=this.searchQuery&&m,g=t.annotations,x=this.activeLayers;x.has("performance")&&g?.p95Ms!==void 0&&t.type==="endpoint"&&(R=Ot(g.p95Ms)+"18"),x.has("heat")&&(R=is(t.stats.requestCount/i)+"20");let w=x.has("auth")&&t.type==="endpoint"&&!g?.hasAuth,H=x.has("auth")&&g?.hasAuth,Z=x.has("security")?g?.securityFindings?.length??0:0,Q=g?.securityFindings?.some(F=>F.severity==="critical"),tt=x.has("issues")?g?.openIssueCount??0:0,W=this.nodeSubtitle(t),I=x.has("performance")&&g?.p95Ms!==void 0&&t.type==="endpoint";return O`
831
793
  <g class="graph-g" transform="translate(${t.x},${t.y})" style="opacity:${$};cursor:pointer;transition:opacity .15s,transform .1s"
832
- @click=${q=>{q.stopPropagation(),!this.wasDragging&&(this.locked=this.locked===t.id?null:t.id,this.detailTab="overview");}}
794
+ @click=${F=>{F.stopPropagation(),!this.wasDragging&&(this.locked=this.locked===t.id?null:t.id,this.detailTab="overview");}}
833
795
  @mouseenter=${()=>{this.hovered=t.id;}}
834
796
  @mouseleave=${()=>{this.hovered=null;}}
835
- @mousedown=${q=>{q.detail>=2||this.startNodeDrag(q,t.id,t);}}>
797
+ @mousedown=${F=>{F.detail>=2||this.startNodeDrag(F,t.id,t);}}>
836
798
 
837
- ${f?O`
799
+ ${v?O`
838
800
  <rect x="-3" y="-3" width="${t.w+6}" height="${t.h+6}" rx="9" fill="none"
839
- stroke="${er}" stroke-width="2" stroke-dasharray="4,2"/>
840
- `:p}
801
+ stroke="${ur}" stroke-width="2" stroke-dasharray="4,2"/>
802
+ `:d}
841
803
 
842
- ${R?O`
843
- <rect width="${t.w}" height="${t.h}" rx="8" fill="${y}" stroke="${ve}"
804
+ ${w?O`
805
+ <rect width="${t.w}" height="${t.h}" rx="8" fill="${R}" stroke="${Se}"
844
806
  stroke-width="1.2" stroke-dasharray="5,3"/>
845
807
  `:O`
846
- <rect width="${t.w}" height="${t.h}" rx="8" fill="${y}" stroke="${x}" stroke-width="${k}"/>
808
+ <rect width="${t.w}" height="${t.h}" rx="8" fill="${R}" stroke="${S}" stroke-width="${P}"/>
847
809
  `}
848
810
 
849
811
  <text x="12" y="${t.h/2-4}" fill="#1e293b" font-size="11.5" font-weight="600"
850
- font-family="'Inter',system-ui,sans-serif">${v.icon} ${t.label}</text>
812
+ font-family="'Inter',system-ui,sans-serif">${f.icon} ${t.label}</text>
851
813
  <text x="12" y="${t.h/2+10}" fill="#a1a1aa" font-size="9"
852
- font-family="ui-monospace,monospace">${G}</text>
814
+ font-family="ui-monospace,monospace">${W}</text>
853
815
 
854
- ${C?O`
855
- <text x="${t.w-8}" y="${t.h-6}" fill="${It(g.p95Ms)}" font-size="9"
816
+ ${I?O`
817
+ <text x="${t.w-8}" y="${t.h-6}" fill="${Ot(g.p95Ms)}" font-size="9"
856
818
  font-family="ui-monospace,monospace" text-anchor="end">p95: ${g.p95Ms}ms</text>
857
- `:p}
819
+ `:d}
858
820
 
859
821
  ${H?O`
860
822
  <g transform="translate(${t.w-24},3)">
861
823
  <title>Auth protected</title>
862
- <rect width="18" height="18" rx="3" fill="${sr}" stroke="${ze}" stroke-width="0.5"/>
824
+ <rect width="18" height="18" rx="3" fill="${mr}" stroke="${ns}" stroke-width="0.5"/>
863
825
  <text x="9" y="13" text-anchor="middle" font-size="10">🛡</text>
864
826
  </g>
865
- `:p}
827
+ `:d}
866
828
 
867
- ${R?O`
829
+ ${w?O`
868
830
  <g transform="translate(${t.w-24},3)">
869
831
  <title>No auth detected — this endpoint may be unprotected</title>
870
- <rect width="18" height="18" rx="3" fill="#fff7ed" stroke="${ve}" stroke-width="0.5"/>
832
+ <rect width="18" height="18" rx="3" fill="#fff7ed" stroke="${Se}" stroke-width="0.5"/>
871
833
  <text x="9" y="13" text-anchor="middle" font-size="10" fill="#ea580c">!</text>
872
834
  </g>
873
- `:p}
835
+ `:d}
874
836
 
875
- ${X>0?O`
876
- <g transform="translate(${t.w-(H||R?46:24)},3)">
877
- <rect width="18" height="18" rx="3" fill="${B?rr:ir}"
878
- stroke="${B?Je:Ze}" stroke-width="0.5"
879
- class="${B?"graph-pulse":""}"/>
837
+ ${Z>0?O`
838
+ <g transform="translate(${t.w-(H||w?46:24)},3)">
839
+ <rect width="18" height="18" rx="3" fill="${Q?fr:vr}"
840
+ stroke="${Q?as:ls}" stroke-width="0.5"
841
+ class="${Q?"graph-pulse":""}"/>
880
842
  <text x="9" y="13" text-anchor="middle" font-size="9" font-weight="600"
881
- fill="${B?Je:Ze}">${X}</text>
843
+ fill="${Q?as:ls}">${Z}</text>
882
844
  </g>
883
- `:p}
845
+ `:d}
884
846
 
885
- ${V>0?O`
886
- <circle cx="${t.w-8}" cy="8" r="5" fill="${ct}" stroke="white" stroke-width="1"/>
887
- <text x="${t.w-8}" y="11" text-anchor="middle" font-size="7" fill="white" font-weight="700">${V}</text>
888
- `:t.stats.errorRate>.05?O`<circle cx="${t.w-12}" cy="12" r="4" fill="${ct}"/>`:p}
847
+ ${tt>0?O`
848
+ <circle cx="${t.w-8}" cy="8" r="5" fill="${ut}" stroke="white" stroke-width="1"/>
849
+ <text x="${t.w-8}" y="11" text-anchor="middle" font-size="7" fill="white" font-weight="700">${tt}</text>
850
+ `:t.stats.errorRate>.05?O`<circle cx="${t.w-12}" cy="12" r="4" fill="${ut}"/>`:d}
889
851
 
890
- ${g?.isMiddleware&&T.has("auth")?O`
852
+ ${g?.isMiddleware&&x.has("auth")?O`
891
853
  <text x="${t.w}" y="${t.h+12}" text-anchor="end" font-size="8" fill="#6b7280"
892
854
  font-family="ui-monospace,monospace">middleware</text>
893
- `:p}
855
+ `:d}
894
856
  </g>
895
- `}nodeSubtitle(t){switch(t.type){case "endpoint":return `${t.stats.requestCount} req \xB7 ${t.stats.avgLatencyMs}ms${t.stats.avgQueryCount>0?` \xB7 ${t.stats.avgQueryCount}q`:""}`;case "action":return `${t.stats.requestCount}\xD7 \xB7 ${t.stats.avgLatencyMs}ms`;case "table":return "table";default:return "service"}}renderEdge(t,e,r,i){let n=this.activeNodeId,l=e===null||e.has(t.data.source)&&e.has(t.data.target),c=r?.has(t.key)??false,d=l?n===null?.25:.6:.04,h=l&&n!==null,m=t.color,v=t.thickness;if(r&&!c&&(d=.04),c&&(d=.85,m=Ke,v=Math.max(v,1.8)),this.activeLayers.has("heat")&&!c){let V=Math.max(1,...this.graphEdges.map(C=>C.stats.frequency)),G=t.data.stats.frequency/V;m=Ve(G),l&&(d=Math.max(d,.4));}let x=this.activeLayers.has("issues")&&t.data.annotations?.hasIssue,y=Math.abs(t.tx-t.sx),k=Math.min(y*.45,120),$=t.sx<t.tx,f=$?t.sx+k:t.sx-k,g=$?t.tx-k:t.tx+k,T=(t.sx+t.tx)/2,R=(t.sy+t.ty)/2,H=4,X=x?ct:m,B=x?Math.max(v,1.5):v;return O`
857
+ `}nodeSubtitle(t){switch(t.type){case "endpoint":return `${t.stats.requestCount} req \xB7 ${t.stats.avgLatencyMs}ms${t.stats.avgQueryCount>0?` \xB7 ${t.stats.avgQueryCount}q`:""}`;case "action":return `${t.stats.requestCount}\xD7 \xB7 ${t.stats.avgLatencyMs}ms`;case "table":return "table";default:return "service"}}renderEdge(t,e,s,i){let n=this.activeNodeId,a=e===null||e.has(t.data.source)&&e.has(t.data.target),c=s?.has(t.key)??false,p=a?n===null?.25:.6:.04,h=a&&n!==null,m=t.color,f=t.thickness;if(s&&!c&&(p=.04),c&&(p=.85,m=os,f=Math.max(f,1.8)),this.activeLayers.has("heat")&&!c){let tt=Math.max(1,...this.graphEdges.map(I=>I.stats.frequency)),W=t.data.stats.frequency/tt;m=is(W),a&&(p=Math.max(p,.4));}let S=this.activeLayers.has("issues")&&t.data.annotations?.hasIssue,R=Math.abs(t.tx-t.sx),P=Math.min(R*.45,120),$=t.sx<t.tx,v=$?t.sx+P:t.sx-P,g=$?t.tx-P:t.tx+P,x=(t.sx+t.tx)/2,w=(t.sy+t.ty)/2,H=4,Z=S?ut:m,Q=S?Math.max(f,1.5):f;return O`
896
858
  <g style="transition:opacity .15s">
897
- <path d="M${t.sx},${t.sy} C${f},${t.sy} ${g},${t.ty} ${t.tx},${t.ty}"
898
- fill="none" stroke="${X}" stroke-width="${B}"
899
- stroke-opacity="${d}" stroke-linecap="round"
859
+ <path d="M${t.sx},${t.sy} C${v},${t.sy} ${g},${t.ty} ${t.tx},${t.ty}"
860
+ fill="none" stroke="${Z}" stroke-width="${Q}"
861
+ stroke-opacity="${p}" stroke-linecap="round"
900
862
  stroke-dasharray="${c?"6,4":t.dashed?"3,3":"none"}"
901
863
  class="${c?"graph-flow-edge":""}"/>
902
864
  <polygon points="${t.tx},${t.ty} ${t.tx+($?-H*1.5:H*1.5)},${t.ty-H} ${t.tx+($?-H*1.5:H*1.5)},${t.ty+H}"
903
- fill="${X}" fill-opacity="${d}"/>
865
+ fill="${Z}" fill-opacity="${p}"/>
904
866
  ${h?O`
905
- <rect x="${T-t.label.length*2.8-2}" y="${R-7}" width="${t.label.length*5.6+8}" height="14"
867
+ <rect x="${x-t.label.length*2.8-2}" y="${w-7}" width="${t.label.length*5.6+8}" height="14"
906
868
  rx="4" fill="white" fill-opacity="0.92" stroke="${m}" stroke-width="0.4" stroke-opacity="0.15"/>
907
- <text x="${T}" y="${R+3.5}" fill="${m}" font-size="8" font-weight="500"
869
+ <text x="${x}" y="${w+3.5}" fill="${m}" font-size="8" font-weight="500"
908
870
  font-family="ui-monospace,monospace" text-anchor="middle" opacity="0.85">${t.label}</text>
909
- `:p}
910
- ${x?O`
911
- <text x="${T}" y="${R-10}" fill="${ct}" font-size="8" font-weight="600"
871
+ `:d}
872
+ ${S?O`
873
+ <text x="${x}" y="${w-10}" fill="${ut}" font-size="8" font-weight="600"
912
874
  text-anchor="middle">⚠ N+1</text>
913
- `:p}
875
+ `:d}
914
876
  </g>
915
- `}renderDetailPanel(t){let{node:e,edges:r}=t,i=At[e.type]||At.endpoint,n=e.annotations,l=(n?.securityFindings?.length??0)>0,c=(n?.openIssueCount??0)>0,d=n?.p95Ms!==void 0,m=[{key:"overview",label:"Overview",show:true},{key:"security",label:`Security${l?` (${n.securityFindings.length})`:""}`,show:l},{key:"performance",label:"Perf",show:d},{key:"issues",label:`Issues${c?` (${n.openIssueCount})`:""}`,show:c}].filter(v=>v.show);return a`
877
+ `}renderDetailPanel(t){let{node:e,edges:s}=t,i=kt[e.type]||kt.endpoint,n=e.annotations,a=(n?.securityFindings?.length??0)>0,c=(n?.openIssueCount??0)>0,p=n?.p95Ms!==void 0,m=[{key:"overview",label:"Overview",show:true},{key:"security",label:`Security${a?` (${n.securityFindings.length})`:""}`,show:a},{key:"performance",label:"Perf",show:p},{key:"issues",label:`Issues${c?` (${n.openIssueCount})`:""}`,show:c}].filter(f=>f.show);return l`
916
878
  <div class="graph-detail">
917
879
  <div class="graph-detail-head">
918
880
  <div>
919
881
  <div class="graph-detail-badge" style="color:${i.stroke}">${i.icon} ${e.type}</div>
920
882
  <div class="graph-detail-name">${e.label}</div>
921
- ${n?.hasAuth?a`<span class="graph-detail-auth-badge">🛡 Authenticated</span>`:p}
922
- ${n?.isMiddleware?a`<span class="graph-detail-mw-badge">middleware</span>`:p}
883
+ ${n?.hasAuth?l`<span class="graph-detail-auth-badge">🛡 Authenticated</span>`:d}
884
+ ${n?.isMiddleware?l`<span class="graph-detail-mw-badge">middleware</span>`:d}
923
885
  </div>
924
886
  <button class="graph-detail-close" @click=${()=>{this.locked=null;}}>✕</button>
925
887
  </div>
926
888
 
927
- ${m.length>1?a`
889
+ ${m.length>1?l`
928
890
  <div class="graph-detail-tabs">
929
- ${m.map(v=>a`
930
- <button class="graph-detail-tab ${this.detailTab===v.key?"active":""}"
931
- @click=${()=>{this.detailTab=v.key;}}>${v.label}</button>
891
+ ${m.map(f=>l`
892
+ <button class="graph-detail-tab ${this.detailTab===f.key?"active":""}"
893
+ @click=${()=>{this.detailTab=f.key;}}>${f.label}</button>
932
894
  `)}
933
895
  </div>
934
- `:p}
896
+ `:d}
935
897
 
936
- ${this.detailTab==="overview"?this.renderOverviewTab(e,r):p}
937
- ${this.detailTab==="security"?this.renderSecurityTab(n):p}
938
- ${this.detailTab==="performance"?this.renderPerformanceTab(e,n):p}
939
- ${this.detailTab==="issues"?this.renderIssuesTab(n):p}
898
+ ${this.detailTab==="overview"?this.renderOverviewTab(e,s):d}
899
+ ${this.detailTab==="security"?this.renderSecurityTab(n):d}
900
+ ${this.detailTab==="performance"?this.renderPerformanceTab(e,n):d}
901
+ ${this.detailTab==="issues"?this.renderIssuesTab(n):d}
940
902
  </div>
941
- `}renderOverviewTab(t,e){return a`
903
+ `}renderOverviewTab(t,e){return l`
942
904
  <div class="graph-detail-stats">
943
905
  <div class="graph-detail-stat">
944
906
  <div class="graph-detail-val">${t.stats.requestCount}</div>
945
907
  <div class="graph-detail-lbl">${t.type==="action"?"OCCURRENCES":"REQUESTS"}</div>
946
908
  </div>
947
909
  <div class="graph-detail-stat">
948
- <div class="graph-detail-val" style="color:${It(t.stats.avgLatencyMs)}">${t.stats.avgLatencyMs}ms</div>
910
+ <div class="graph-detail-val" style="color:${Ot(t.stats.avgLatencyMs)}">${t.stats.avgLatencyMs}ms</div>
949
911
  <div class="graph-detail-lbl">AVG LATENCY</div>
950
912
  </div>
951
- ${t.stats.avgQueryCount>0?a`
913
+ ${t.stats.avgQueryCount>0?l`
952
914
  <div class="graph-detail-stat">
953
915
  <div class="graph-detail-val">${t.stats.avgQueryCount}</div>
954
916
  <div class="graph-detail-lbl">QUERIES/REQ</div>
955
917
  </div>
956
- `:p}
957
- ${t.stats.errorRate>.01?a`
918
+ `:d}
919
+ ${t.stats.errorRate>.01?l`
958
920
  <div class="graph-detail-stat">
959
- <div class="graph-detail-val" style="color:${ct}">${Math.round(t.stats.errorRate*100)}%</div>
921
+ <div class="graph-detail-val" style="color:${ut}">${Math.round(t.stats.errorRate*100)}%</div>
960
922
  <div class="graph-detail-lbl">ERRORS</div>
961
923
  </div>
962
- `:p}
924
+ `:d}
963
925
  </div>
964
926
 
965
- ${e.length>0?a`
927
+ ${e.length>0?l`
966
928
  <div class="graph-detail-sec">Connections</div>
967
- ${e.map(r=>{let i=r.source===this.locked,n=(i?r.target:r.source).replace(/^(action|endpoint|table|external):/,"");return a`
929
+ ${e.map(s=>{let i=s.source===this.locked,n=(i?s.target:s.source).replace(/^(action|endpoint|table|external):/,"");return l`
968
930
  <div class="graph-detail-conn">
969
- <span class="graph-detail-edge-dot" style="background:${fe[r.type]}"></span>
970
- <span class="graph-detail-edge-type">${r.type}</span>
931
+ <span class="graph-detail-edge-dot" style="background:${xe[s.type]}"></span>
932
+ <span class="graph-detail-edge-type">${s.type}</span>
971
933
  <span>${i?"\u2192":"\u2190"} ${n}</span>
972
- <span class="graph-detail-dim">${r.stats.frequency}× · ${r.stats.avgLatencyMs}ms</span>
934
+ <span class="graph-detail-dim">${s.stats.frequency}× · ${s.stats.avgLatencyMs}ms</span>
973
935
  </div>
974
936
  `})}
975
- `:p}
937
+ `:d}
976
938
 
977
- ${e.some(r=>r.patterns?.length)?a`
939
+ ${e.some(s=>s.patterns?.length)?l`
978
940
  <div class="graph-detail-sec">SQL Patterns</div>
979
- ${e.filter(r=>r.patterns).flatMap(r=>r.patterns).map(r=>a`
980
- <pre class="graph-detail-sql">${r.length>200?r.slice(0,200)+"\u2026":r}</pre>
941
+ ${e.filter(s=>s.patterns).flatMap(s=>s.patterns).map(s=>l`
942
+ <pre class="graph-detail-sql">${s.length>200?s.slice(0,200)+"\u2026":s}</pre>
981
943
  `)}
982
- `:p}
983
- `}renderSecurityTab(t){return t?.securityFindings?.length?a`
984
- ${t.securityFindings.map(e=>a`
944
+ `:d}
945
+ `}renderSecurityTab(t){return t?.securityFindings?.length?l`
946
+ ${t.securityFindings.map(e=>l`
985
947
  <div class="graph-detail-finding">
986
948
  <span class="graph-detail-severity graph-detail-severity-${e.severity}">${e.severity}</span>
987
949
  <div class="graph-detail-finding-title">${e.title}</div>
988
950
  <div class="graph-detail-finding-meta">${e.rule} · ${e.count} occurrence${e.count!==1?"s":""}</div>
989
951
  </div>
990
952
  `)}
991
- `:a`<div class="graph-detail-empty">No security findings</div>`}renderPerformanceTab(t,e){return a`
953
+ `:l`<div class="graph-detail-empty">No security findings</div>`}renderPerformanceTab(t,e){return l`
992
954
  <div class="graph-detail-stats">
993
- ${e?.p95Ms!==void 0?a`
955
+ ${e?.p95Ms!==void 0?l`
994
956
  <div class="graph-detail-stat">
995
- <div class="graph-detail-val" style="color:${It(e.p95Ms)}">${e.p95Ms}ms</div>
957
+ <div class="graph-detail-val" style="color:${Ot(e.p95Ms)}">${e.p95Ms}ms</div>
996
958
  <div class="graph-detail-lbl">P95 LATENCY</div>
997
959
  </div>
998
- `:p}
960
+ `:d}
999
961
  <div class="graph-detail-stat">
1000
- <div class="graph-detail-val" style="color:${It(t.stats.avgLatencyMs)}">${t.stats.avgLatencyMs}ms</div>
962
+ <div class="graph-detail-val" style="color:${Ot(t.stats.avgLatencyMs)}">${t.stats.avgLatencyMs}ms</div>
1001
963
  <div class="graph-detail-lbl">AVG LATENCY</div>
1002
964
  </div>
1003
- ${t.stats.avgQueryCount>0?a`
965
+ ${t.stats.avgQueryCount>0?l`
1004
966
  <div class="graph-detail-stat">
1005
967
  <div class="graph-detail-val">${t.stats.avgQueryCount}</div>
1006
968
  <div class="graph-detail-lbl">QUERIES/REQ</div>
1007
969
  </div>
1008
- `:p}
970
+ `:d}
1009
971
  <div class="graph-detail-stat">
1010
972
  <div class="graph-detail-val">${t.stats.requestCount}</div>
1011
973
  <div class="graph-detail-lbl">TOTAL REQS</div>
1012
974
  </div>
1013
975
  </div>
1014
976
 
1015
- ${(e?.insights?.length??0)>0?a`
977
+ ${(e?.insights?.length??0)>0?l`
1016
978
  <div class="graph-detail-sec">Performance Insights</div>
1017
- ${e.insights.map(r=>a`
979
+ ${e.insights.map(s=>l`
1018
980
  <div class="graph-detail-finding">
1019
- <span class="graph-detail-severity graph-detail-severity-${r.severity}">${r.severity}</span>
1020
- <div class="graph-detail-finding-title">${r.title}</div>
1021
- <div class="graph-detail-finding-meta">${r.type}</div>
981
+ <span class="graph-detail-severity graph-detail-severity-${s.severity}">${s.severity}</span>
982
+ <div class="graph-detail-finding-title">${s.title}</div>
983
+ <div class="graph-detail-finding-meta">${s.type}</div>
1022
984
  </div>
1023
985
  `)}
1024
- `:p}
1025
- `}renderIssuesTab(t){let e=t?.openIssueCount??0;return e===0?a`<div class="graph-detail-empty">No open issues</div>`:a`
986
+ `:d}
987
+ `}renderIssuesTab(t){let e=t?.openIssueCount??0;return e===0?l`<div class="graph-detail-empty">No open issues</div>`:l`
1026
988
  <div class="graph-detail-issue-summary">
1027
989
  <div class="graph-detail-stat">
1028
- <div class="graph-detail-val" style="color:${ct}">${e}</div>
990
+ <div class="graph-detail-val" style="color:${ut}">${e}</div>
1029
991
  <div class="graph-detail-lbl">OPEN ISSUES</div>
1030
992
  </div>
1031
993
  </div>
1032
994
  <p class="graph-detail-hint">View the Issues tab for full details and remediation hints.</p>
1033
- `}getSelectedNodeDetail(){if(!this.locked)return null;let t=this.graphNodes.find(r=>r.id===this.locked);if(!t)return null;let e=this.graphEdges.filter(r=>r.source===this.locked||r.target===this.locked);return {node:t,edges:e}}};u([I({context:A})],M.prototype,"store",2),u([b()],M.prototype,"graphNodes",2),u([b()],M.prototype,"graphEdges",2),u([b()],M.prototype,"locked",2),u([b()],M.prototype,"hovered",2),u([b()],M.prototype,"loading",2),u([b()],M.prototype,"activeLayers",2),u([b()],M.prototype,"searchQuery",2),u([b()],M.prototype,"viewTransform",2),u([b()],M.prototype,"dragging",2),u([b()],M.prototype,"detailTab",2),u([b()],M.prototype,"consolidatedFlows",2),u([b()],M.prototype,"activeFlowIdx",2),u([b()],M.prototype,"focusIdx",2),M=u([S("bk-graph-view")],M);function qi(o){return o===0?"<1ms":_(o)}var N=class extends E{constructor(){super(...arguments);this.requestId="";this.requestStarted=0;this.data=null;this.loading=false;this.failed=false;this.expandedSqlIdx=-1;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate()),this.requestId&&this.loadTimeline();}async loadTimeline(){if(!this.requestId)return;let t=N.cache.get(this.requestId);if(t){this.data=t;return}this.loading=true;try{let e=await fetch(`${w.activity}?requestId=${this.requestId}`);if(!e.ok){this.failed=!0,this.loading=!1;return}let r=await e.json();if(N.cache.size>=ke){let i=N.cache.keys().next().value;i!==void 0&&N.cache.delete(i);}N.cache.set(this.requestId,r),this.data=r,this.loading=!1;}catch(e){console.debug("[brakit] timeline load failed:",e),this.failed=true,this.loading=false;}}toggleSql(t,e){e.stopPropagation(),this.expandedSqlIdx=this.expandedSqlIdx===t?-1:t;}copySql(t,e){e.stopPropagation(),navigator.clipboard.writeText(t).then(()=>D.show("SQL copied")).catch(()=>D.show("Copy failed"));}render(){if(this.loading)return a`<div class="tl-loading">Loading activity...</div>`;if(this.failed||!this.data||this.data.total===0)return p;let t=this.data,e=t.timeline[0]?.timestamp??0;return a`
995
+ `}getSelectedNodeDetail(){if(!this.locked)return null;let t=this.graphNodes.find(s=>s.id===this.locked);if(!t)return null;let e=this.graphEdges.filter(s=>s.source===this.locked||s.target===this.locked);return {node:t,edges:e}}};u([C({context:A})],M.prototype,"store",2),u([b()],M.prototype,"graphNodes",2),u([b()],M.prototype,"graphEdges",2),u([b()],M.prototype,"locked",2),u([b()],M.prototype,"hovered",2),u([b()],M.prototype,"loading",2),u([b()],M.prototype,"activeLayers",2),u([b()],M.prototype,"searchQuery",2),u([b()],M.prototype,"viewTransform",2),u([b()],M.prototype,"dragging",2),u([b()],M.prototype,"detailTab",2),u([b()],M.prototype,"consolidatedFlows",2),u([b()],M.prototype,"activeFlowIdx",2),u([b()],M.prototype,"focusIdx",2),M=u([_("bk-graph-view")],M);var ie=class extends J{constructor(){super(...arguments);this.activeTab="requests";this.handleNavigateExplorer=t=>{let e=t.detail;ve.some(s=>s.key===e)&&(this.activeTab=e);};}connectedCallback(){super.connectedCallback(),window.addEventListener("navigate-explorer",this.handleNavigateExplorer);}disconnectedCallback(){super.disconnectedCallback(),window.removeEventListener("navigate-explorer",this.handleNavigateExplorer);}switchTab(t){this.activeTab=t,fetch(`${T.tab}?event=explorer.${t}`).catch(()=>{});}getCount(t){let e=this.store.state;switch(t){case "requests":return e.requests.filter(s=>!s.path?.startsWith(U)).length;case "fetches":return e.fetches.length;case "queries":return e.queries.length;case "logs":return e.logs.length;case "errors":return e.errors.length}}render(){return l`
996
+ <div class="explorer-tabs">
997
+ ${ve.map(t=>l`
998
+ <button class="explorer-tab ${this.activeTab===t.key?"active":""}"
999
+ @click=${()=>this.switchTab(t.key)}>
1000
+ ${t.label}
1001
+ <span class="explorer-tab-count">${this.getCount(t.key)}</span>
1002
+ </button>
1003
+ `)}
1004
+ </div>
1005
+ <div style="display:${this.activeTab==="requests"?"block":"none"}">
1006
+ <bk-requests-view></bk-requests-view>
1007
+ </div>
1008
+ <div style="display:${this.activeTab==="fetches"?"block":"none"}">
1009
+ <bk-fetches-view></bk-fetches-view>
1010
+ </div>
1011
+ <div style="display:${this.activeTab==="queries"?"block":"none"}">
1012
+ <bk-queries-view></bk-queries-view>
1013
+ </div>
1014
+ <div style="display:${this.activeTab==="logs"?"block":"none"}">
1015
+ <bk-logs-view></bk-logs-view>
1016
+ </div>
1017
+ <div style="display:${this.activeTab==="errors"?"block":"none"}">
1018
+ <bk-errors-view></bk-errors-view>
1019
+ </div>
1020
+ `}};u([b()],ie.prototype,"activeTab",2),ie=u([_("bk-explorer-view")],ie);var Vi=[{key:"all",label:"All"},{key:"security",label:"Security"},{key:"performance",label:"Performance"},{key:"reliability",label:"Reliability"}],mt=class extends J{constructor(){super(...arguments);this.filter="all";this.expandedIdx=-1;this.showDismissed=false;}getFilteredIssues(t){return (this.filter==="all"?t:t.filter(s=>Xt(s)===this.filter)).sort((s,i)=>{let n=h=>h==="open"||h==="regressed"?0:h==="fixing"?1:2,a=n(s.state)-n(i.state);if(a!==0)return a;let c=Y[s.issue.severity]?.sort??3,p=Y[i.issue.severity]?.sort??3;return c-p})}getCounts(t){let e={all:t.length,security:0,performance:0,reliability:0};for(let s of t)e[Xt(s)]++;return e}render(){if(!(this.store.state.requests.length>0||this.store.state.queries.length>0))return l`<bk-empty-state
1021
+ title="Waiting for requests..."
1022
+ subtitle="Start using your app to see insights here"
1023
+ ></bk-empty-state>`;let e=(this.store.state.issues||[]).filter(ir),s=this.getFilteredIssues(e),i=this.getCounts(e),n=s.filter(f=>f.state==="open"&&f.aiStatus!=="wont_fix"),a=s.filter(f=>f.state==="regressed"&&f.aiStatus!=="wont_fix"),c=s.filter(f=>f.state==="fixing"),p=s.filter(f=>f.state==="resolved"),h=s.filter(f=>f.aiStatus==="wont_fix"),m=0;return l`
1024
+ <div class="insights-filters">
1025
+ ${Vi.map(f=>l`
1026
+ <button class="insights-chip ${this.filter===f.key?"active":""}"
1027
+ @click=${()=>{this.filter=f.key,this.expandedIdx=-1;}}>
1028
+ ${f.label}
1029
+ ${i[f.key]>0?l`<span class="insights-chip-count">${i[f.key]}</span>`:d}
1030
+ </button>
1031
+ `)}
1032
+ </div>
1033
+
1034
+ ${this.renderSummaryBar(e)}
1035
+
1036
+ <div class="insights-list">
1037
+ ${n.length+a.length>0?l`
1038
+ <div class="insights-ai-hint">Copy to your AI: <code>"Fix brakit findings"</code></div>
1039
+ `:d}
1040
+ ${n.length===0&&a.length===0&&c.length===0&&p.length===0&&h.length===0?l`<div class="insights-empty"><span class="insights-empty-icon">\u2713</span>${this.filter==="all"?"All clear \u2014 no issues detected":`No ${this.filter} issues`}</div>`:d}
1041
+
1042
+ ${a.length>0?l`
1043
+ <div class="insights-section insights-section-regressed">
1044
+ <span class="insights-section-icon">\u21A9</span> Regressed
1045
+ <span class="insights-section-count">${a.length}</span>
1046
+ </div>
1047
+ ${a.map(f=>this.renderIssueCard(f,m++))}
1048
+ `:d}
1049
+
1050
+ ${n.length>0?l`
1051
+ <div class="insights-section">
1052
+ <span class="insights-section-icon">\u25CF</span> Open
1053
+ <span class="insights-section-count">${n.length}</span>
1054
+ </div>
1055
+ ${n.map(f=>this.renderIssueCard(f,m++))}
1056
+ `:d}
1057
+
1058
+ ${c.length>0?l`
1059
+ <div class="insights-section insights-section-verifying">
1060
+ <span class="insights-section-icon">\u29D7</span> Verifying
1061
+ <span class="insights-section-count">${c.length}</span>
1062
+ </div>
1063
+ ${c.map(f=>this.renderIssueCard(f,m++))}
1064
+ `:d}
1065
+
1066
+ ${p.length>0?l`
1067
+ <div class="insights-section insights-section-resolved">
1068
+ <span class="insights-section-icon">\u2713</span> Resolved
1069
+ <span class="insights-section-count">${p.length}</span>
1070
+ </div>
1071
+ ${p.map(f=>this.renderIssueCard(f,m++))}
1072
+ `:d}
1073
+
1074
+ ${h.length>0?l`
1075
+ <div class="insights-section insights-section-dismissed" @click=${()=>{this.showDismissed=!this.showDismissed;}}>
1076
+ <span class="insights-section-icon">${this.showDismissed?"\u25BE":"\u25B8"}</span> Won't Fix
1077
+ <span class="insights-section-count">${h.length}</span>
1078
+ </div>
1079
+ ${this.showDismissed?h.map(f=>this.renderIssueCard(f,m++)):d}
1080
+ `:d}
1081
+ </div>
1082
+ `}renderSummaryBar(t){let e=t.filter(a=>(a.state==="open"||a.state==="regressed")&&a.aiStatus!=="wont_fix"),s=e.filter(a=>a.issue.severity==="critical").length,i=e.filter(a=>a.issue.severity==="warning").length,n=t.filter(a=>a.state==="resolved").length;return s===0&&i===0&&n===0?d:l`
1083
+ <div class="insights-summary">
1084
+ ${s>0?l`<span class="insights-summary-stat critical">${s} critical</span>`:d}
1085
+ ${i>0?l`<span class="insights-summary-stat warning">${i} warning</span>`:d}
1086
+ ${n>0?l`<span class="insights-summary-stat resolved">${n} resolved</span>`:d}
1087
+ </div>
1088
+ `}renderIssueCard(t,e){let s=t.issue,i=Y[s.severity]||Y.info,n=this.expandedIdx===e,a=t.state==="resolved",c=t.state==="fixing",p=Xt(t);return l`
1089
+ <div class="insights-card ${n?"expanded":""} ${a?"resolved":""}"
1090
+ @click=${()=>{this.expandedIdx=this.expandedIdx===e?-1:e;}}>
1091
+ <div class="insights-card-left">
1092
+ <span class="insights-sev ${i.cls}">${i.icon}</span>
1093
+ </div>
1094
+ <div class="insights-card-body">
1095
+ <div class="insights-card-header">
1096
+ <span class="insights-card-title ${a?"resolved":""}">${s.title}</span>
1097
+ <span class="insights-card-cat">${p}</span>
1098
+ ${s.count?l`<span class="insights-card-count">${s.count}\u00D7</span>`:d}
1099
+ ${t.state==="regressed"?l`<span class="insights-badge-regressed">regressed</span>`:d}
1100
+ ${c?l`<span class="insights-badge-verifying">verifying</span>`:d}
1101
+ ${a?l`<span class="insights-badge-resolved">resolved</span>`:d}
1102
+ </div>
1103
+ <div class="insights-card-desc">${s.desc}</div>
1104
+ ${n?l`
1105
+ ${s.detail?l`<div class="insights-card-detail">${s.detail}</div>`:d}
1106
+ ${t.cleanHitsSinceLastSeen>0?l`
1107
+ <div class="insights-card-progress">${t.cleanHitsSinceLastSeen}/${5} clean requests</div>
1108
+ `:d}
1109
+ ${s.hint?l`<div class="insights-card-hint">${s.hint}</div>`:d}
1110
+ `:d}
1111
+ </div>
1112
+ ${s.hint?l`<span class="insights-card-arrow">${n?"\u2193":"\u2192"}</span>`:d}
1113
+ </div>
1114
+ `}};u([b()],mt.prototype,"filter",2),u([b()],mt.prototype,"expandedIdx",2),u([b()],mt.prototype,"showDismissed",2),mt=u([_("bk-insights-view")],mt);function Ki(o){return o===0?"<1ms":y(o)}var k=class extends E{constructor(){super(...arguments);this.requestId="";this.requestStarted=0;this.data=null;this.loading=false;this.failed=false;this.expandedSqlIdx=-1;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate()),this.requestId&&this.loadTimeline();}async loadTimeline(){if(!this.requestId)return;let t=k.cache.get(this.requestId);if(t){this.data=t;return}this.loading=true;try{let e=await fetch(`${T.activity}?requestId=${this.requestId}`);if(!e.ok){this.failed=!0,this.loading=!1;return}let s=await e.json();if(k.cache.size>=We){let i=k.cache.keys().next().value;i!==void 0&&k.cache.delete(i);}k.cache.set(this.requestId,s),this.data=s,this.loading=!1;}catch(e){console.debug("[brakit] timeline load failed:",e),this.failed=true,this.loading=false;}}toggleSql(t,e){e.stopPropagation(),this.expandedSqlIdx=this.expandedSqlIdx===t?-1:t;}copySql(t,e){e.stopPropagation(),navigator.clipboard.writeText(t).then(()=>D.show("SQL copied")).catch(()=>D.show("Copy failed"));}render(){if(this.loading)return l`<div class="tl-loading">Loading activity...</div>`;if(this.failed||!this.data||this.data.total===0)return d;let t=this.data,e=t.timeline[0]?.timestamp??0;return l`
1034
1115
  <div class="tl-header">
1035
1116
  <span class="tl-title">Activity Timeline</span>
1036
1117
  <span class="tl-counts">
1037
- ${t.counts.queries>0?a`<span class="tl-count tl-count-query">${t.counts.queries} quer${t.counts.queries===1?"y":"ies"}</span>`:p}
1038
- ${t.counts.fetches>0?a`<span class="tl-count tl-count-fetch">${t.counts.fetches} fetch${t.counts.fetches===1?"":"es"}</span>`:p}
1039
- ${t.counts.logs>0?a`<span class="tl-count tl-count-log">${t.counts.logs} log${t.counts.logs===1?"":"s"}</span>`:p}
1040
- ${t.counts.errors>0?a`<span class="tl-count tl-count-error">${t.counts.errors} error${t.counts.errors===1?"":"s"}</span>`:p}
1118
+ ${t.counts.queries>0?l`<span class="tl-count tl-count-query">${t.counts.queries} quer${t.counts.queries===1?"y":"ies"}</span>`:d}
1119
+ ${t.counts.fetches>0?l`<span class="tl-count tl-count-fetch">${t.counts.fetches} fetch${t.counts.fetches===1?"":"es"}</span>`:d}
1120
+ ${t.counts.logs>0?l`<span class="tl-count tl-count-log">${t.counts.logs} log${t.counts.logs===1?"":"s"}</span>`:d}
1121
+ ${t.counts.errors>0?l`<span class="tl-count tl-count-error">${t.counts.errors} error${t.counts.errors===1?"":"s"}</span>`:d}
1041
1122
  </span>
1042
1123
  </div>
1043
1124
  <div class="tl-events">${this.renderTimeline(t.timeline,e)}</div>
1044
- `}renderTimeline(t,e){let r=new Map,i=[];for(let l of t){let c=l.type==="query"?l.data.parentFetchId:void 0;if(l.type==="query"&&c){let d=r.get(c);d||(d=[],r.set(c,d)),d.push(l);}else i.push(l);}let n=0;return i.map(l=>{let c=n++,d=l.type==="fetch"?l.data.fetchId:void 0,h=d?r.get(d):void 0;if(h&&h.length>0){let m=h.length;return a`
1045
- ${this.renderEvent(l,c,e)}
1125
+ `}renderTimeline(t,e){let s=new Map,i=[];for(let a of t){let c=a.type==="query"?a.data.parentFetchId:void 0;if(a.type==="query"&&c){let p=s.get(c);p||(p=[],s.set(c,p)),p.push(a);}else i.push(a);}let n=0;return i.map(a=>{let c=n++,p=a.type==="fetch"?a.data.fetchId:void 0,h=p?s.get(p):void 0;if(h&&h.length>0){let m=h.length;return l`
1126
+ ${this.renderEvent(a,c,e)}
1046
1127
  <div class="tl-nested">
1047
1128
  <span class="tl-nested-label">${m} nested quer${m===1?"y":"ies"}</span>
1048
- ${h.map(v=>{let x=n++;return this.renderEvent(v,x,e,true)})}
1129
+ ${h.map(f=>{let S=n++;return this.renderEvent(f,S,e,true)})}
1049
1130
  </div>
1050
- `}return this.renderEvent(l,c,e)})}renderEvent(t,e,r,i=false){let n=Ms[t.type]||"var(--text-dim)",l=Ns[t.type]||t.type,c="+"+_(Math.round(t.timestamp-r)),d=t.type==="query"?t.data.sql:void 0,h=!!d,m=this.expandedSqlIdx===e;return a`
1131
+ `}return this.renderEvent(a,c,e)})}renderEvent(t,e,s,i=false){let n=Bs[t.type]||"var(--text-dim)",a=Ws[t.type]||t.type,c="+"+y(Math.round(t.timestamp-s)),p=t.type==="query"?t.data.sql:void 0,h=!!p,m=this.expandedSqlIdx===e;return l`
1051
1132
  <div class="tl-event ${h?"tl-clickable":""} ${i?"tl-nested-event":""}"
1052
1133
  style="${h?"":`border-left-color:${n}`}"
1053
- @click=${h?v=>this.toggleSql(e,v):p}>
1134
+ @click=${h?f=>this.toggleSql(e,f):d}>
1054
1135
  <span class="tl-event-time">${c}</span>
1055
- <span class="tl-event-type" style="color:${n}">${l}</span>
1136
+ <span class="tl-event-type" style="color:${n}">${a}</span>
1056
1137
  ${this.renderEventContent(t)}
1057
- ${d?a`
1138
+ ${p?l`
1058
1139
  <div class="tl-event-sql ${m?"open":""}">
1059
- <button class="tl-sql-copy" @click=${v=>this.copySql(d,v)}>Copy</button>
1060
- ${d}
1061
- </div>`:p}
1140
+ <button class="tl-sql-copy" @click=${f=>this.copySql(p,f)}>Copy</button>
1141
+ ${p}
1142
+ </div>`:d}
1062
1143
  </div>
1063
- `}renderEventContent(t){switch(t.type){case "fetch":{let e=t.data,r=e.statusCode>=400;return a`
1144
+ `}renderEventContent(t){switch(t.type){case "fetch":{let e=t.data,s=e.statusCode>=400;return l`
1064
1145
  <span class="tl-event-summary">${e.method} ${e.url}</span>
1065
- <span class="tl-event-status" style="${r?"color:var(--red)":""}">${e.statusCode}</span>
1066
- <span class="tl-event-dur">${_(e.durationMs)}</span>
1067
- `}case "query":{let e=t.data,r=(e.normalizedOp||e.operation||"?").toUpperCase(),i=e.table||e.model||"",n=pe[r]||"var(--text-dim)";return a`
1068
- <span class="tl-event-summary"><span style="color:${n};font-weight:600">${r}</span> ${i}</span>
1069
- <span class="tl-event-dur">${qi(e.durationMs)}</span>
1070
- `}case "log":{let e=t.data,r=As[e.level]||"var(--text-dim)";return a`<span class="tl-event-summary"><span style="color:${r}">${e.level.toUpperCase()}</span> ${e.message}</span>`}case "error":{let e=t.data;return a`<span class="tl-event-summary" style="color:var(--red)">${e.name}: ${e.message}</span>`}default:return p}}};N.cache=new Map,u([I({context:A})],N.prototype,"store",2),u([L({attribute:"request-id"})],N.prototype,"requestId",2),u([L({attribute:"request-started",type:Number})],N.prototype,"requestStarted",2),u([b()],N.prototype,"data",2),u([b()],N.prototype,"loading",2),u([b()],N.prototype,"failed",2),u([b()],N.prototype,"expandedSqlIdx",2),N=u([S("bk-timeline-panel")],N);function Lt(o){try{return JSON.parse(o)}catch{return null}}var Ee=class{constructor(s,t){this.host=s;this.store=t;this.retryCount=0;this.boundHandlers={fetch:s=>{let t=Lt(s.data);t&&this.store.prependFetch(t);},log:s=>{let t=Lt(s.data);t&&this.store.prependLog(t);},error:s=>{let t=Lt(s.data);t&&this.store.prependError(t);},query:s=>{let t=Lt(s.data);t&&this.store.prependQuery(t);},issues:s=>{let t=Lt(s.data);t&&this.store.setIssues(t);}};s.addController(this);}hostConnected(){this.connect();}hostDisconnected(){this.removeListeners(),this.eventSource?.close(),clearTimeout(this.reloadTimer),clearTimeout(this.perfReloadTimer),clearTimeout(this.reconnectTimer);}removeListeners(){this.eventSource&&(this.eventSource.removeEventListener(ie,this.boundHandlers.fetch),this.eventSource.removeEventListener("log",this.boundHandlers.log),this.eventSource.removeEventListener(oe,this.boundHandlers.error),this.eventSource.removeEventListener(ne,this.boundHandlers.query),this.eventSource.removeEventListener(ae,this.boundHandlers.issues));}connect(){this.removeListeners(),this.eventSource?.close(),this.eventSource=new EventSource(w.events),this.eventSource.onopen=()=>{this.retryCount=0;},this.eventSource.onerror=()=>{this.eventSource?.close(),this.scheduleReconnect();},this.eventSource.onmessage=s=>{let t=Lt(s.data);t&&(t.path?.startsWith(F)||(this.store.prependRequest(t),clearTimeout(this.reloadTimer),this.reloadTimer=setTimeout(()=>this.reloadFlows(),300),this.store.state.activeView==="performance"&&(clearTimeout(this.perfReloadTimer),this.perfReloadTimer=setTimeout(()=>this.reloadMetrics(),De))));},this.eventSource.addEventListener(ie,this.boundHandlers.fetch),this.eventSource.addEventListener("log",this.boundHandlers.log),this.eventSource.addEventListener(oe,this.boundHandlers.error),this.eventSource.addEventListener(ne,this.boundHandlers.query),this.eventSource.addEventListener(ae,this.boundHandlers.issues);}scheduleReconnect(){if(this.retryCount>=10)return;let s=Math.min(1e3*2**this.retryCount,3e4);this.retryCount++,this.reconnectTimer=setTimeout(()=>this.connect(),s);}async reloadFlows(){try{let t=await(await fetch(w.flows)).json();this.store.setFlows(t.flows);}catch{}}async reloadMetrics(){try{let t=await(await fetch(w.metricsLive)).json();this.store.setMetrics(t.endpoints||[]);}catch{}}};function vr(){return a`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>`}function gr(){return a`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>`}function br(){return a`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>`}function Er(){return a`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg>`}function yr(){return a`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/></svg>`}function _r(){return a`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>`}function $r(){return a`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>`}function xr(){return a`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>`}function Sr(){return a`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg>`}function Tr(){return a`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="3"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="18" r="3"/><line x1="9" y1="6" x2="15" y2="6"/><line x1="6" y1="9" x2="6" y2="15"/><line x1="18" y1="9" x2="18" y2="15"/><line x1="9" y1="18" x2="15" y2="18"/></svg>`}var dt=class extends E{constructor(){super(...arguments);this.store=new ue;this.activeView="overview";this.viewMode="simple";this.sse=new Ee(this,this.store);}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.loadInitialData(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}async loadInitialData(){try{let[t,e]=await Promise.all([fetch(w.flows),fetch(w.requests)]),[r,i]=await Promise.all([t.json(),e.json()]);this.store.setFlows(r.flows),this.store.setRequests(i.requests);}catch(t){console.warn("[brakit]",t);}try{let[t,e,r,i,n]=await Promise.all([fetch(w.fetches),fetch(w.errors),fetch(w.logs),fetch(w.queries),fetch(w.metricsLive)]),[l,c,d,h,m]=await Promise.all([t.json(),e.json(),r.json(),i.json(),n.json()]);this.store.setFetches(l.entries),this.store.setErrors(c.entries),this.store.setLogs(d.entries),this.store.setQueries(h.entries),this.store.setMetrics(m.endpoints||[]);}catch(t){console.warn("[brakit]",t);}try{let e=await(await fetch(w.insights)).json();this.store.setIssues(e.issues||[]);}catch(t){console.warn("[brakit]",t);}}switchView(t){t!==this.activeView&&(this.activeView=t,this.store.setActiveView(t),fetch(`${w.tab}?tab=${encodeURIComponent(t)}`).catch(()=>{}),t==="performance"&&this.sse.reloadMetrics());}async handleClear(){confirm("This will clear all data including performance metrics history. Continue?")&&(await fetch(w.clear,{method:"POST"}),this.store.clearAll(),D.show("Cleared"));}handleCopyAsCurl(t){Tt(t);}render(){let t=this.store.state,e=t.requests.filter(c=>!c.path?.startsWith(F)),r=e.filter(c=>c.statusCode>=400).length,i=e.length>0?Math.round(e.reduce((c,d)=>c+d.durationMs,0)/e.length):0,n=(t.issues||[]).filter(c=>c.state!=="resolved"&&c.state!=="stale").length,l=window.__BRAKIT_CONFIG__;return a`
1146
+ <span class="tl-event-status" style="${s?"color:var(--red)":""}">${e.statusCode}</span>
1147
+ <span class="tl-event-dur">${y(e.durationMs)}</span>
1148
+ `}case "query":{let e=t.data,s=(e.normalizedOp||e.operation||"?").toUpperCase(),i=e.table||e.model||"",n=be[s]||"var(--text-dim)";return l`
1149
+ <span class="tl-event-summary"><span style="color:${n};font-weight:600">${s}</span> ${i}</span>
1150
+ <span class="tl-event-dur">${Ki(e.durationMs)}</span>
1151
+ `}case "log":{let e=t.data,s=qs[e.level]||"var(--text-dim)";return l`<span class="tl-event-summary"><span style="color:${s}">${e.level.toUpperCase()}</span> ${e.message}</span>`}case "error":{let e=t.data;return l`<span class="tl-event-summary" style="color:var(--red)">${e.name}: ${e.message}</span>`}default:return d}}};k.cache=new Map,u([C({context:A})],k.prototype,"store",2),u([L({attribute:"request-id"})],k.prototype,"requestId",2),u([L({attribute:"request-started",type:Number})],k.prototype,"requestStarted",2),u([b()],k.prototype,"data",2),u([b()],k.prototype,"loading",2),u([b()],k.prototype,"failed",2),u([b()],k.prototype,"expandedSqlIdx",2),k=u([_("bk-timeline-panel")],k);function Dt(o){try{return JSON.parse(o)}catch{return null}}var Re=class{constructor(r,t){this.host=r;this.store=t;this.retryCount=0;this.boundHandlers={fetch:r=>{let t=Dt(r.data);t&&this.store.prependFetch(t);},log:r=>{let t=Dt(r.data);t&&this.store.prependLog(t);},error:r=>{let t=Dt(r.data);t&&this.store.prependError(t);},query:r=>{let t=Dt(r.data);t&&this.store.prependQuery(t);},issues:r=>{let t=Dt(r.data);t&&this.store.setIssues(t);}};r.addController(this);}hostConnected(){this.connect();}hostDisconnected(){this.removeListeners(),this.eventSource?.close(),clearTimeout(this.reloadTimer),clearTimeout(this.perfReloadTimer),clearTimeout(this.reconnectTimer);}removeListeners(){this.eventSource&&(this.eventSource.removeEventListener(he,this.boundHandlers.fetch),this.eventSource.removeEventListener("log",this.boundHandlers.log),this.eventSource.removeEventListener(ue,this.boundHandlers.error),this.eventSource.removeEventListener(me,this.boundHandlers.query),this.eventSource.removeEventListener(fe,this.boundHandlers.issues));}connect(){this.removeListeners(),this.eventSource?.close(),this.eventSource=new EventSource(T.events),this.eventSource.onopen=()=>{this.retryCount=0;},this.eventSource.onerror=()=>{this.eventSource?.close(),this.scheduleReconnect();},this.eventSource.onmessage=r=>{let t=Dt(r.data);t&&(t.path?.startsWith(U)||(this.store.prependRequest(t),clearTimeout(this.reloadTimer),this.reloadTimer=setTimeout(()=>this.reloadFlows(),300),this.store.state.activeView==="performance"&&(clearTimeout(this.perfReloadTimer),this.perfReloadTimer=setTimeout(()=>this.reloadMetrics(),je))));},this.eventSource.addEventListener(he,this.boundHandlers.fetch),this.eventSource.addEventListener("log",this.boundHandlers.log),this.eventSource.addEventListener(ue,this.boundHandlers.error),this.eventSource.addEventListener(me,this.boundHandlers.query),this.eventSource.addEventListener(fe,this.boundHandlers.issues);}scheduleReconnect(){if(this.retryCount>=10)return;let r=Math.min(1e3*2**this.retryCount,3e4);this.retryCount++,this.reconnectTimer=setTimeout(()=>this.connect(),r);}async reloadFlows(){try{let t=await(await fetch(T.flows)).json();this.store.setFlows(t.flows);}catch{}}async reloadMetrics(){try{let t=await(await fetch(T.metricsLive)).json();this.store.setMetrics(t.endpoints||[]);}catch{}}};function Ar(){return l`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>`}function Cr(){return l`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>`}function Ir(){return l`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg>`}function Lr(){return l`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18h6"/><path d="M10 22h4"/><path d="M12 2a7 7 0 0 0-4 12.7V17h8v-2.3A7 7 0 0 0 12 2z"/></svg>`}function Mr(){return l`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>`}function kr(){return l`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="3"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="18" r="3"/><line x1="9" y1="6" x2="15" y2="6"/><line x1="6" y1="9" x2="6" y2="15"/><line x1="18" y1="9" x2="18" y2="15"/><line x1="9" y1="18" x2="15" y2="18"/></svg>`}var ft=class extends E{constructor(){super(...arguments);this.store=new ye;this.activeView="overview";this.viewMode="simple";this.sse=new Re(this,this.store);this.handleStateChanged=t=>{t.detail==="activeView"&&(this.activeView=this.store.state.activeView),this.requestUpdate();};}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.loadInitialData(),this.store.addEventListener("state-changed",this.handleStateChanged);}disconnectedCallback(){super.disconnectedCallback(),this.store.removeEventListener("state-changed",this.handleStateChanged);}async loadInitialData(){try{let[t,e]=await Promise.all([j(T.flows),j(T.requests)]);this.store.setFlows(t.flows),this.store.setRequests(e.requests);}catch(t){console.warn("[brakit]",t);}try{let[t,e,s,i,n]=await Promise.all([j(T.fetches),j(T.errors),j(T.logs),j(T.queries),j(T.metricsLive)]);this.store.setFetches(t.entries),this.store.setErrors(e.entries),this.store.setLogs(s.entries),this.store.setQueries(i.entries),this.store.setMetrics(n.endpoints||[]);}catch(t){console.warn("[brakit]",t);}try{let t=await j(T.insights);this.store.setIssues(t.issues||[]);}catch(t){console.warn("[brakit]",t);}}switchView(t){t!==this.activeView&&(this.activeView=t,this.store.setActiveView(t),fetch(`${T.tab}?tab=${encodeURIComponent(t)}`).catch(()=>{}),t==="performance"&&this.sse.reloadMetrics());}async handleClear(){confirm(N.CLEAR_CONFIRM)&&(await fetch(T.clear,{method:"POST"}),this.store.clearAll(),D.show(N.CLEARED_TOAST));}handleCopyAsCurl(t){Lt(t);}render(){let t=this.store.state,e=t.requests.filter(c=>!c.path?.startsWith(U)),s=e.filter(c=>c.statusCode>=400).length,i=e.length>0?Math.round(e.reduce((c,p)=>c+p.durationMs,0)/e.length):0,n=(t.issues||[]).filter(_e).length,a=window.__BRAKIT_CONFIG__;return l`
1071
1152
  <div class="app" id="app">
1072
1153
  <aside class="sidebar">
1073
1154
  <div class="sidebar-logo">
1074
1155
  <span class="logo-text">brakit</span>
1075
- <span class="logo-version">v${l?.version??""}</span>
1156
+ <span class="logo-version">v${a?.version??""}</span>
1076
1157
  </div>
1077
1158
  <nav class="sidebar-nav">
1078
- ${this.renderSidebarItem("overview","Overview",vr(),void 0)}
1079
- <div class="sidebar-section">Monitor</div>
1080
- ${this.renderSidebarItem("actions","Actions",gr(),t.flows.length)}
1081
- ${this.renderSidebarItem("requests","Requests",br(),e.length)}
1082
- ${this.renderSidebarItem("fetches","Fetches",Er(),t.fetches.length)}
1083
- <div class="sidebar-section">Insights</div>
1084
- ${this.renderSidebarItem("queries","Queries",yr(),t.queries.length)}
1085
- ${this.renderSidebarItem("errors","Errors",_r(),t.errors.length)}
1086
- ${this.renderSidebarItem("logs","Logs",$r(),t.logs.length)}
1087
- ${this.renderSidebarItem("security","Security",xr(),n,n===0)}
1088
- ${this.renderSidebarItem("performance","Performance",Sr(),void 0)}
1089
- <div class="sidebar-section">Topology</div>
1090
- <button class="sidebar-item ${this.activeView==="graph"?"active":""}" @click=${()=>this.switchView("graph")}>
1091
- <span class="item-icon">${Tr()}</span>
1092
- <span class="item-label">Graph</span>
1093
- <span class="sidebar-beta">beta</span>
1094
- </button>
1159
+ ${this.renderSidebarItem("overview","Overview",Ar(),void 0)}
1160
+ ${this.renderSidebarItem("actions","Actions",Cr(),t.flows.length)}
1161
+ ${this.renderSidebarItem("insights","Insights",Lr(),n,n===0)}
1162
+ ${this.renderSidebarItem("performance","Performance",Ir(),void 0)}
1163
+ ${this.renderSidebarItem("graph","Graph",kr(),void 0)}
1164
+ <div class="sidebar-divider"></div>
1165
+ ${this.renderSidebarItem("explorer","Explorer",Mr(),e.length+t.fetches.length+t.queries.length+t.logs.length+t.errors.length)}
1095
1166
  </nav>
1096
- <div class="sidebar-footer">:${l?.port??""}</div>
1167
+ <div class="sidebar-footer">:${a?.port??""}</div>
1097
1168
  </aside>
1098
1169
  <div class="main-panel">
1099
1170
  <div class="header">
1100
1171
  <div class="header-left">
1101
- <span class="header-title" id="header-title">${Ie[this.activeView]||this.activeView}</span>
1102
- <span class="header-sub" id="header-sub">${Ce[this.activeView]||""}</span>
1172
+ <span class="header-title" id="header-title">${Pe[this.activeView]||this.activeView}</span>
1173
+ <span class="header-sub" id="header-sub">${He[this.activeView]||""}</span>
1103
1174
  </div>
1104
1175
  <div class="header-right">
1105
- ${this.activeView==="actions"?a`
1176
+ ${this.activeView==="actions"?l`
1106
1177
  <div class="segmented-control" id="mode-toggle">
1107
1178
  <button class="segmented-btn ${this.viewMode==="simple"?"active":""}" @click=${()=>{this.viewMode="simple",this.store.setViewMode("simple");}}>Quick</button>
1108
1179
  <button class="segmented-btn ${this.viewMode==="detailed"?"active":""}" @click=${()=>{this.viewMode="detailed",this.store.setViewMode("detailed");}}>Detailed</button>
1109
1180
  </div>
1110
- `:p}
1181
+ `:d}
1111
1182
  <button class="btn btn-danger" @click=${this.handleClear}>Clear</button>
1112
1183
  </div>
1113
1184
  </div>
1114
1185
  <div class="main-content">
1115
- <div id="overview-container" style="display:${this.activeView==="overview"?"block":"none"}">
1186
+ <div style="display:${this.activeView==="overview"?"block":"none"}">
1116
1187
  <bk-overview-view></bk-overview-view>
1117
1188
  </div>
1118
- <div class="view-flows" id="flow-container" style="display:${this.activeView==="actions"?"block":"none"}">
1189
+ <div style="display:${this.activeView==="actions"?"block":"none"}">
1119
1190
  <bk-flows-view></bk-flows-view>
1120
1191
  </div>
1121
- <div class="view-requests" id="request-container" style="display:${this.activeView==="requests"?"block":"none"}">
1122
- <bk-requests-view></bk-requests-view>
1123
- </div>
1124
- <div class="view-telemetry" id="fetch-container" style="display:${this.activeView==="fetches"?"block":"none"}">
1125
- <bk-fetches-view></bk-fetches-view>
1192
+ <div style="display:${this.activeView==="insights"?"block":"none"}">
1193
+ <bk-insights-view></bk-insights-view>
1126
1194
  </div>
1127
- <div class="view-telemetry" id="query-container" style="display:${this.activeView==="queries"?"block":"none"}">
1128
- <bk-queries-view></bk-queries-view>
1129
- </div>
1130
- <div class="view-telemetry" id="error-container" style="display:${this.activeView==="errors"?"block":"none"}">
1131
- <bk-errors-view></bk-errors-view>
1132
- </div>
1133
- <div class="view-telemetry" id="log-container" style="display:${this.activeView==="logs"?"block":"none"}">
1134
- <bk-logs-view></bk-logs-view>
1135
- </div>
1136
- <div class="view-telemetry" id="security-container" style="display:${this.activeView==="security"?"block":"none"}">
1137
- <bk-security-view></bk-security-view>
1138
- </div>
1139
- <div class="view-telemetry" id="performance-container" style="display:${this.activeView==="performance"?"block":"none"}">
1195
+ <div style="display:${this.activeView==="performance"?"block":"none"}">
1140
1196
  <bk-performance-view></bk-performance-view>
1141
1197
  </div>
1142
- <div class="view-telemetry" id="graph-container" style="display:${this.activeView==="graph"?"block":"none"}">
1198
+ <div style="display:${this.activeView==="graph"?"block":"none"}">
1143
1199
  <bk-graph-view></bk-graph-view>
1144
1200
  </div>
1201
+ <div style="display:${this.activeView==="explorer"?"block":"none"}">
1202
+ <bk-explorer-view></bk-explorer-view>
1203
+ </div>
1145
1204
  </div>
1146
1205
  <div class="footer">
1147
- <span id="stat-total">${e.length} request${e.length!==1?"s":""}</span>
1148
- <span id="stat-flows">${t.flows.length} action${t.flows.length!==1?"s":""}</span>
1149
- <span id="stat-errors" class="error-count">${r} error${r!==1?"s":""}</span>
1206
+ <span id="stat-total">${e.length} ${B(e.length,"request")}</span>
1207
+ <span id="stat-flows">${t.flows.length} ${B(t.flows.length,"action")}</span>
1208
+ <span id="stat-errors" class="error-count">${s} ${B(s,"error")}</span>
1150
1209
  <span id="stat-avg">Avg: ${i}ms</span>
1151
1210
  </div>
1152
1211
  </div>
1153
1212
  </div>
1154
1213
  <bk-toast></bk-toast>
1155
- `}renderSidebarItem(t,e,r,i,n=false){return a`
1214
+ `}renderSidebarItem(t,e,s,i,n=false){return l`
1156
1215
  <button class="sidebar-item ${this.activeView===t?"active":""}" @click=${()=>this.switchView(t)}>
1157
- <span class="item-icon">${r}</span>
1216
+ <span class="item-icon">${s}</span>
1158
1217
  <span class="item-label">${e}</span>
1159
- ${i!==void 0?a`<span class="item-count" style="display:${n?"none":""}">${i}</span>`:p}
1218
+ ${i!==void 0?l`<span class="item-count" style="display:${n?"none":""}">${i}</span>`:d}
1160
1219
  </button>
1161
- `}};u([Be({context:A})],dt.prototype,"store",2),u([b()],dt.prototype,"activeView",2),u([b()],dt.prototype,"viewMode",2),dt=u([S("bk-dashboard")],dt);
1220
+ `}};u([Je({context:A})],ft.prototype,"store",2),u([b()],ft.prototype,"activeView",2),u([b()],ft.prototype,"viewMode",2),ft=u([_("bk-dashboard")],ft);
1162
1221
  /*! Bundled license information:
1163
1222
 
1164
1223
  @lit/reactive-element/css-tag.js: