🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

ghostbug

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ghostbug - npm Package Compare versions

Comparing version
0.1.0
to
0.2.0-beta.0
+14
-4
dist/index.cjs

@@ -1,3 +0,3 @@

'use strict';Object.defineProperty(exports,'__esModule',{value:true});var f="0.1.0",N={maxReports:50,maxBreadcrumbs:20,maxClicks:20,widget:false,collectors:{errors:true,console:true,network:true,clicks:true},rateLimit:{maxEvents:10,windowMs:1e3},beforeReport:e=>e,debug:false};var b=class{constructor(){this.listeners=new Map;}on(t,o){return this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(o),()=>this.off(t,o)}off(t,o){this.listeners.get(t)?.delete(o);}emit(t,o){this.listeners.get(t)?.forEach(r=>{try{r(o);}catch{}});}clear(){this.listeners.clear();}};var h=class{constructor(t){this.capacity=t;this.head=0;this._size=0;this.buffer=new Array(t);}push(t){this.buffer[this.head]=t,this.head=(this.head+1)%this.capacity,this._size<this.capacity&&this._size++;}toArray(){if(this._size===0)return [];let t=[],o=this._size<this.capacity?0:this.head;for(let r=0;r<this._size;r++){let n=(o+r)%this.capacity;t.push(this.buffer[n]);}return t}get size(){return this._size}get isFull(){return this._size===this.capacity}peek(){if(this._size===0)return;let t=(this.head-1+this.capacity)%this.capacity;return this.buffer[t]}find(t){return this.toArray().find(t)}forEach(t){this.toArray().forEach(t);}clear(){this.buffer=new Array(this.capacity),this.head=0,this._size=0;}};var y=class{constructor(t,o){this.maxEvents=t;this.windowMs=o;this.timestamps=[];}allow(){let t=Date.now();return this.timestamps=this.timestamps.filter(o=>t-o<this.windowMs),this.timestamps.length>=this.maxEvents?false:(this.timestamps.push(t),true)}reset(){this.timestamps=[];}};function _(e){let t=5381;for(let o=0;o<e.length;o++)t=(t<<5)+t+e.charCodeAt(o)&4294967295;return (t>>>0).toString(36)}function P(e){let t;switch(e.kind){case "error":{let o=e.stack?.split(`
`)[1]?.trim()||"";t=`${e.name}:${e.message}:${o}`;break}case "console":t=`console:${e.level}:${e.args.join(",")}`;break;case "network":t=`network:${e.method}:${e.url}:${e.status}`;break}return _(t)}function M(){let e=new Uint8Array(8);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(36).padStart(2,"0")).join("").slice(0,12)}var v=class{constructor(t,o,r){this.eventBus=t;this.contextCollector=o;this.options=r;this.unsubscribers=[];this.reports=new h(r.maxReports),this.breadcrumbs=new h(r.maxBreadcrumbs),this.rateLimiter=new y(r.rateLimit.maxEvents,r.rateLimit.windowMs),this.subscribe();}subscribe(){this.unsubscribers.push(this.eventBus.on("error:captured",t=>{this.addBreadcrumb({category:"error",message:t.message}),this.handleCapturedEvent("error",t);}),this.eventBus.on("console:captured",t=>{this.addBreadcrumb({category:"console",message:`console.${t.level}: ${t.args.join(", ")}`}),t.level==="error"&&this.handleCapturedEvent("console",t);}),this.eventBus.on("network:captured",t=>{this.handleCapturedEvent("network",t);}),this.eventBus.on("breadcrumb:added",t=>{this.addBreadcrumb(t);}));}handleCapturedEvent(t,o){if(!this.rateLimiter.allow())return;let r=P(o),n=this.reports.find(l=>l.fingerprint===r);if(n){n.count++,n.timestamp=new Date().toISOString(),this.eventBus.emit("report:deduplicated",n);return}let s={id:M(),fingerprint:r,type:t,timestamp:new Date().toISOString(),count:1,payload:o,breadcrumbs:this.breadcrumbs.toArray(),context:this.contextCollector.snapshot()},i=this.options.beforeReport(s);i&&(s=i,this.reports.push(s),this.eventBus.emit("report:created",s));}addBreadcrumb(t){this.breadcrumbs.push({...t,timestamp:new Date().toISOString()});}getReports(){return this.reports.toArray()}clear(){this.reports.clear(),this.breadcrumbs.clear(),this.unsubscribers.forEach(t=>t()),this.unsubscribers=[];}get reportCount(){return this.reports.size}};var w=class{constructor(t){this.eventBus=t;this.name="error";this.originalOnError=null;this.rejectionHandler=null;}setup(){this.originalOnError=window.onerror,window.onerror=(t,o,r,n,s)=>{let i={kind:"error",message:String(t),stack:s?.stack,filename:o??void 0,lineno:r??void 0,colno:n??void 0,name:s?.name};return this.eventBus.emit("error:captured",i),this.originalOnError?this.originalOnError.call(window,t,o,r,n,s):false},this.rejectionHandler=t=>{let o=t.reason,r={kind:"error",message:o instanceof Error?o.message:String(o),stack:o instanceof Error?o.stack:void 0,name:o instanceof Error?o.name:"UnhandledRejection"};this.eventBus.emit("error:captured",r);},window.addEventListener("unhandledrejection",this.rejectionHandler);}teardown(){window.onerror=this.originalOnError,this.originalOnError=null,this.rejectionHandler&&(window.removeEventListener("unhandledrejection",this.rejectionHandler),this.rejectionHandler=null);}};function g(e,t){let o=new WeakSet;return JSON.stringify(e,(r,n)=>{if(typeof n=="object"&&n!==null){if(o.has(n))return "[Circular]";o.add(n);}return typeof n=="function"?"[Function]":typeof n=="symbol"?n.toString():n instanceof Error?{name:n.name,message:n.message,stack:n.stack}:n},t)}var x=class{constructor(t){this.eventBus=t;this.name="console";this.originalError=null;this.originalWarn=null;}setup(){this.originalError=console.error,this.originalWarn=console.warn,console.error=(...t)=>{let o={kind:"console",level:"error",args:t.map(r=>g(r))};this.eventBus.emit("console:captured",o),this.originalError.apply(console,t);},console.warn=(...t)=>{let o={kind:"console",level:"warn",args:t.map(r=>g(r))};this.eventBus.emit("console:captured",o),this.originalWarn.apply(console,t);};}teardown(){this.originalError&&(console.error=this.originalError),this.originalWarn&&(console.warn=this.originalWarn),this.originalError=null,this.originalWarn=null;}};var E=class{constructor(t){this.eventBus=t;this.name="network";this.originalFetch=null;this.originalXhrOpen=null;this.originalXhrSend=null;}setup(){this.patchFetch(),this.patchXHR();}patchFetch(){this.originalFetch=window.fetch;let t=this.eventBus,o=this.originalFetch;window.fetch=function(r,n){let s=n?.method?.toUpperCase()||"GET",i=typeof r=="string"?r:r instanceof URL?r.href:r.url,l=performance.now();return o.call(window,r,n).then(a=>{let c=Math.round(performance.now()-l);if(a.status>=400){let d={kind:"network",method:s,url:i,status:a.status,statusText:a.statusText,duration:c};t.emit("network:captured",d);}return t.emit("breadcrumb:added",{category:"network",message:`${s} ${i} -> ${a.status}`}),a},a=>{let c=Math.round(performance.now()-l),d={kind:"network",method:s,url:i,status:0,statusText:a.message||"Network Error",duration:c};throw t.emit("network:captured",d),a})};}patchXHR(){this.originalXhrOpen=XMLHttpRequest.prototype.open,this.originalXhrSend=XMLHttpRequest.prototype.send;let t=this.eventBus,o=this.originalXhrOpen,r=this.originalXhrSend;XMLHttpRequest.prototype.open=function(n,s,...i){return this.__ghostbug_method=n.toUpperCase(),this.__ghostbug_url=String(s),o.apply(this,[n,s,...i])},XMLHttpRequest.prototype.send=function(n){let s=performance.now(),i=this;return i.addEventListener("loadend",function(){let l=Math.round(performance.now()-s),a=i.__ghostbug_method||"UNKNOWN",c=i.__ghostbug_url||"";if(i.status>=400||i.status===0){let d={kind:"network",method:a,url:c,status:i.status,statusText:i.statusText,duration:l};t.emit("network:captured",d);}t.emit("breadcrumb:added",{category:"network",message:`${a} ${c} -> ${i.status}`});}),r.call(this,n)};}teardown(){this.originalFetch&&(window.fetch=this.originalFetch,this.originalFetch=null),this.originalXhrOpen&&(XMLHttpRequest.prototype.open=this.originalXhrOpen,this.originalXhrOpen=null),this.originalXhrSend&&(XMLHttpRequest.prototype.send=this.originalXhrSend,this.originalXhrSend=null);}};function H(e){if(e.id)return `#${e.id}`;let t=e.getAttribute("data-testid");if(t)return `[data-testid="${t}"]`;let o=[],r=e,n=0;for(;r&&r!==document.documentElement&&n<5;){let s=r.tagName.toLowerCase();if(r.id){o.unshift(`#${r.id}`);break}let i=Array.from(r.classList).slice(0,2);i.length>0&&(s+="."+i.join("."));let l=r.parentElement;if(l){let a=r.tagName,c=Array.from(l.children).filter(d=>d.tagName===a);if(c.length>1){let d=c.indexOf(r)+1;s+=`:nth-child(${d})`;}}o.unshift(s),r=l,n++;}return o.join(" > ")}var k=class{constructor(t,o){this.eventBus=t;this.name="click";this.handler=null;this.clicks=new h(o);}setup(){this.handler=t=>{let o=t.target;if(!o)return;let r={timestamp:new Date().toISOString(),selector:H(o),tagName:o.tagName.toLowerCase(),text:(o.textContent||"").trim().slice(0,100),position:{x:t.clientX,y:t.clientY}};this.clicks.push(r),this.eventBus.emit("click:captured",r),this.eventBus.emit("breadcrumb:added",{category:"click",message:`Clicked ${r.tagName} "${r.text}"`,data:{selector:r.selector}});},document.addEventListener("click",this.handler,true);}getClickTrail(){return this.clicks.toArray()}teardown(){this.handler&&(document.removeEventListener("click",this.handler,true),this.handler=null),this.clicks.clear();}};var C=class{constructor(){this.name="context";}setup(){}teardown(){}snapshot(){return {url:window.location.href,referrer:document.referrer,userAgent:navigator.userAgent,language:navigator.language,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:window.screen.width,height:window.screen.height},devicePixelRatio:window.devicePixelRatio||1,timestamp:new Date().toISOString(),memory:performance.memory?{usedJSHeapSize:performance.memory.usedJSHeapSize,totalJSHeapSize:performance.memory.totalJSHeapSize}:void 0}}};var z=`
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var f="0.1.0",_={maxReports:50,maxBreadcrumbs:20,maxClicks:20,widget:false,collectors:{errors:true,console:true,network:true,clicks:true,interactions:true,performance:true,memory:true},rateLimit:{maxEvents:10,windowMs:1e3},beforeReport:r=>r,debug:false};var b=class{constructor(){this.listeners=new Map;}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>this.off(e,t)}off(e,t){this.listeners.get(e)?.delete(t);}emit(e,t){this.listeners.get(e)?.forEach(o=>{try{o(t);}catch{}});}clear(){this.listeners.clear();}};var m=class{constructor(e){this.capacity=e;this.head=0;this._size=0;this.buffer=new Array(e);}push(e){this.buffer[this.head]=e,this.head=(this.head+1)%this.capacity,this._size<this.capacity&&this._size++;}toArray(){if(this._size===0)return [];let e=[],t=this._size<this.capacity?0:this.head;for(let o=0;o<this._size;o++){let n=(t+o)%this.capacity;e.push(this.buffer[n]);}return e}get size(){return this._size}get isFull(){return this._size===this.capacity}peek(){if(this._size===0)return;let e=(this.head-1+this.capacity)%this.capacity;return this.buffer[e]}find(e){return this.toArray().find(e)}forEach(e){this.toArray().forEach(e);}clear(){this.buffer=new Array(this.capacity),this.head=0,this._size=0;}};var v=class{constructor(e,t){this.maxEvents=e;this.windowMs=t;this.timestamps=[];}allow(){let e=Date.now();return this.timestamps=this.timestamps.filter(t=>e-t<this.windowMs),this.timestamps.length>=this.maxEvents?false:(this.timestamps.push(e),true)}reset(){this.timestamps=[];}};function q(r){let e=5381;for(let t=0;t<r.length;t++)e=(e<<5)+e+r.charCodeAt(t)&4294967295;return (e>>>0).toString(36)}function I(r){let e;switch(r.kind){case "error":{let t=r.stack?.split(`
`)[1]?.trim()||"";e=`${r.name}:${r.message}:${t}`;break}case "console":e=`console:${r.level}:${r.args.join(",")}`;break;case "network":e=`network:${r.method}:${r.url}:${r.status}`;break;case "performance":e=`performance:${r.metric}:${Math.floor(r.value/100)*100}`;break;case "memory":e=`memory:${Math.floor(r.heapUsagePercent*10)/10}`;break}return q(e)}function A(){let r=new Uint8Array(8);return crypto.getRandomValues(r),Array.from(r,e=>e.toString(36).padStart(2,"0")).join("").slice(0,12)}var W=3e3,y=class{constructor(e,t,o){this.eventBus=e;this.contextCollector=t;this.options=o;this.unsubscribers=[];this.reports=new m(o.maxReports),this.breadcrumbs=new m(o.maxBreadcrumbs),this.rateLimiter=new v(o.rateLimit.maxEvents,o.rateLimit.windowMs),this.subscribe();}subscribe(){this.unsubscribers.push(this.eventBus.on("error:captured",e=>{this.addBreadcrumb({category:"error",message:e.message}),this.handleCapturedEvent("error",e);}),this.eventBus.on("console:captured",e=>{this.addBreadcrumb({category:"console",message:`console.${e.level}: ${e.args.join(", ")}`}),e.level==="error"&&this.handleCapturedEvent("console",e);}),this.eventBus.on("network:captured",e=>{this.handleCapturedEvent("network",e);}),this.eventBus.on("performance:captured",e=>{this.addBreadcrumb({category:"performance",message:`${e.metric}: ${e.value}ms`}),this.handleCapturedEvent("performance",e);}),this.eventBus.on("memory:captured",e=>{this.handleCapturedEvent("memory",e);}),this.eventBus.on("breadcrumb:added",e=>{this.addBreadcrumb(e);}));}async handleCapturedEvent(e,t){if(!this.rateLimiter.allow())return;let o=I(t),n=this.reports.find(l=>l.fingerprint===o);if(n){n.count++,n.timestamp=new Date().toISOString(),this.eventBus.emit("report:deduplicated",n);return}let i={id:A(),fingerprint:o,type:e,timestamp:new Date().toISOString(),count:1,payload:t,breadcrumbs:this.breadcrumbs.toArray(),context:this.contextCollector.snapshot()};if(this.options.screenshotFn)try{i.screenshot=await Promise.race([this.options.screenshotFn(),new Promise((l,a)=>setTimeout(()=>a(new Error("screenshot timeout")),W))]);}catch{}let s=this.options.beforeReport(i);s&&(i=s,this.reports.push(i),this.eventBus.emit("report:created",i));}addBreadcrumb(e){this.breadcrumbs.push({...e,timestamp:new Date().toISOString()});}getReports(){return this.reports.toArray()}clear(){this.reports.clear(),this.breadcrumbs.clear(),this.unsubscribers.forEach(e=>e()),this.unsubscribers=[];}get reportCount(){return this.reports.size}};var w=class{constructor(e){this.eventBus=e;this.name="error";this.originalOnError=null;this.rejectionHandler=null;}setup(){this.originalOnError=window.onerror,window.onerror=(e,t,o,n,i)=>{let s={kind:"error",message:String(e),stack:i?.stack,filename:t??void 0,lineno:o??void 0,colno:n??void 0,name:i?.name};return this.eventBus.emit("error:captured",s),this.originalOnError?this.originalOnError.call(window,e,t,o,n,i):false},this.rejectionHandler=e=>{let t=e.reason,o={kind:"error",message:t instanceof Error?t.message:String(t),stack:t instanceof Error?t.stack:void 0,name:t instanceof Error?t.name:"UnhandledRejection"};this.eventBus.emit("error:captured",o);},window.addEventListener("unhandledrejection",this.rejectionHandler);}teardown(){window.onerror=this.originalOnError,this.originalOnError=null,this.rejectionHandler&&(window.removeEventListener("unhandledrejection",this.rejectionHandler),this.rejectionHandler=null);}};function g(r,e){let t=new WeakSet;return JSON.stringify(r,(o,n)=>{if(typeof n=="object"&&n!==null){if(t.has(n))return "[Circular]";t.add(n);}return typeof n=="function"?"[Function]":typeof n=="symbol"?n.toString():n instanceof Error?{name:n.name,message:n.message,stack:n.stack}:n},e)}var x=class{constructor(e){this.eventBus=e;this.name="console";this.originalError=null;this.originalWarn=null;}setup(){this.originalError=console.error,this.originalWarn=console.warn,console.error=(...e)=>{let t={kind:"console",level:"error",args:e.map(o=>g(o))};this.eventBus.emit("console:captured",t),this.originalError.apply(console,e);},console.warn=(...e)=>{let t={kind:"console",level:"warn",args:e.map(o=>g(o))};this.eventBus.emit("console:captured",t),this.originalWarn.apply(console,e);};}teardown(){this.originalError&&(console.error=this.originalError),this.originalWarn&&(console.warn=this.originalWarn),this.originalError=null,this.originalWarn=null;}};var E=class{constructor(e){this.eventBus=e;this.name="network";this.originalFetch=null;this.originalXhrOpen=null;this.originalXhrSend=null;}setup(){this.patchFetch(),this.patchXHR();}patchFetch(){this.originalFetch=window.fetch;let e=this.eventBus,t=this.originalFetch;window.fetch=function(o,n){let i=n?.method?.toUpperCase()||"GET",s=typeof o=="string"?o:o instanceof URL?o.href:o.url,l=performance.now();return t.call(window,o,n).then(a=>{let p=Math.round(performance.now()-l);if(a.status>=400){let u={kind:"network",method:i,url:s,status:a.status,statusText:a.statusText,duration:p};e.emit("network:captured",u);}return e.emit("breadcrumb:added",{category:"network",message:`${i} ${s} -> ${a.status}`}),a},a=>{let p=Math.round(performance.now()-l),u={kind:"network",method:i,url:s,status:0,statusText:a.message||"Network Error",duration:p};throw e.emit("network:captured",u),a})};}patchXHR(){this.originalXhrOpen=XMLHttpRequest.prototype.open,this.originalXhrSend=XMLHttpRequest.prototype.send;let e=this.eventBus,t=this.originalXhrOpen,o=this.originalXhrSend;XMLHttpRequest.prototype.open=function(n,i,...s){return this.__ghostbug_method=n.toUpperCase(),this.__ghostbug_url=String(i),t.apply(this,[n,i,...s])},XMLHttpRequest.prototype.send=function(n){let i=performance.now(),s=this;return s.addEventListener("loadend",function(){let l=Math.round(performance.now()-i),a=s.__ghostbug_method||"UNKNOWN",p=s.__ghostbug_url||"";if(s.status>=400||s.status===0){let u={kind:"network",method:a,url:p,status:s.status,statusText:s.statusText,duration:l};e.emit("network:captured",u);}e.emit("breadcrumb:added",{category:"network",message:`${a} ${p} -> ${s.status}`});}),o.call(this,n)};}teardown(){this.originalFetch&&(window.fetch=this.originalFetch,this.originalFetch=null),this.originalXhrOpen&&(XMLHttpRequest.prototype.open=this.originalXhrOpen,this.originalXhrOpen=null),this.originalXhrSend&&(XMLHttpRequest.prototype.send=this.originalXhrSend,this.originalXhrSend=null);}};function F(r){if(r.id)return `#${r.id}`;let e=r.getAttribute("data-testid");if(e)return `[data-testid="${e}"]`;let t=[],o=r,n=0;for(;o&&o!==document.documentElement&&n<5;){let i=o.tagName.toLowerCase();if(o.id){t.unshift(`#${o.id}`);break}let s=Array.from(o.classList).slice(0,2);s.length>0&&(i+="."+s.join("."));let l=o.parentElement;if(l){let a=o.tagName,p=Array.from(l.children).filter(u=>u.tagName===a);if(p.length>1){let u=p.indexOf(o)+1;i+=`:nth-child(${u})`;}}t.unshift(i),o=l,n++;}return t.join(" > ")}var k=class{constructor(e,t){this.eventBus=e;this.name="click";this.handler=null;this.clicks=new m(t);}setup(){this.handler=e=>{let t=e.target;if(!t)return;let o={timestamp:new Date().toISOString(),selector:F(t),tagName:t.tagName.toLowerCase(),text:(t.textContent||"").trim().slice(0,100),position:{x:e.clientX,y:e.clientY}};this.clicks.push(o),this.eventBus.emit("click:captured",o),this.eventBus.emit("breadcrumb:added",{category:"click",message:`Clicked ${o.tagName} "${o.text}"`,data:{selector:o.selector}});},document.addEventListener("click",this.handler,true);}getClickTrail(){return this.clicks.toArray()}teardown(){this.handler&&(document.removeEventListener("click",this.handler,true),this.handler=null),this.clicks.clear();}};var C=class{constructor(e){this.getMeta=e;this.name="context";}setup(){}teardown(){}snapshot(){let e=this.getMeta?.();return {url:window.location.href,referrer:document.referrer,userAgent:navigator.userAgent,language:navigator.language,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:window.screen.width,height:window.screen.height},devicePixelRatio:window.devicePixelRatio||1,timestamp:new Date().toISOString(),memory:performance.memory?{usedJSHeapSize:performance.memory.usedJSHeapSize,totalJSHeapSize:performance.memory.totalJSHeapSize}:void 0,user:e?.user,tags:e?.tags}}};var S=class{constructor(e){this.eventBus=e;this.name="interactions";this.handlers=[];this.scrollTimer=null;this.resizeTimer=null;}setup(){this.addHandler(window,"scroll",this.onScroll.bind(this),{passive:true,capture:true}),this.addHandler(document,"input",this.onInput.bind(this),true),this.addHandler(document,"change",this.onChange.bind(this),true),this.addHandler(window,"popstate",this.onPopState.bind(this)),this.addHandler(window,"hashchange",this.onHashChange.bind(this)),this.addHandler(document,"visibilitychange",this.onVisibilityChange.bind(this)),this.addHandler(window,"resize",this.onResize.bind(this),{passive:true});}addHandler(e,t,o,n){e.addEventListener(t,o,n),this.handlers.push({target:e,event:t,handler:o});}onScroll(){this.scrollTimer&&clearTimeout(this.scrollTimer),this.scrollTimer=setTimeout(()=>{this.eventBus.emit("breadcrumb:added",{category:"interaction",message:"Scrolled",data:{x:window.scrollX,y:window.scrollY}});},300);}onInput(e){let t=e.target;if(!t)return;let o=t.tagName.toLowerCase(),n=t.id?`#${t.id}`:"",i=t.type?`[type="${t.type}"]`:"";this.eventBus.emit("breadcrumb:added",{category:"interaction",message:`Input on ${o}${n}${i}`});}onChange(e){let t=e.target;if(!t)return;let o=t.tagName.toLowerCase(),n=t.id?`#${t.id}`:"";this.eventBus.emit("breadcrumb:added",{category:"interaction",message:`Change on ${o}${n}`});}onPopState(){this.eventBus.emit("breadcrumb:added",{category:"navigation",message:`Navigated to ${window.location.href}`});}onHashChange(){this.eventBus.emit("breadcrumb:added",{category:"navigation",message:`Hash changed to ${window.location.hash}`});}onVisibilityChange(){this.eventBus.emit("breadcrumb:added",{category:"visibility",message:document.hidden?"Tab hidden":"Tab visible"});}onResize(){this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=setTimeout(()=>{this.eventBus.emit("breadcrumb:added",{category:"interaction",message:"Window resized",data:{width:window.innerWidth,height:window.innerHeight}});},300);}teardown(){this.scrollTimer&&clearTimeout(this.scrollTimer),this.resizeTimer&&clearTimeout(this.resizeTimer),this.handlers.forEach(({target:e,event:t,handler:o})=>{e.removeEventListener(t,o);}),this.handlers=[];}};var B=class{constructor(e){this.eventBus=e;this.name="performance";this.observers=[];}setup(){typeof PerformanceObserver>"u"||(this.observe("longtask",e=>{e.forEach(t=>{if(t.duration<50)return;let o={kind:"performance",metric:"longtask",value:Math.round(t.duration),entries:[{name:t.name,duration:t.duration,startTime:t.startTime}]};this.eventBus.emit("performance:captured",o),this.eventBus.emit("breadcrumb:added",{category:"performance",message:`Long task: ${Math.round(t.duration)}ms`});});}),this.observe("largest-contentful-paint",e=>{let t=e[e.length-1];t&&this.eventBus.emit("breadcrumb:added",{category:"performance",message:`LCP: ${Math.round(t.startTime)}ms`,data:{value:t.startTime}});}),this.observe("paint",e=>{e.forEach(t=>{t.name==="first-contentful-paint"&&this.eventBus.emit("breadcrumb:added",{category:"performance",message:`FCP: ${Math.round(t.startTime)}ms`,data:{value:t.startTime}});});}),this.observe("layout-shift",e=>{e.forEach(t=>{let o=t.value;o>.1&&this.eventBus.emit("breadcrumb:added",{category:"performance",message:`Layout shift: ${o.toFixed(4)}`,data:{cls:o}});});}));}observe(e,t){try{let o=new PerformanceObserver(n=>{t(n.getEntries());});o.observe({type:e,buffered:!0}),this.observers.push(o);}catch{}}teardown(){this.observers.forEach(e=>e.disconnect()),this.observers=[];}};function j(){let r=performance.memory;return !r||typeof r.usedJSHeapSize!="number"?null:r}var R=class{constructor(e){this.eventBus=e;this.name="memory";this.intervalId=null;this.baselineUsed=null;}setup(){let e=j();e&&(this.baselineUsed=e.usedJSHeapSize,this.intervalId=setInterval(()=>{let t=j();if(!t)return;let o=t.usedJSHeapSize/t.jsHeapSizeLimit,n=this.baselineUsed>0?(t.usedJSHeapSize-this.baselineUsed)/this.baselineUsed:0;this.eventBus.emit("breadcrumb:added",{category:"memory",message:`Heap: ${(o*100).toFixed(1)}% used (${(t.usedJSHeapSize/1048576).toFixed(1)}MB)`,data:{usedJSHeapSize:t.usedJSHeapSize,jsHeapSizeLimit:t.jsHeapSizeLimit}});let i=o>=.9,s=n>=.5;if(i||s){let a={kind:"memory",message:i?`Heap usage critical: ${(o*100).toFixed(1)}% of limit`:`Heap growth spike: ${(n*100).toFixed(1)}% since init`,usedJSHeapSize:t.usedJSHeapSize,totalJSHeapSize:t.totalJSHeapSize,jsHeapSizeLimit:t.jsHeapSizeLimit,heapUsagePercent:o,heapGrowthPercent:n};this.eventBus.emit("memory:captured",a);}},1e4));}teardown(){this.intervalId!==null&&(clearInterval(this.intervalId),this.intervalId=null),this.baselineUsed=null;}};var U=`
:host {

@@ -204,2 +204,12 @@ all: initial;

.gb-type-performance {
background: #e8f5e9;
color: #2e7d32;
}
.gb-type-memory {
background: #f3e5f5;
color: #6a1b9a;
}
.gb-report-message {

@@ -247,4 +257,4 @@ font-size: 13px;

}
`;var q='<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5s-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z"/></svg>';function A(){let e=document.createElement("button");e.className="gb-fab",e.setAttribute("aria-label","ghostbug - bug reports");let t=document.createElement("span");t.innerHTML=q,e.appendChild(t);let o=document.createElement("span");return o.className="gb-badge",o.setAttribute("data-count","0"),o.textContent="0",e.appendChild(o),e}function j(e){let t=document.createElement("div");t.className=`gb-panel gb-pos-${e}`;let o=document.createElement("div");o.className="gb-header";let r=document.createElement("span");r.className="gb-header-title",r.textContent="ghostbug",o.appendChild(r);let n=document.createElement("button");n.className="gb-header-btn gb-copy-btn",n.textContent="Copy MD",o.appendChild(n);let s=document.createElement("button");s.className="gb-header-btn gb-download-btn",s.textContent="Export",o.appendChild(s);let i=document.createElement("button");i.className="gb-close-btn",i.textContent="\xD7",i.setAttribute("aria-label","Close"),o.appendChild(i),t.appendChild(o);let l=document.createElement("div");l.className="gb-report-list";let a=document.createElement("div");return a.className="gb-empty",a.textContent="No bugs captured yet.",l.appendChild(a),t.appendChild(l),t}function I(e){let t=document.createElement("div");t.className="gb-report-item";let o=document.createElement("span");if(o.className=`gb-report-type gb-type-${e.payload.kind==="error"?"error":e.payload.kind}`,o.textContent=e.type,t.appendChild(o),e.count>1){let i=document.createElement("span");i.className="gb-report-count",i.textContent=`\xD7${e.count}`,t.appendChild(i);}let r=document.createElement("div");r.className="gb-report-message",r.textContent=F(e),t.appendChild(r);let n=document.createElement("div");n.className="gb-report-meta";let s=e.timestamp.split("T")[1]?.split(".")[0]||e.timestamp;return n.textContent=`${s} \xB7 ${e.context.url}`,t.appendChild(n),t}function F(e){switch(e.payload.kind){case "error":return e.payload.message;case "console":return e.payload.args.join(", ");case "network":return `${e.payload.method} ${e.payload.url} \u2192 ${e.payload.status}`}}function R(e){return g({generator:"ghostbug",version:f,exportedAt:new Date().toISOString(),reportCount:e.length,reports:e},2)}function B(e){let t=[];return t.push(`# Bug Report \u2014 ghostbug v${f}`),t.push(`**Generated:** ${new Date().toISOString()}`),t.push(`**Reports:** ${e.length}`),t.push(""),t.push("---"),t.push(""),e.forEach((o,r)=>{t.push(`## ${r+1}. ${X(o)}`),t.push(""),t.push(`- **Type:** ${o.type}`),t.push(`- **Time:** ${o.timestamp}`),t.push(`- **Occurrences:** ${o.count}`),t.push(`- **URL:** ${o.context.url}`),t.push(`- **Browser:** ${U(o.context.userAgent)}`),t.push(`- **Viewport:** ${o.context.viewport.width}x${o.context.viewport.height}`),t.push(""),t.push(...D(o.payload)),t.push(""),o.breadcrumbs.length>0&&(t.push("### Breadcrumbs"),t.push(""),t.push("| Time | Category | Event |"),t.push("|------|----------|-------|"),o.breadcrumbs.forEach(n=>{let s=n.timestamp.split("T")[1]?.split(".")[0]||n.timestamp;t.push(`| ${s} | ${n.category} | ${n.message} |`);}),t.push("")),t.push("---"),t.push("");}),t.join(`
`)}function X(e){switch(e.payload.kind){case "error":return `${e.payload.name||"Error"}: ${e.payload.message}`;case "console":return `Console ${e.payload.level}: ${e.payload.args[0]||""}`;case "network":return `${e.payload.method} ${e.payload.url} \u2192 ${e.payload.status}`}}function D(e){let t=[];switch(e.kind){case "error":e.stack&&(t.push("### Stack Trace"),t.push(""),t.push("```"),t.push(e.stack),t.push("```")),e.filename&&t.push(`**File:** ${e.filename}:${e.lineno}:${e.colno}`);break;case "console":t.push("### Console Output"),t.push(""),t.push("```"),e.args.forEach(o=>t.push(o)),t.push("```");break;case "network":t.push("### Network Details"),t.push(""),t.push(`- **Method:** ${e.method}`),t.push(`- **URL:** ${e.url}`),t.push(`- **Status:** ${e.status} ${e.statusText}`),t.push(`- **Duration:** ${e.duration}ms`);break}return t}function U(e){if(e.includes("Chrome")){let t=e.match(/Chrome\/(\d+)/);return t?`Chrome ${t[1]}`:"Chrome"}if(e.includes("Firefox")){let t=e.match(/Firefox\/(\d+)/);return t?`Firefox ${t[1]}`:"Firefox"}if(e.includes("Safari")&&!e.includes("Chrome")){let t=e.match(/Version\/(\d+)/);return t?`Safari ${t[1]}`:"Safari"}return e.slice(0,50)}var S=class{constructor(t,o,r){this.eventBus=t;this.reportManager=o;this.options=r;this.hostElement=null;this.shadowRoot=null;this.panel=null;this.badge=null;this.reportList=null;this.isExpanded=false;this.unsubscribers=[];}mount(){this.hostElement=document.createElement("div"),this.hostElement.id="ghostbug-widget";let t=this.hostElement.style;t.position="fixed",t.zIndex=String(this.options.zIndex),t.margin="0",t.padding="0",this.applyPosition(t),this.shadowRoot=this.hostElement.attachShadow({mode:"closed"});let o=document.createElement("style");o.textContent=z,this.shadowRoot.appendChild(o);let r=document.createElement("div");r.className="gb-container";let n=A();this.badge=n.querySelector(".gb-badge"),n.addEventListener("click",()=>this.toggle()),r.appendChild(n),this.panel=j(this.options.position),r.appendChild(this.panel),this.panel.querySelector(".gb-close-btn")?.addEventListener("click",()=>this.toggle()),this.panel.querySelector(".gb-copy-btn")?.addEventListener("click",()=>this.copyMarkdown()),this.panel.querySelector(".gb-download-btn")?.addEventListener("click",()=>this.downloadJSON()),this.reportList=this.panel.querySelector(".gb-report-list"),this.shadowRoot.appendChild(r),document.body.appendChild(this.hostElement),this.unsubscribers.push(this.eventBus.on("report:created",()=>this.update()),this.eventBus.on("report:deduplicated",()=>this.update())),this.options.collapsed||this.toggle();}applyPosition(t){let o=this.options.position;t.top=o.startsWith("top")?"16px":"auto",t.bottom=o.startsWith("bottom")?"16px":"auto",t.left=o.endsWith("left")?"16px":"auto",t.right=o.endsWith("right")?"16px":"auto";}toggle(){this.isExpanded=!this.isExpanded,this.isExpanded?(this.panel?.classList.add("gb-open"),this.renderReportList()):this.panel?.classList.remove("gb-open");}update(){this.updateBadge(),this.isExpanded&&this.renderReportList();}updateBadge(){if(!this.badge)return;let t=this.reportManager.reportCount;this.badge.textContent=String(t),this.badge.setAttribute("data-count",String(t));}renderReportList(){if(!this.reportList)return;this.reportList.textContent="";let t=this.reportManager.getReports();if(t.length===0){let r=document.createElement("div");r.className="gb-empty",r.textContent="No bugs captured yet.",this.reportList.appendChild(r);return}[...t].reverse().forEach(r=>{let n=I(r);this.reportList.appendChild(n);});}copyMarkdown(){let t=B(this.reportManager.getReports());navigator.clipboard.writeText(t).then(()=>this.showToast("Copied to clipboard!"),()=>this.showToast("Copy failed"));}downloadJSON(){let t=R(this.reportManager.getReports()),o=new Blob([t],{type:"application/json"}),r=URL.createObjectURL(o),n=document.createElement("a");n.href=r,n.download="ghostbug-report.json",n.click(),URL.revokeObjectURL(r);}showToast(t){if(!this.shadowRoot)return;let o=document.createElement("div");o.className="gb-toast",o.textContent=t,this.shadowRoot.appendChild(o),requestAnimationFrame(()=>{o.classList.add("gb-show");}),setTimeout(()=>{o.classList.remove("gb-show"),setTimeout(()=>o.remove(),300);},2e3);}unmount(){this.unsubscribers.forEach(t=>t()),this.unsubscribers=[],this.hostElement?.remove(),this.hostElement=null,this.shadowRoot=null,this.panel=null,this.badge=null,this.reportList=null;}};var p=null,m=null,u=[],L=null,$=new Set,O=false;function W(e,t){return t?{maxReports:t.maxReports??e.maxReports,maxBreadcrumbs:t.maxBreadcrumbs??e.maxBreadcrumbs,maxClicks:t.maxClicks??e.maxClicks,widget:t.widget??e.widget,collectors:{...e.collectors,...t.collectors},rateLimit:{...e.rateLimit,...t.rateLimit},beforeReport:t.beforeReport??e.beforeReport,debug:t.debug??e.debug}:{...e}}function G(e){if(O){e?.debug&&console.warn("[ghostbug] Already initialized. Call destroy() first.");return}let t=W(N,e);p=new b;let o=new C;if(m=new v(p,o,t),t.collectors.errors&&u.push(new w(p)),t.collectors.console&&u.push(new x(p)),t.collectors.network&&u.push(new E(p)),t.collectors.clicks&&u.push(new k(p,t.maxClicks)),u.push(o),u.forEach(r=>r.setup()),p.on("report:created",r=>{$.forEach(n=>{try{n(r);}catch{}});}),t.widget){let r=typeof t.widget=="object"?{position:t.widget.position||"bottom-right",collapsed:t.widget.collapsed??true,zIndex:t.widget.zIndex??2147483647}:{position:"bottom-right",collapsed:true,zIndex:2147483647};L=new S(p,m,r),L.mount();}O=true;}function J(){return T(),m.getReports()}function V(e="ghostbug-report.json"){T();let t=R(m.getReports()),o=new Blob([t],{type:"application/json"}),r=URL.createObjectURL(o),n=document.createElement("a");n.href=r,n.download=e,n.click(),URL.revokeObjectURL(r);}function Y(){return T(),B(m.getReports())}function K(e){return $.add(e),()=>$.delete(e)}function Q(){L?.unmount(),L=null,u.forEach(e=>e.teardown()),u=[],p?.clear(),p=null,m?.clear(),m=null,$.clear(),O=false;}function T(){if(!O)throw new Error("[ghostbug] Not initialized. Call ghostbug.init() first.")}var Xt={init:G,getReports:J,download:V,toMarkdown:Y,onBug:K,destroy:Q};exports.default=Xt;exports.destroy=Q;exports.download=V;exports.getReports=J;exports.init=G;exports.onBug=K;exports.toMarkdown=Y;//# sourceMappingURL=index.cjs.map
`;var J='<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5s-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z"/></svg>';function D(){let r=document.createElement("button");r.className="gb-fab",r.setAttribute("aria-label","ghostbug - bug reports");let e=document.createElement("span");e.innerHTML=J,r.appendChild(e);let t=document.createElement("span");return t.className="gb-badge",t.setAttribute("data-count","0"),t.textContent="0",r.appendChild(t),r}function G(r){let e=document.createElement("div");e.className=`gb-panel gb-pos-${r}`;let t=document.createElement("div");t.className="gb-header";let o=document.createElement("span");o.className="gb-header-title",o.textContent="ghostbug",t.appendChild(o);let n=document.createElement("button");n.className="gb-header-btn gb-copy-btn",n.textContent="Copy MD",t.appendChild(n);let i=document.createElement("button");i.className="gb-header-btn gb-download-btn",i.textContent="Export",t.appendChild(i);let s=document.createElement("button");s.className="gb-close-btn",s.textContent="\xD7",s.setAttribute("aria-label","Close"),t.appendChild(s),e.appendChild(t);let l=document.createElement("div");l.className="gb-report-list";let a=document.createElement("div");return a.className="gb-empty",a.textContent="No bugs captured yet.",l.appendChild(a),e.appendChild(l),e}function X(r){let e=document.createElement("div");e.className="gb-report-item";let t=document.createElement("span");if(t.className=`gb-report-type gb-type-${r.payload.kind==="error"?"error":r.payload.kind}`,t.textContent=r.type,e.appendChild(t),r.count>1){let s=document.createElement("span");s.className="gb-report-count",s.textContent=`\xD7${r.count}`,e.appendChild(s);}let o=document.createElement("div");o.className="gb-report-message",o.textContent=V(r),e.appendChild(o);let n=document.createElement("div");n.className="gb-report-meta";let i=r.timestamp.split("T")[1]?.split(".")[0]||r.timestamp;return n.textContent=`${i} \xB7 ${r.context.url}`,e.appendChild(n),e}function V(r){switch(r.payload.kind){case "error":return r.payload.message;case "console":return r.payload.args.join(", ");case "network":return `${r.payload.method} ${r.payload.url} \u2192 ${r.payload.status}`;case "performance":return `${r.payload.metric}: ${r.payload.value}ms`;case "memory":return r.payload.message}}function T(r){return g({generator:"ghostbug",version:f,exportedAt:new Date().toISOString(),reportCount:r.length,reports:r},2)}function L(r){let e=[];return e.push(`# Bug Report \u2014 ghostbug v${f}`),e.push(`**Generated:** ${new Date().toISOString()}`),e.push(`**Reports:** ${r.length}`),e.push(""),e.push("---"),e.push(""),r.forEach((t,o)=>{e.push(`## ${o+1}. ${Y(t)}`),e.push(""),e.push(`- **Type:** ${t.type}`),e.push(`- **Time:** ${t.timestamp}`),e.push(`- **Occurrences:** ${t.count}`),e.push(`- **URL:** ${t.context.url}`),e.push(`- **Browser:** ${Q(t.context.userAgent)}`),e.push(`- **Viewport:** ${t.context.viewport.width}x${t.context.viewport.height}`),e.push(""),e.push(...K(t.payload)),e.push(""),t.breadcrumbs.length>0&&(e.push("### Breadcrumbs"),e.push(""),e.push("| Time | Category | Event |"),e.push("|------|----------|-------|"),t.breadcrumbs.forEach(n=>{let i=n.timestamp.split("T")[1]?.split(".")[0]||n.timestamp;e.push(`| ${i} | ${n.category} | ${n.message} |`);}),e.push("")),e.push("---"),e.push("");}),e.join(`
`)}function Y(r){switch(r.payload.kind){case "error":return `${r.payload.name||"Error"}: ${r.payload.message}`;case "console":return `Console ${r.payload.level}: ${r.payload.args[0]||""}`;case "network":return `${r.payload.method} ${r.payload.url} \u2192 ${r.payload.status}`;case "performance":return `Performance: ${r.payload.metric} ${r.payload.value}ms`;case "memory":return `Memory: ${r.payload.message}`}}function K(r){let e=[];switch(r.kind){case "error":r.stack&&(e.push("### Stack Trace"),e.push(""),e.push("```"),e.push(r.stack),e.push("```")),r.filename&&e.push(`**File:** ${r.filename}:${r.lineno}:${r.colno}`);break;case "console":e.push("### Console Output"),e.push(""),e.push("```"),r.args.forEach(t=>e.push(t)),e.push("```");break;case "network":e.push("### Network Details"),e.push(""),e.push(`- **Method:** ${r.method}`),e.push(`- **URL:** ${r.url}`),e.push(`- **Status:** ${r.status} ${r.statusText}`),e.push(`- **Duration:** ${r.duration}ms`);break;case "performance":e.push("### Performance Details"),e.push(""),e.push(`- **Metric:** ${r.metric}`),e.push(`- **Value:** ${r.value}ms`),r.entries.length>0&&e.push(`- **Start Time:** ${Math.round(r.entries[0].startTime)}ms`);break;case "memory":e.push("### Memory Details"),e.push(""),e.push(`- **Used:** ${(r.usedJSHeapSize/1048576).toFixed(1)}MB`),e.push(`- **Limit:** ${(r.jsHeapSizeLimit/1048576).toFixed(1)}MB`),e.push(`- **Usage:** ${(r.heapUsagePercent*100).toFixed(1)}%`),e.push(`- **Growth since init:** ${(r.heapGrowthPercent*100).toFixed(1)}%`);break}return e}function Q(r){if(r.includes("Chrome")){let e=r.match(/Chrome\/(\d+)/);return e?`Chrome ${e[1]}`:"Chrome"}if(r.includes("Firefox")){let e=r.match(/Firefox\/(\d+)/);return e?`Firefox ${e[1]}`:"Firefox"}if(r.includes("Safari")&&!r.includes("Chrome")){let e=r.match(/Version\/(\d+)/);return e?`Safari ${e[1]}`:"Safari"}return r.slice(0,50)}var P=class{constructor(e,t,o){this.eventBus=e;this.reportManager=t;this.options=o;this.hostElement=null;this.shadowRoot=null;this.panel=null;this.badge=null;this.reportList=null;this.isExpanded=false;this.unsubscribers=[];}mount(){this.hostElement=document.createElement("div"),this.hostElement.id="ghostbug-widget";let e=this.hostElement.style;e.position="fixed",e.zIndex=String(this.options.zIndex),e.margin="0",e.padding="0",this.applyPosition(e),this.shadowRoot=this.hostElement.attachShadow({mode:"closed"});let t=document.createElement("style");t.textContent=U,this.shadowRoot.appendChild(t);let o=document.createElement("div");o.className="gb-container";let n=D();this.badge=n.querySelector(".gb-badge"),n.addEventListener("click",()=>this.toggle()),o.appendChild(n),this.panel=G(this.options.position),o.appendChild(this.panel),this.panel.querySelector(".gb-close-btn")?.addEventListener("click",()=>this.toggle()),this.panel.querySelector(".gb-copy-btn")?.addEventListener("click",()=>this.copyMarkdown()),this.panel.querySelector(".gb-download-btn")?.addEventListener("click",()=>this.downloadJSON()),this.reportList=this.panel.querySelector(".gb-report-list"),this.shadowRoot.appendChild(o),document.body.appendChild(this.hostElement),this.unsubscribers.push(this.eventBus.on("report:created",()=>this.update()),this.eventBus.on("report:deduplicated",()=>this.update())),this.options.collapsed||this.toggle();}applyPosition(e){let t=this.options.position;e.top=t.startsWith("top")?"16px":"auto",e.bottom=t.startsWith("bottom")?"16px":"auto",e.left=t.endsWith("left")?"16px":"auto",e.right=t.endsWith("right")?"16px":"auto";}toggle(){this.isExpanded=!this.isExpanded,this.isExpanded?(this.panel?.classList.add("gb-open"),this.renderReportList()):this.panel?.classList.remove("gb-open");}update(){this.updateBadge(),this.isExpanded&&this.renderReportList();}updateBadge(){if(!this.badge)return;let e=this.reportManager.reportCount;this.badge.textContent=String(e),this.badge.setAttribute("data-count",String(e));}renderReportList(){if(!this.reportList)return;this.reportList.textContent="";let e=this.reportManager.getReports();if(e.length===0){let o=document.createElement("div");o.className="gb-empty",o.textContent="No bugs captured yet.",this.reportList.appendChild(o);return}[...e].reverse().forEach(o=>{let n=X(o);this.reportList.appendChild(n);});}copyMarkdown(){let e=L(this.reportManager.getReports());navigator.clipboard.writeText(e).then(()=>this.showToast("Copied to clipboard!"),()=>this.showToast("Copy failed"));}downloadJSON(){let e=T(this.reportManager.getReports()),t=new Blob([e],{type:"application/json"}),o=URL.createObjectURL(t),n=document.createElement("a");n.href=o,n.download="ghostbug-report.json",n.click(),URL.revokeObjectURL(o);}showToast(e){if(!this.shadowRoot)return;let t=document.createElement("div");t.className="gb-toast",t.textContent=e,this.shadowRoot.appendChild(t),requestAnimationFrame(()=>{t.classList.add("gb-show");}),setTimeout(()=>{t.classList.remove("gb-show"),setTimeout(()=>t.remove(),300);},2e3);}unmount(){this.unsubscribers.forEach(e=>e()),this.unsubscribers=[],this.hostElement?.remove(),this.hostElement=null,this.shadowRoot=null,this.panel=null,this.badge=null,this.reportList=null;}};var c=null,h=null,d=[],H=null,$=new Set,M=false,z,O;function Z(r,e){return e?{maxReports:e.maxReports??r.maxReports,maxBreadcrumbs:e.maxBreadcrumbs??r.maxBreadcrumbs,maxClicks:e.maxClicks??r.maxClicks,widget:e.widget??r.widget,collectors:{...r.collectors,...e.collectors},rateLimit:{...r.rateLimit,...e.rateLimit},beforeReport:e.beforeReport??r.beforeReport,debug:e.debug??r.debug,screenshotFn:e.screenshotFn}:{...r}}function ee(r){if(M){r?.debug&&console.warn("[ghostbug] Already initialized. Call destroy() first.");return}let e=Z(_,r);c=new b;let t=new C(()=>({user:z,tags:O}));if(h=new y(c,t,e),e.collectors.errors&&d.push(new w(c)),e.collectors.console&&d.push(new x(c)),e.collectors.network&&d.push(new E(c)),e.collectors.clicks&&d.push(new k(c,e.maxClicks)),e.collectors.interactions&&d.push(new S(c)),e.collectors.performance&&d.push(new B(c)),e.collectors.memory&&d.push(new R(c)),d.push(t),d.forEach(o=>o.setup()),c.on("report:created",o=>{$.forEach(n=>{try{n(o);}catch{}});}),e.widget){let o=typeof e.widget=="object"?{position:e.widget.position||"bottom-right",collapsed:e.widget.collapsed??true,zIndex:e.widget.zIndex??2147483647}:{position:"bottom-right",collapsed:true,zIndex:2147483647};H=new P(c,h,o),H.mount();}M=true;}function te(){return N(),h.getReports()}function re(r="ghostbug-report.json"){N();let e=T(h.getReports()),t=new Blob([e],{type:"application/json"}),o=URL.createObjectURL(t),n=document.createElement("a");n.href=o,n.download=r,n.click(),URL.revokeObjectURL(o);}function oe(){return N(),L(h.getReports())}function ne(r){return $.add(r),()=>$.delete(r)}function ie(r){z=r;}function se(r){O={...O,...r};}function ae(){H?.unmount(),H=null,d.forEach(r=>r.teardown()),d=[],c?.clear(),c=null,h?.clear(),h=null,$.clear(),z=void 0,O=void 0,M=false;}function N(){if(!M)throw new Error("[ghostbug] Not initialized. Call ghostbug.init() first.")}var nt={init:ee,getReports:te,download:re,toMarkdown:oe,onBug:ne,setUser:ie,setTags:se,destroy:ae};exports.default=nt;exports.destroy=ae;exports.download=re;exports.getReports=te;exports.init=ee;exports.onBug=ne;exports.setTags=se;exports.setUser=ie;exports.toMarkdown=oe;//# sourceMappingURL=index.cjs.map
//# sourceMappingURL=index.cjs.map

@@ -18,2 +18,4 @@ interface GhostbugOptions {

debug?: boolean;
/** Async function that returns a screenshot data URL. Called on each new bug report. */
screenshotFn?: () => Promise<string>;
}

@@ -25,2 +27,5 @@ interface CollectorToggle {

clicks?: boolean;
interactions?: boolean;
performance?: boolean;
memory?: boolean;
}

@@ -39,3 +44,3 @@ interface RateLimitConfig {

}
type BugReportType = 'error' | 'unhandled-rejection' | 'console' | 'network';
type BugReportType = 'error' | 'unhandled-rejection' | 'console' | 'network' | 'performance' | 'memory';
interface BugReport {

@@ -47,5 +52,6 @@ id: string;

count: number;
payload: ErrorPayload | ConsolePayload | NetworkPayload;
payload: ErrorPayload | ConsolePayload | NetworkPayload | PerformancePayload | MemoryPayload;
breadcrumbs: Breadcrumb[];
context: PageContext;
screenshot?: string;
}

@@ -74,3 +80,23 @@ interface ErrorPayload {

}
type BreadcrumbCategory = 'click' | 'navigation' | 'console' | 'network' | 'error';
interface PerformancePayload {
kind: 'performance';
metric: string;
value: number;
entries: PerformanceEntryData[];
}
interface PerformanceEntryData {
name: string;
duration: number;
startTime: number;
}
interface MemoryPayload {
kind: 'memory';
message: string;
usedJSHeapSize: number;
totalJSHeapSize: number;
jsHeapSizeLimit: number;
heapUsagePercent: number;
heapGrowthPercent: number;
}
type BreadcrumbCategory = 'click' | 'navigation' | 'console' | 'network' | 'error' | 'interaction' | 'visibility' | 'performance' | 'memory';
interface Breadcrumb {

@@ -101,2 +127,4 @@ timestamp: string;

};
user?: Record<string, unknown>;
tags?: Record<string, unknown>;
}

@@ -120,2 +148,4 @@ interface ClickEntry {

declare function onBug(callback: BugCallback): () => void;
declare function setUser(user: Record<string, unknown>): void;
declare function setTags(tags: Record<string, unknown>): void;
declare function destroy(): void;

@@ -129,5 +159,7 @@

onBug: typeof onBug;
setUser: typeof setUser;
setTags: typeof setTags;
destroy: typeof destroy;
};
export { type Breadcrumb, type BugCallback, type BugReport, type ClickEntry, type ConsolePayload, type ErrorPayload, type GhostbugOptions, type NetworkPayload, type PageContext, type WidgetOptions, _default as default, destroy, download, getReports, init, onBug, toMarkdown };
export { type Breadcrumb, type BugCallback, type BugReport, type ClickEntry, type ConsolePayload, type ErrorPayload, type GhostbugOptions, type MemoryPayload, type NetworkPayload, type PageContext, type PerformanceEntryData, type PerformancePayload, type WidgetOptions, _default as default, destroy, download, getReports, init, onBug, setTags, setUser, toMarkdown };

@@ -18,2 +18,4 @@ interface GhostbugOptions {

debug?: boolean;
/** Async function that returns a screenshot data URL. Called on each new bug report. */
screenshotFn?: () => Promise<string>;
}

@@ -25,2 +27,5 @@ interface CollectorToggle {

clicks?: boolean;
interactions?: boolean;
performance?: boolean;
memory?: boolean;
}

@@ -39,3 +44,3 @@ interface RateLimitConfig {

}
type BugReportType = 'error' | 'unhandled-rejection' | 'console' | 'network';
type BugReportType = 'error' | 'unhandled-rejection' | 'console' | 'network' | 'performance' | 'memory';
interface BugReport {

@@ -47,5 +52,6 @@ id: string;

count: number;
payload: ErrorPayload | ConsolePayload | NetworkPayload;
payload: ErrorPayload | ConsolePayload | NetworkPayload | PerformancePayload | MemoryPayload;
breadcrumbs: Breadcrumb[];
context: PageContext;
screenshot?: string;
}

@@ -74,3 +80,23 @@ interface ErrorPayload {

}
type BreadcrumbCategory = 'click' | 'navigation' | 'console' | 'network' | 'error';
interface PerformancePayload {
kind: 'performance';
metric: string;
value: number;
entries: PerformanceEntryData[];
}
interface PerformanceEntryData {
name: string;
duration: number;
startTime: number;
}
interface MemoryPayload {
kind: 'memory';
message: string;
usedJSHeapSize: number;
totalJSHeapSize: number;
jsHeapSizeLimit: number;
heapUsagePercent: number;
heapGrowthPercent: number;
}
type BreadcrumbCategory = 'click' | 'navigation' | 'console' | 'network' | 'error' | 'interaction' | 'visibility' | 'performance' | 'memory';
interface Breadcrumb {

@@ -101,2 +127,4 @@ timestamp: string;

};
user?: Record<string, unknown>;
tags?: Record<string, unknown>;
}

@@ -120,2 +148,4 @@ interface ClickEntry {

declare function onBug(callback: BugCallback): () => void;
declare function setUser(user: Record<string, unknown>): void;
declare function setTags(tags: Record<string, unknown>): void;
declare function destroy(): void;

@@ -129,5 +159,7 @@

onBug: typeof onBug;
setUser: typeof setUser;
setTags: typeof setTags;
destroy: typeof destroy;
};
export { type Breadcrumb, type BugCallback, type BugReport, type ClickEntry, type ConsolePayload, type ErrorPayload, type GhostbugOptions, type NetworkPayload, type PageContext, type WidgetOptions, _default as default, destroy, download, getReports, init, onBug, toMarkdown };
export { type Breadcrumb, type BugCallback, type BugReport, type ClickEntry, type ConsolePayload, type ErrorPayload, type GhostbugOptions, type MemoryPayload, type NetworkPayload, type PageContext, type PerformanceEntryData, type PerformancePayload, type WidgetOptions, _default as default, destroy, download, getReports, init, onBug, setTags, setUser, toMarkdown };

@@ -1,3 +0,3 @@

"use strict";var ghostbug=(()=>{var T=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var J=Object.getOwnPropertyNames;var V=Object.prototype.hasOwnProperty;var Y=(e,t)=>{for(var o in t)T(e,o,{get:t[o],enumerable:!0})},K=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of J(t))!V.call(e,n)&&n!==o&&T(e,n,{get:()=>t[n],enumerable:!(r=G(t,n))||r.enumerable});return e};var Q=e=>K(T({},"__esModule",{value:!0}),e);var at={};Y(at,{default:()=>st,destroy:()=>W,download:()=>X,getReports:()=>F,init:()=>q,onBug:()=>U,toMarkdown:()=>D});var f="0.1.0",P={maxReports:50,maxBreadcrumbs:20,maxClicks:20,widget:!1,collectors:{errors:!0,console:!0,network:!0,clicks:!0},rateLimit:{maxEvents:10,windowMs:1e3},beforeReport:e=>e,debug:!1};var b=class{constructor(){this.listeners=new Map}on(t,o){return this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(o),()=>this.off(t,o)}off(t,o){this.listeners.get(t)?.delete(o)}emit(t,o){this.listeners.get(t)?.forEach(r=>{try{r(o)}catch{}})}clear(){this.listeners.clear()}};var h=class{constructor(t){this.capacity=t;this.head=0;this._size=0;this.buffer=new Array(t)}push(t){this.buffer[this.head]=t,this.head=(this.head+1)%this.capacity,this._size<this.capacity&&this._size++}toArray(){if(this._size===0)return[];let t=[],o=this._size<this.capacity?0:this.head;for(let r=0;r<this._size;r++){let n=(o+r)%this.capacity;t.push(this.buffer[n])}return t}get size(){return this._size}get isFull(){return this._size===this.capacity}peek(){if(this._size===0)return;let t=(this.head-1+this.capacity)%this.capacity;return this.buffer[t]}find(t){return this.toArray().find(t)}forEach(t){this.toArray().forEach(t)}clear(){this.buffer=new Array(this.capacity),this.head=0,this._size=0}};var y=class{constructor(t,o){this.maxEvents=t;this.windowMs=o;this.timestamps=[]}allow(){let t=Date.now();return this.timestamps=this.timestamps.filter(o=>t-o<this.windowMs),this.timestamps.length>=this.maxEvents?!1:(this.timestamps.push(t),!0)}reset(){this.timestamps=[]}};function Z(e){let t=5381;for(let o=0;o<e.length;o++)t=(t<<5)+t+e.charCodeAt(o)&4294967295;return(t>>>0).toString(36)}function M(e){let t;switch(e.kind){case"error":{let o=e.stack?.split(`
`)[1]?.trim()||"";t=`${e.name}:${e.message}:${o}`;break}case"console":t=`console:${e.level}:${e.args.join(",")}`;break;case"network":t=`network:${e.method}:${e.url}:${e.status}`;break}return Z(t)}function H(){let e=new Uint8Array(8);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(36).padStart(2,"0")).join("").slice(0,12)}var v=class{constructor(t,o,r){this.eventBus=t;this.contextCollector=o;this.options=r;this.unsubscribers=[];this.reports=new h(r.maxReports),this.breadcrumbs=new h(r.maxBreadcrumbs),this.rateLimiter=new y(r.rateLimit.maxEvents,r.rateLimit.windowMs),this.subscribe()}subscribe(){this.unsubscribers.push(this.eventBus.on("error:captured",t=>{this.addBreadcrumb({category:"error",message:t.message}),this.handleCapturedEvent("error",t)}),this.eventBus.on("console:captured",t=>{this.addBreadcrumb({category:"console",message:`console.${t.level}: ${t.args.join(", ")}`}),t.level==="error"&&this.handleCapturedEvent("console",t)}),this.eventBus.on("network:captured",t=>{this.handleCapturedEvent("network",t)}),this.eventBus.on("breadcrumb:added",t=>{this.addBreadcrumb(t)}))}handleCapturedEvent(t,o){if(!this.rateLimiter.allow())return;let r=M(o),n=this.reports.find(l=>l.fingerprint===r);if(n){n.count++,n.timestamp=new Date().toISOString(),this.eventBus.emit("report:deduplicated",n);return}let s={id:H(),fingerprint:r,type:t,timestamp:new Date().toISOString(),count:1,payload:o,breadcrumbs:this.breadcrumbs.toArray(),context:this.contextCollector.snapshot()},i=this.options.beforeReport(s);i&&(s=i,this.reports.push(s),this.eventBus.emit("report:created",s))}addBreadcrumb(t){this.breadcrumbs.push({...t,timestamp:new Date().toISOString()})}getReports(){return this.reports.toArray()}clear(){this.reports.clear(),this.breadcrumbs.clear(),this.unsubscribers.forEach(t=>t()),this.unsubscribers=[]}get reportCount(){return this.reports.size}};var w=class{constructor(t){this.eventBus=t;this.name="error";this.originalOnError=null;this.rejectionHandler=null}setup(){this.originalOnError=window.onerror,window.onerror=(t,o,r,n,s)=>{let i={kind:"error",message:String(t),stack:s?.stack,filename:o??void 0,lineno:r??void 0,colno:n??void 0,name:s?.name};return this.eventBus.emit("error:captured",i),this.originalOnError?this.originalOnError.call(window,t,o,r,n,s):!1},this.rejectionHandler=t=>{let o=t.reason,r={kind:"error",message:o instanceof Error?o.message:String(o),stack:o instanceof Error?o.stack:void 0,name:o instanceof Error?o.name:"UnhandledRejection"};this.eventBus.emit("error:captured",r)},window.addEventListener("unhandledrejection",this.rejectionHandler)}teardown(){window.onerror=this.originalOnError,this.originalOnError=null,this.rejectionHandler&&(window.removeEventListener("unhandledrejection",this.rejectionHandler),this.rejectionHandler=null)}};function g(e,t){let o=new WeakSet;return JSON.stringify(e,(r,n)=>{if(typeof n=="object"&&n!==null){if(o.has(n))return"[Circular]";o.add(n)}return typeof n=="function"?"[Function]":typeof n=="symbol"?n.toString():n instanceof Error?{name:n.name,message:n.message,stack:n.stack}:n},t)}var x=class{constructor(t){this.eventBus=t;this.name="console";this.originalError=null;this.originalWarn=null}setup(){this.originalError=console.error,this.originalWarn=console.warn,console.error=(...t)=>{let o={kind:"console",level:"error",args:t.map(r=>g(r))};this.eventBus.emit("console:captured",o),this.originalError.apply(console,t)},console.warn=(...t)=>{let o={kind:"console",level:"warn",args:t.map(r=>g(r))};this.eventBus.emit("console:captured",o),this.originalWarn.apply(console,t)}}teardown(){this.originalError&&(console.error=this.originalError),this.originalWarn&&(console.warn=this.originalWarn),this.originalError=null,this.originalWarn=null}};var E=class{constructor(t){this.eventBus=t;this.name="network";this.originalFetch=null;this.originalXhrOpen=null;this.originalXhrSend=null}setup(){this.patchFetch(),this.patchXHR()}patchFetch(){this.originalFetch=window.fetch;let t=this.eventBus,o=this.originalFetch;window.fetch=function(r,n){let s=n?.method?.toUpperCase()||"GET",i=typeof r=="string"?r:r instanceof URL?r.href:r.url,l=performance.now();return o.call(window,r,n).then(a=>{let c=Math.round(performance.now()-l);if(a.status>=400){let d={kind:"network",method:s,url:i,status:a.status,statusText:a.statusText,duration:c};t.emit("network:captured",d)}return t.emit("breadcrumb:added",{category:"network",message:`${s} ${i} -> ${a.status}`}),a},a=>{let c=Math.round(performance.now()-l),d={kind:"network",method:s,url:i,status:0,statusText:a.message||"Network Error",duration:c};throw t.emit("network:captured",d),a})}}patchXHR(){this.originalXhrOpen=XMLHttpRequest.prototype.open,this.originalXhrSend=XMLHttpRequest.prototype.send;let t=this.eventBus,o=this.originalXhrOpen,r=this.originalXhrSend;XMLHttpRequest.prototype.open=function(n,s,...i){return this.__ghostbug_method=n.toUpperCase(),this.__ghostbug_url=String(s),o.apply(this,[n,s,...i])},XMLHttpRequest.prototype.send=function(n){let s=performance.now(),i=this;return i.addEventListener("loadend",function(){let l=Math.round(performance.now()-s),a=i.__ghostbug_method||"UNKNOWN",c=i.__ghostbug_url||"";if(i.status>=400||i.status===0){let d={kind:"network",method:a,url:c,status:i.status,statusText:i.statusText,duration:l};t.emit("network:captured",d)}t.emit("breadcrumb:added",{category:"network",message:`${a} ${c} -> ${i.status}`})}),r.call(this,n)}}teardown(){this.originalFetch&&(window.fetch=this.originalFetch,this.originalFetch=null),this.originalXhrOpen&&(XMLHttpRequest.prototype.open=this.originalXhrOpen,this.originalXhrOpen=null),this.originalXhrSend&&(XMLHttpRequest.prototype.send=this.originalXhrSend,this.originalXhrSend=null)}};function z(e){if(e.id)return`#${e.id}`;let t=e.getAttribute("data-testid");if(t)return`[data-testid="${t}"]`;let o=[],r=e,n=0;for(;r&&r!==document.documentElement&&n<5;){let s=r.tagName.toLowerCase();if(r.id){o.unshift(`#${r.id}`);break}let i=Array.from(r.classList).slice(0,2);i.length>0&&(s+="."+i.join("."));let l=r.parentElement;if(l){let a=r.tagName,c=Array.from(l.children).filter(d=>d.tagName===a);if(c.length>1){let d=c.indexOf(r)+1;s+=`:nth-child(${d})`}}o.unshift(s),r=l,n++}return o.join(" > ")}var k=class{constructor(t,o){this.eventBus=t;this.name="click";this.handler=null;this.clicks=new h(o)}setup(){this.handler=t=>{let o=t.target;if(!o)return;let r={timestamp:new Date().toISOString(),selector:z(o),tagName:o.tagName.toLowerCase(),text:(o.textContent||"").trim().slice(0,100),position:{x:t.clientX,y:t.clientY}};this.clicks.push(r),this.eventBus.emit("click:captured",r),this.eventBus.emit("breadcrumb:added",{category:"click",message:`Clicked ${r.tagName} "${r.text}"`,data:{selector:r.selector}})},document.addEventListener("click",this.handler,!0)}getClickTrail(){return this.clicks.toArray()}teardown(){this.handler&&(document.removeEventListener("click",this.handler,!0),this.handler=null),this.clicks.clear()}};var C=class{constructor(){this.name="context"}setup(){}teardown(){}snapshot(){return{url:window.location.href,referrer:document.referrer,userAgent:navigator.userAgent,language:navigator.language,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:window.screen.width,height:window.screen.height},devicePixelRatio:window.devicePixelRatio||1,timestamp:new Date().toISOString(),memory:performance.memory?{usedJSHeapSize:performance.memory.usedJSHeapSize,totalJSHeapSize:performance.memory.totalJSHeapSize}:void 0}}};var A=`
"use strict";var ghostbug=(()=>{var z=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var re=Object.getOwnPropertyNames;var oe=Object.prototype.hasOwnProperty;var ne=(r,e)=>{for(var t in e)z(r,t,{get:e[t],enumerable:!0})},ie=(r,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of re(e))!oe.call(r,n)&&n!==t&&z(r,n,{get:()=>e[n],enumerable:!(o=te(e,n))||o.enumerable});return r};var se=r=>ie(z({},"__esModule",{value:!0}),r);var fe={};ne(fe,{default:()=>ge,destroy:()=>ee,download:()=>V,getReports:()=>J,init:()=>W,onBug:()=>K,setTags:()=>Z,setUser:()=>Q,toMarkdown:()=>Y});var f="0.1.0",I={maxReports:50,maxBreadcrumbs:20,maxClicks:20,widget:!1,collectors:{errors:!0,console:!0,network:!0,clicks:!0,interactions:!0,performance:!0,memory:!0},rateLimit:{maxEvents:10,windowMs:1e3},beforeReport:r=>r,debug:!1};var b=class{constructor(){this.listeners=new Map}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>this.off(e,t)}off(e,t){this.listeners.get(e)?.delete(t)}emit(e,t){this.listeners.get(e)?.forEach(o=>{try{o(t)}catch{}})}clear(){this.listeners.clear()}};var m=class{constructor(e){this.capacity=e;this.head=0;this._size=0;this.buffer=new Array(e)}push(e){this.buffer[this.head]=e,this.head=(this.head+1)%this.capacity,this._size<this.capacity&&this._size++}toArray(){if(this._size===0)return[];let e=[],t=this._size<this.capacity?0:this.head;for(let o=0;o<this._size;o++){let n=(t+o)%this.capacity;e.push(this.buffer[n])}return e}get size(){return this._size}get isFull(){return this._size===this.capacity}peek(){if(this._size===0)return;let e=(this.head-1+this.capacity)%this.capacity;return this.buffer[e]}find(e){return this.toArray().find(e)}forEach(e){this.toArray().forEach(e)}clear(){this.buffer=new Array(this.capacity),this.head=0,this._size=0}};var v=class{constructor(e,t){this.maxEvents=e;this.windowMs=t;this.timestamps=[]}allow(){let e=Date.now();return this.timestamps=this.timestamps.filter(t=>e-t<this.windowMs),this.timestamps.length>=this.maxEvents?!1:(this.timestamps.push(e),!0)}reset(){this.timestamps=[]}};function ae(r){let e=5381;for(let t=0;t<r.length;t++)e=(e<<5)+e+r.charCodeAt(t)&4294967295;return(e>>>0).toString(36)}function A(r){let e;switch(r.kind){case"error":{let t=r.stack?.split(`
`)[1]?.trim()||"";e=`${r.name}:${r.message}:${t}`;break}case"console":e=`console:${r.level}:${r.args.join(",")}`;break;case"network":e=`network:${r.method}:${r.url}:${r.status}`;break;case"performance":e=`performance:${r.metric}:${Math.floor(r.value/100)*100}`;break;case"memory":e=`memory:${Math.floor(r.heapUsagePercent*10)/10}`;break}return ae(e)}function F(){let r=new Uint8Array(8);return crypto.getRandomValues(r),Array.from(r,e=>e.toString(36).padStart(2,"0")).join("").slice(0,12)}var le=3e3,y=class{constructor(e,t,o){this.eventBus=e;this.contextCollector=t;this.options=o;this.unsubscribers=[];this.reports=new m(o.maxReports),this.breadcrumbs=new m(o.maxBreadcrumbs),this.rateLimiter=new v(o.rateLimit.maxEvents,o.rateLimit.windowMs),this.subscribe()}subscribe(){this.unsubscribers.push(this.eventBus.on("error:captured",e=>{this.addBreadcrumb({category:"error",message:e.message}),this.handleCapturedEvent("error",e)}),this.eventBus.on("console:captured",e=>{this.addBreadcrumb({category:"console",message:`console.${e.level}: ${e.args.join(", ")}`}),e.level==="error"&&this.handleCapturedEvent("console",e)}),this.eventBus.on("network:captured",e=>{this.handleCapturedEvent("network",e)}),this.eventBus.on("performance:captured",e=>{this.addBreadcrumb({category:"performance",message:`${e.metric}: ${e.value}ms`}),this.handleCapturedEvent("performance",e)}),this.eventBus.on("memory:captured",e=>{this.handleCapturedEvent("memory",e)}),this.eventBus.on("breadcrumb:added",e=>{this.addBreadcrumb(e)}))}async handleCapturedEvent(e,t){if(!this.rateLimiter.allow())return;let o=A(t),n=this.reports.find(l=>l.fingerprint===o);if(n){n.count++,n.timestamp=new Date().toISOString(),this.eventBus.emit("report:deduplicated",n);return}let i={id:F(),fingerprint:o,type:e,timestamp:new Date().toISOString(),count:1,payload:t,breadcrumbs:this.breadcrumbs.toArray(),context:this.contextCollector.snapshot()};if(this.options.screenshotFn)try{i.screenshot=await Promise.race([this.options.screenshotFn(),new Promise((l,a)=>setTimeout(()=>a(new Error("screenshot timeout")),le))])}catch{}let s=this.options.beforeReport(i);s&&(i=s,this.reports.push(i),this.eventBus.emit("report:created",i))}addBreadcrumb(e){this.breadcrumbs.push({...e,timestamp:new Date().toISOString()})}getReports(){return this.reports.toArray()}clear(){this.reports.clear(),this.breadcrumbs.clear(),this.unsubscribers.forEach(e=>e()),this.unsubscribers=[]}get reportCount(){return this.reports.size}};var w=class{constructor(e){this.eventBus=e;this.name="error";this.originalOnError=null;this.rejectionHandler=null}setup(){this.originalOnError=window.onerror,window.onerror=(e,t,o,n,i)=>{let s={kind:"error",message:String(e),stack:i?.stack,filename:t??void 0,lineno:o??void 0,colno:n??void 0,name:i?.name};return this.eventBus.emit("error:captured",s),this.originalOnError?this.originalOnError.call(window,e,t,o,n,i):!1},this.rejectionHandler=e=>{let t=e.reason,o={kind:"error",message:t instanceof Error?t.message:String(t),stack:t instanceof Error?t.stack:void 0,name:t instanceof Error?t.name:"UnhandledRejection"};this.eventBus.emit("error:captured",o)},window.addEventListener("unhandledrejection",this.rejectionHandler)}teardown(){window.onerror=this.originalOnError,this.originalOnError=null,this.rejectionHandler&&(window.removeEventListener("unhandledrejection",this.rejectionHandler),this.rejectionHandler=null)}};function g(r,e){let t=new WeakSet;return JSON.stringify(r,(o,n)=>{if(typeof n=="object"&&n!==null){if(t.has(n))return"[Circular]";t.add(n)}return typeof n=="function"?"[Function]":typeof n=="symbol"?n.toString():n instanceof Error?{name:n.name,message:n.message,stack:n.stack}:n},e)}var x=class{constructor(e){this.eventBus=e;this.name="console";this.originalError=null;this.originalWarn=null}setup(){this.originalError=console.error,this.originalWarn=console.warn,console.error=(...e)=>{let t={kind:"console",level:"error",args:e.map(o=>g(o))};this.eventBus.emit("console:captured",t),this.originalError.apply(console,e)},console.warn=(...e)=>{let t={kind:"console",level:"warn",args:e.map(o=>g(o))};this.eventBus.emit("console:captured",t),this.originalWarn.apply(console,e)}}teardown(){this.originalError&&(console.error=this.originalError),this.originalWarn&&(console.warn=this.originalWarn),this.originalError=null,this.originalWarn=null}};var E=class{constructor(e){this.eventBus=e;this.name="network";this.originalFetch=null;this.originalXhrOpen=null;this.originalXhrSend=null}setup(){this.patchFetch(),this.patchXHR()}patchFetch(){this.originalFetch=window.fetch;let e=this.eventBus,t=this.originalFetch;window.fetch=function(o,n){let i=n?.method?.toUpperCase()||"GET",s=typeof o=="string"?o:o instanceof URL?o.href:o.url,l=performance.now();return t.call(window,o,n).then(a=>{let p=Math.round(performance.now()-l);if(a.status>=400){let u={kind:"network",method:i,url:s,status:a.status,statusText:a.statusText,duration:p};e.emit("network:captured",u)}return e.emit("breadcrumb:added",{category:"network",message:`${i} ${s} -> ${a.status}`}),a},a=>{let p=Math.round(performance.now()-l),u={kind:"network",method:i,url:s,status:0,statusText:a.message||"Network Error",duration:p};throw e.emit("network:captured",u),a})}}patchXHR(){this.originalXhrOpen=XMLHttpRequest.prototype.open,this.originalXhrSend=XMLHttpRequest.prototype.send;let e=this.eventBus,t=this.originalXhrOpen,o=this.originalXhrSend;XMLHttpRequest.prototype.open=function(n,i,...s){return this.__ghostbug_method=n.toUpperCase(),this.__ghostbug_url=String(i),t.apply(this,[n,i,...s])},XMLHttpRequest.prototype.send=function(n){let i=performance.now(),s=this;return s.addEventListener("loadend",function(){let l=Math.round(performance.now()-i),a=s.__ghostbug_method||"UNKNOWN",p=s.__ghostbug_url||"";if(s.status>=400||s.status===0){let u={kind:"network",method:a,url:p,status:s.status,statusText:s.statusText,duration:l};e.emit("network:captured",u)}e.emit("breadcrumb:added",{category:"network",message:`${a} ${p} -> ${s.status}`})}),o.call(this,n)}}teardown(){this.originalFetch&&(window.fetch=this.originalFetch,this.originalFetch=null),this.originalXhrOpen&&(XMLHttpRequest.prototype.open=this.originalXhrOpen,this.originalXhrOpen=null),this.originalXhrSend&&(XMLHttpRequest.prototype.send=this.originalXhrSend,this.originalXhrSend=null)}};function j(r){if(r.id)return`#${r.id}`;let e=r.getAttribute("data-testid");if(e)return`[data-testid="${e}"]`;let t=[],o=r,n=0;for(;o&&o!==document.documentElement&&n<5;){let i=o.tagName.toLowerCase();if(o.id){t.unshift(`#${o.id}`);break}let s=Array.from(o.classList).slice(0,2);s.length>0&&(i+="."+s.join("."));let l=o.parentElement;if(l){let a=o.tagName,p=Array.from(l.children).filter(u=>u.tagName===a);if(p.length>1){let u=p.indexOf(o)+1;i+=`:nth-child(${u})`}}t.unshift(i),o=l,n++}return t.join(" > ")}var k=class{constructor(e,t){this.eventBus=e;this.name="click";this.handler=null;this.clicks=new m(t)}setup(){this.handler=e=>{let t=e.target;if(!t)return;let o={timestamp:new Date().toISOString(),selector:j(t),tagName:t.tagName.toLowerCase(),text:(t.textContent||"").trim().slice(0,100),position:{x:e.clientX,y:e.clientY}};this.clicks.push(o),this.eventBus.emit("click:captured",o),this.eventBus.emit("breadcrumb:added",{category:"click",message:`Clicked ${o.tagName} "${o.text}"`,data:{selector:o.selector}})},document.addEventListener("click",this.handler,!0)}getClickTrail(){return this.clicks.toArray()}teardown(){this.handler&&(document.removeEventListener("click",this.handler,!0),this.handler=null),this.clicks.clear()}};var C=class{constructor(e){this.getMeta=e;this.name="context"}setup(){}teardown(){}snapshot(){let e=this.getMeta?.();return{url:window.location.href,referrer:document.referrer,userAgent:navigator.userAgent,language:navigator.language,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:window.screen.width,height:window.screen.height},devicePixelRatio:window.devicePixelRatio||1,timestamp:new Date().toISOString(),memory:performance.memory?{usedJSHeapSize:performance.memory.usedJSHeapSize,totalJSHeapSize:performance.memory.totalJSHeapSize}:void 0,user:e?.user,tags:e?.tags}}};var S=class{constructor(e){this.eventBus=e;this.name="interactions";this.handlers=[];this.scrollTimer=null;this.resizeTimer=null}setup(){this.addHandler(window,"scroll",this.onScroll.bind(this),{passive:!0,capture:!0}),this.addHandler(document,"input",this.onInput.bind(this),!0),this.addHandler(document,"change",this.onChange.bind(this),!0),this.addHandler(window,"popstate",this.onPopState.bind(this)),this.addHandler(window,"hashchange",this.onHashChange.bind(this)),this.addHandler(document,"visibilitychange",this.onVisibilityChange.bind(this)),this.addHandler(window,"resize",this.onResize.bind(this),{passive:!0})}addHandler(e,t,o,n){e.addEventListener(t,o,n),this.handlers.push({target:e,event:t,handler:o})}onScroll(){this.scrollTimer&&clearTimeout(this.scrollTimer),this.scrollTimer=setTimeout(()=>{this.eventBus.emit("breadcrumb:added",{category:"interaction",message:"Scrolled",data:{x:window.scrollX,y:window.scrollY}})},300)}onInput(e){let t=e.target;if(!t)return;let o=t.tagName.toLowerCase(),n=t.id?`#${t.id}`:"",i=t.type?`[type="${t.type}"]`:"";this.eventBus.emit("breadcrumb:added",{category:"interaction",message:`Input on ${o}${n}${i}`})}onChange(e){let t=e.target;if(!t)return;let o=t.tagName.toLowerCase(),n=t.id?`#${t.id}`:"";this.eventBus.emit("breadcrumb:added",{category:"interaction",message:`Change on ${o}${n}`})}onPopState(){this.eventBus.emit("breadcrumb:added",{category:"navigation",message:`Navigated to ${window.location.href}`})}onHashChange(){this.eventBus.emit("breadcrumb:added",{category:"navigation",message:`Hash changed to ${window.location.hash}`})}onVisibilityChange(){this.eventBus.emit("breadcrumb:added",{category:"visibility",message:document.hidden?"Tab hidden":"Tab visible"})}onResize(){this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=setTimeout(()=>{this.eventBus.emit("breadcrumb:added",{category:"interaction",message:"Window resized",data:{width:window.innerWidth,height:window.innerHeight}})},300)}teardown(){this.scrollTimer&&clearTimeout(this.scrollTimer),this.resizeTimer&&clearTimeout(this.resizeTimer),this.handlers.forEach(({target:e,event:t,handler:o})=>{e.removeEventListener(t,o)}),this.handlers=[]}};var B=class{constructor(e){this.eventBus=e;this.name="performance";this.observers=[]}setup(){typeof PerformanceObserver>"u"||(this.observe("longtask",e=>{e.forEach(t=>{if(t.duration<50)return;let o={kind:"performance",metric:"longtask",value:Math.round(t.duration),entries:[{name:t.name,duration:t.duration,startTime:t.startTime}]};this.eventBus.emit("performance:captured",o),this.eventBus.emit("breadcrumb:added",{category:"performance",message:`Long task: ${Math.round(t.duration)}ms`})})}),this.observe("largest-contentful-paint",e=>{let t=e[e.length-1];t&&this.eventBus.emit("breadcrumb:added",{category:"performance",message:`LCP: ${Math.round(t.startTime)}ms`,data:{value:t.startTime}})}),this.observe("paint",e=>{e.forEach(t=>{t.name==="first-contentful-paint"&&this.eventBus.emit("breadcrumb:added",{category:"performance",message:`FCP: ${Math.round(t.startTime)}ms`,data:{value:t.startTime}})})}),this.observe("layout-shift",e=>{e.forEach(t=>{let o=t.value;o>.1&&this.eventBus.emit("breadcrumb:added",{category:"performance",message:`Layout shift: ${o.toFixed(4)}`,data:{cls:o}})})}))}observe(e,t){try{let o=new PerformanceObserver(n=>{t(n.getEntries())});o.observe({type:e,buffered:!0}),this.observers.push(o)}catch{}}teardown(){this.observers.forEach(e=>e.disconnect()),this.observers=[]}};function U(){let r=performance.memory;return!r||typeof r.usedJSHeapSize!="number"?null:r}var R=class{constructor(e){this.eventBus=e;this.name="memory";this.intervalId=null;this.baselineUsed=null}setup(){let e=U();e&&(this.baselineUsed=e.usedJSHeapSize,this.intervalId=setInterval(()=>{let t=U();if(!t)return;let o=t.usedJSHeapSize/t.jsHeapSizeLimit,n=this.baselineUsed>0?(t.usedJSHeapSize-this.baselineUsed)/this.baselineUsed:0;this.eventBus.emit("breadcrumb:added",{category:"memory",message:`Heap: ${(o*100).toFixed(1)}% used (${(t.usedJSHeapSize/1048576).toFixed(1)}MB)`,data:{usedJSHeapSize:t.usedJSHeapSize,jsHeapSizeLimit:t.jsHeapSizeLimit}});let i=o>=.9,s=n>=.5;if(i||s){let a={kind:"memory",message:i?`Heap usage critical: ${(o*100).toFixed(1)}% of limit`:`Heap growth spike: ${(n*100).toFixed(1)}% since init`,usedJSHeapSize:t.usedJSHeapSize,totalJSHeapSize:t.totalJSHeapSize,jsHeapSizeLimit:t.jsHeapSizeLimit,heapUsagePercent:o,heapGrowthPercent:n};this.eventBus.emit("memory:captured",a)}},1e4))}teardown(){this.intervalId!==null&&(clearInterval(this.intervalId),this.intervalId=null),this.baselineUsed=null}};var D=`
:host {

@@ -204,2 +204,12 @@ all: initial;

.gb-type-performance {
background: #e8f5e9;
color: #2e7d32;
}
.gb-type-memory {
background: #f3e5f5;
color: #6a1b9a;
}
.gb-report-message {

@@ -247,4 +257,4 @@ font-size: 13px;

}
`;var tt='<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5s-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z"/></svg>';function j(){let e=document.createElement("button");e.className="gb-fab",e.setAttribute("aria-label","ghostbug - bug reports");let t=document.createElement("span");t.innerHTML=tt,e.appendChild(t);let o=document.createElement("span");return o.className="gb-badge",o.setAttribute("data-count","0"),o.textContent="0",e.appendChild(o),e}function I(e){let t=document.createElement("div");t.className=`gb-panel gb-pos-${e}`;let o=document.createElement("div");o.className="gb-header";let r=document.createElement("span");r.className="gb-header-title",r.textContent="ghostbug",o.appendChild(r);let n=document.createElement("button");n.className="gb-header-btn gb-copy-btn",n.textContent="Copy MD",o.appendChild(n);let s=document.createElement("button");s.className="gb-header-btn gb-download-btn",s.textContent="Export",o.appendChild(s);let i=document.createElement("button");i.className="gb-close-btn",i.textContent="\xD7",i.setAttribute("aria-label","Close"),o.appendChild(i),t.appendChild(o);let l=document.createElement("div");l.className="gb-report-list";let a=document.createElement("div");return a.className="gb-empty",a.textContent="No bugs captured yet.",l.appendChild(a),t.appendChild(l),t}function _(e){let t=document.createElement("div");t.className="gb-report-item";let o=document.createElement("span");if(o.className=`gb-report-type gb-type-${e.payload.kind==="error"?"error":e.payload.kind}`,o.textContent=e.type,t.appendChild(o),e.count>1){let i=document.createElement("span");i.className="gb-report-count",i.textContent=`\xD7${e.count}`,t.appendChild(i)}let r=document.createElement("div");r.className="gb-report-message",r.textContent=et(e),t.appendChild(r);let n=document.createElement("div");n.className="gb-report-meta";let s=e.timestamp.split("T")[1]?.split(".")[0]||e.timestamp;return n.textContent=`${s} \xB7 ${e.context.url}`,t.appendChild(n),t}function et(e){switch(e.payload.kind){case"error":return e.payload.message;case"console":return e.payload.args.join(", ");case"network":return`${e.payload.method} ${e.payload.url} \u2192 ${e.payload.status}`}}function R(e){return g({generator:"ghostbug",version:f,exportedAt:new Date().toISOString(),reportCount:e.length,reports:e},2)}function B(e){let t=[];return t.push(`# Bug Report \u2014 ghostbug v${f}`),t.push(`**Generated:** ${new Date().toISOString()}`),t.push(`**Reports:** ${e.length}`),t.push(""),t.push("---"),t.push(""),e.forEach((o,r)=>{t.push(`## ${r+1}. ${ot(o)}`),t.push(""),t.push(`- **Type:** ${o.type}`),t.push(`- **Time:** ${o.timestamp}`),t.push(`- **Occurrences:** ${o.count}`),t.push(`- **URL:** ${o.context.url}`),t.push(`- **Browser:** ${nt(o.context.userAgent)}`),t.push(`- **Viewport:** ${o.context.viewport.width}x${o.context.viewport.height}`),t.push(""),t.push(...rt(o.payload)),t.push(""),o.breadcrumbs.length>0&&(t.push("### Breadcrumbs"),t.push(""),t.push("| Time | Category | Event |"),t.push("|------|----------|-------|"),o.breadcrumbs.forEach(n=>{let s=n.timestamp.split("T")[1]?.split(".")[0]||n.timestamp;t.push(`| ${s} | ${n.category} | ${n.message} |`)}),t.push("")),t.push("---"),t.push("")}),t.join(`
`)}function ot(e){switch(e.payload.kind){case"error":return`${e.payload.name||"Error"}: ${e.payload.message}`;case"console":return`Console ${e.payload.level}: ${e.payload.args[0]||""}`;case"network":return`${e.payload.method} ${e.payload.url} \u2192 ${e.payload.status}`}}function rt(e){let t=[];switch(e.kind){case"error":e.stack&&(t.push("### Stack Trace"),t.push(""),t.push("```"),t.push(e.stack),t.push("```")),e.filename&&t.push(`**File:** ${e.filename}:${e.lineno}:${e.colno}`);break;case"console":t.push("### Console Output"),t.push(""),t.push("```"),e.args.forEach(o=>t.push(o)),t.push("```");break;case"network":t.push("### Network Details"),t.push(""),t.push(`- **Method:** ${e.method}`),t.push(`- **URL:** ${e.url}`),t.push(`- **Status:** ${e.status} ${e.statusText}`),t.push(`- **Duration:** ${e.duration}ms`);break}return t}function nt(e){if(e.includes("Chrome")){let t=e.match(/Chrome\/(\d+)/);return t?`Chrome ${t[1]}`:"Chrome"}if(e.includes("Firefox")){let t=e.match(/Firefox\/(\d+)/);return t?`Firefox ${t[1]}`:"Firefox"}if(e.includes("Safari")&&!e.includes("Chrome")){let t=e.match(/Version\/(\d+)/);return t?`Safari ${t[1]}`:"Safari"}return e.slice(0,50)}var S=class{constructor(t,o,r){this.eventBus=t;this.reportManager=o;this.options=r;this.hostElement=null;this.shadowRoot=null;this.panel=null;this.badge=null;this.reportList=null;this.isExpanded=!1;this.unsubscribers=[]}mount(){this.hostElement=document.createElement("div"),this.hostElement.id="ghostbug-widget";let t=this.hostElement.style;t.position="fixed",t.zIndex=String(this.options.zIndex),t.margin="0",t.padding="0",this.applyPosition(t),this.shadowRoot=this.hostElement.attachShadow({mode:"closed"});let o=document.createElement("style");o.textContent=A,this.shadowRoot.appendChild(o);let r=document.createElement("div");r.className="gb-container";let n=j();this.badge=n.querySelector(".gb-badge"),n.addEventListener("click",()=>this.toggle()),r.appendChild(n),this.panel=I(this.options.position),r.appendChild(this.panel),this.panel.querySelector(".gb-close-btn")?.addEventListener("click",()=>this.toggle()),this.panel.querySelector(".gb-copy-btn")?.addEventListener("click",()=>this.copyMarkdown()),this.panel.querySelector(".gb-download-btn")?.addEventListener("click",()=>this.downloadJSON()),this.reportList=this.panel.querySelector(".gb-report-list"),this.shadowRoot.appendChild(r),document.body.appendChild(this.hostElement),this.unsubscribers.push(this.eventBus.on("report:created",()=>this.update()),this.eventBus.on("report:deduplicated",()=>this.update())),this.options.collapsed||this.toggle()}applyPosition(t){let o=this.options.position;t.top=o.startsWith("top")?"16px":"auto",t.bottom=o.startsWith("bottom")?"16px":"auto",t.left=o.endsWith("left")?"16px":"auto",t.right=o.endsWith("right")?"16px":"auto"}toggle(){this.isExpanded=!this.isExpanded,this.isExpanded?(this.panel?.classList.add("gb-open"),this.renderReportList()):this.panel?.classList.remove("gb-open")}update(){this.updateBadge(),this.isExpanded&&this.renderReportList()}updateBadge(){if(!this.badge)return;let t=this.reportManager.reportCount;this.badge.textContent=String(t),this.badge.setAttribute("data-count",String(t))}renderReportList(){if(!this.reportList)return;this.reportList.textContent="";let t=this.reportManager.getReports();if(t.length===0){let r=document.createElement("div");r.className="gb-empty",r.textContent="No bugs captured yet.",this.reportList.appendChild(r);return}[...t].reverse().forEach(r=>{let n=_(r);this.reportList.appendChild(n)})}copyMarkdown(){let t=B(this.reportManager.getReports());navigator.clipboard.writeText(t).then(()=>this.showToast("Copied to clipboard!"),()=>this.showToast("Copy failed"))}downloadJSON(){let t=R(this.reportManager.getReports()),o=new Blob([t],{type:"application/json"}),r=URL.createObjectURL(o),n=document.createElement("a");n.href=r,n.download="ghostbug-report.json",n.click(),URL.revokeObjectURL(r)}showToast(t){if(!this.shadowRoot)return;let o=document.createElement("div");o.className="gb-toast",o.textContent=t,this.shadowRoot.appendChild(o),requestAnimationFrame(()=>{o.classList.add("gb-show")}),setTimeout(()=>{o.classList.remove("gb-show"),setTimeout(()=>o.remove(),300)},2e3)}unmount(){this.unsubscribers.forEach(t=>t()),this.unsubscribers=[],this.hostElement?.remove(),this.hostElement=null,this.shadowRoot=null,this.panel=null,this.badge=null,this.reportList=null}};var p=null,m=null,u=[],L=null,$=new Set,O=!1;function it(e,t){return t?{maxReports:t.maxReports??e.maxReports,maxBreadcrumbs:t.maxBreadcrumbs??e.maxBreadcrumbs,maxClicks:t.maxClicks??e.maxClicks,widget:t.widget??e.widget,collectors:{...e.collectors,...t.collectors},rateLimit:{...e.rateLimit,...t.rateLimit},beforeReport:t.beforeReport??e.beforeReport,debug:t.debug??e.debug}:{...e}}function q(e){if(O){e?.debug&&console.warn("[ghostbug] Already initialized. Call destroy() first.");return}let t=it(P,e);p=new b;let o=new C;if(m=new v(p,o,t),t.collectors.errors&&u.push(new w(p)),t.collectors.console&&u.push(new x(p)),t.collectors.network&&u.push(new E(p)),t.collectors.clicks&&u.push(new k(p,t.maxClicks)),u.push(o),u.forEach(r=>r.setup()),p.on("report:created",r=>{$.forEach(n=>{try{n(r)}catch{}})}),t.widget){let r=typeof t.widget=="object"?{position:t.widget.position||"bottom-right",collapsed:t.widget.collapsed??!0,zIndex:t.widget.zIndex??2147483647}:{position:"bottom-right",collapsed:!0,zIndex:2147483647};L=new S(p,m,r),L.mount()}O=!0}function F(){return N(),m.getReports()}function X(e="ghostbug-report.json"){N();let t=R(m.getReports()),o=new Blob([t],{type:"application/json"}),r=URL.createObjectURL(o),n=document.createElement("a");n.href=r,n.download=e,n.click(),URL.revokeObjectURL(r)}function D(){return N(),B(m.getReports())}function U(e){return $.add(e),()=>$.delete(e)}function W(){L?.unmount(),L=null,u.forEach(e=>e.teardown()),u=[],p?.clear(),p=null,m?.clear(),m=null,$.clear(),O=!1}function N(){if(!O)throw new Error("[ghostbug] Not initialized. Call ghostbug.init() first.")}var st={init:q,getReports:F,download:X,toMarkdown:D,onBug:U,destroy:W};return Q(at);})();
`;var ce='<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5s-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z"/></svg>';function G(){let r=document.createElement("button");r.className="gb-fab",r.setAttribute("aria-label","ghostbug - bug reports");let e=document.createElement("span");e.innerHTML=ce,r.appendChild(e);let t=document.createElement("span");return t.className="gb-badge",t.setAttribute("data-count","0"),t.textContent="0",r.appendChild(t),r}function X(r){let e=document.createElement("div");e.className=`gb-panel gb-pos-${r}`;let t=document.createElement("div");t.className="gb-header";let o=document.createElement("span");o.className="gb-header-title",o.textContent="ghostbug",t.appendChild(o);let n=document.createElement("button");n.className="gb-header-btn gb-copy-btn",n.textContent="Copy MD",t.appendChild(n);let i=document.createElement("button");i.className="gb-header-btn gb-download-btn",i.textContent="Export",t.appendChild(i);let s=document.createElement("button");s.className="gb-close-btn",s.textContent="\xD7",s.setAttribute("aria-label","Close"),t.appendChild(s),e.appendChild(t);let l=document.createElement("div");l.className="gb-report-list";let a=document.createElement("div");return a.className="gb-empty",a.textContent="No bugs captured yet.",l.appendChild(a),e.appendChild(l),e}function q(r){let e=document.createElement("div");e.className="gb-report-item";let t=document.createElement("span");if(t.className=`gb-report-type gb-type-${r.payload.kind==="error"?"error":r.payload.kind}`,t.textContent=r.type,e.appendChild(t),r.count>1){let s=document.createElement("span");s.className="gb-report-count",s.textContent=`\xD7${r.count}`,e.appendChild(s)}let o=document.createElement("div");o.className="gb-report-message",o.textContent=de(r),e.appendChild(o);let n=document.createElement("div");n.className="gb-report-meta";let i=r.timestamp.split("T")[1]?.split(".")[0]||r.timestamp;return n.textContent=`${i} \xB7 ${r.context.url}`,e.appendChild(n),e}function de(r){switch(r.payload.kind){case"error":return r.payload.message;case"console":return r.payload.args.join(", ");case"network":return`${r.payload.method} ${r.payload.url} \u2192 ${r.payload.status}`;case"performance":return`${r.payload.metric}: ${r.payload.value}ms`;case"memory":return r.payload.message}}function T(r){return g({generator:"ghostbug",version:f,exportedAt:new Date().toISOString(),reportCount:r.length,reports:r},2)}function L(r){let e=[];return e.push(`# Bug Report \u2014 ghostbug v${f}`),e.push(`**Generated:** ${new Date().toISOString()}`),e.push(`**Reports:** ${r.length}`),e.push(""),e.push("---"),e.push(""),r.forEach((t,o)=>{e.push(`## ${o+1}. ${pe(t)}`),e.push(""),e.push(`- **Type:** ${t.type}`),e.push(`- **Time:** ${t.timestamp}`),e.push(`- **Occurrences:** ${t.count}`),e.push(`- **URL:** ${t.context.url}`),e.push(`- **Browser:** ${me(t.context.userAgent)}`),e.push(`- **Viewport:** ${t.context.viewport.width}x${t.context.viewport.height}`),e.push(""),e.push(...ue(t.payload)),e.push(""),t.breadcrumbs.length>0&&(e.push("### Breadcrumbs"),e.push(""),e.push("| Time | Category | Event |"),e.push("|------|----------|-------|"),t.breadcrumbs.forEach(n=>{let i=n.timestamp.split("T")[1]?.split(".")[0]||n.timestamp;e.push(`| ${i} | ${n.category} | ${n.message} |`)}),e.push("")),e.push("---"),e.push("")}),e.join(`
`)}function pe(r){switch(r.payload.kind){case"error":return`${r.payload.name||"Error"}: ${r.payload.message}`;case"console":return`Console ${r.payload.level}: ${r.payload.args[0]||""}`;case"network":return`${r.payload.method} ${r.payload.url} \u2192 ${r.payload.status}`;case"performance":return`Performance: ${r.payload.metric} ${r.payload.value}ms`;case"memory":return`Memory: ${r.payload.message}`}}function ue(r){let e=[];switch(r.kind){case"error":r.stack&&(e.push("### Stack Trace"),e.push(""),e.push("```"),e.push(r.stack),e.push("```")),r.filename&&e.push(`**File:** ${r.filename}:${r.lineno}:${r.colno}`);break;case"console":e.push("### Console Output"),e.push(""),e.push("```"),r.args.forEach(t=>e.push(t)),e.push("```");break;case"network":e.push("### Network Details"),e.push(""),e.push(`- **Method:** ${r.method}`),e.push(`- **URL:** ${r.url}`),e.push(`- **Status:** ${r.status} ${r.statusText}`),e.push(`- **Duration:** ${r.duration}ms`);break;case"performance":e.push("### Performance Details"),e.push(""),e.push(`- **Metric:** ${r.metric}`),e.push(`- **Value:** ${r.value}ms`),r.entries.length>0&&e.push(`- **Start Time:** ${Math.round(r.entries[0].startTime)}ms`);break;case"memory":e.push("### Memory Details"),e.push(""),e.push(`- **Used:** ${(r.usedJSHeapSize/1048576).toFixed(1)}MB`),e.push(`- **Limit:** ${(r.jsHeapSizeLimit/1048576).toFixed(1)}MB`),e.push(`- **Usage:** ${(r.heapUsagePercent*100).toFixed(1)}%`),e.push(`- **Growth since init:** ${(r.heapGrowthPercent*100).toFixed(1)}%`);break}return e}function me(r){if(r.includes("Chrome")){let e=r.match(/Chrome\/(\d+)/);return e?`Chrome ${e[1]}`:"Chrome"}if(r.includes("Firefox")){let e=r.match(/Firefox\/(\d+)/);return e?`Firefox ${e[1]}`:"Firefox"}if(r.includes("Safari")&&!r.includes("Chrome")){let e=r.match(/Version\/(\d+)/);return e?`Safari ${e[1]}`:"Safari"}return r.slice(0,50)}var P=class{constructor(e,t,o){this.eventBus=e;this.reportManager=t;this.options=o;this.hostElement=null;this.shadowRoot=null;this.panel=null;this.badge=null;this.reportList=null;this.isExpanded=!1;this.unsubscribers=[]}mount(){this.hostElement=document.createElement("div"),this.hostElement.id="ghostbug-widget";let e=this.hostElement.style;e.position="fixed",e.zIndex=String(this.options.zIndex),e.margin="0",e.padding="0",this.applyPosition(e),this.shadowRoot=this.hostElement.attachShadow({mode:"closed"});let t=document.createElement("style");t.textContent=D,this.shadowRoot.appendChild(t);let o=document.createElement("div");o.className="gb-container";let n=G();this.badge=n.querySelector(".gb-badge"),n.addEventListener("click",()=>this.toggle()),o.appendChild(n),this.panel=X(this.options.position),o.appendChild(this.panel),this.panel.querySelector(".gb-close-btn")?.addEventListener("click",()=>this.toggle()),this.panel.querySelector(".gb-copy-btn")?.addEventListener("click",()=>this.copyMarkdown()),this.panel.querySelector(".gb-download-btn")?.addEventListener("click",()=>this.downloadJSON()),this.reportList=this.panel.querySelector(".gb-report-list"),this.shadowRoot.appendChild(o),document.body.appendChild(this.hostElement),this.unsubscribers.push(this.eventBus.on("report:created",()=>this.update()),this.eventBus.on("report:deduplicated",()=>this.update())),this.options.collapsed||this.toggle()}applyPosition(e){let t=this.options.position;e.top=t.startsWith("top")?"16px":"auto",e.bottom=t.startsWith("bottom")?"16px":"auto",e.left=t.endsWith("left")?"16px":"auto",e.right=t.endsWith("right")?"16px":"auto"}toggle(){this.isExpanded=!this.isExpanded,this.isExpanded?(this.panel?.classList.add("gb-open"),this.renderReportList()):this.panel?.classList.remove("gb-open")}update(){this.updateBadge(),this.isExpanded&&this.renderReportList()}updateBadge(){if(!this.badge)return;let e=this.reportManager.reportCount;this.badge.textContent=String(e),this.badge.setAttribute("data-count",String(e))}renderReportList(){if(!this.reportList)return;this.reportList.textContent="";let e=this.reportManager.getReports();if(e.length===0){let o=document.createElement("div");o.className="gb-empty",o.textContent="No bugs captured yet.",this.reportList.appendChild(o);return}[...e].reverse().forEach(o=>{let n=q(o);this.reportList.appendChild(n)})}copyMarkdown(){let e=L(this.reportManager.getReports());navigator.clipboard.writeText(e).then(()=>this.showToast("Copied to clipboard!"),()=>this.showToast("Copy failed"))}downloadJSON(){let e=T(this.reportManager.getReports()),t=new Blob([e],{type:"application/json"}),o=URL.createObjectURL(t),n=document.createElement("a");n.href=o,n.download="ghostbug-report.json",n.click(),URL.revokeObjectURL(o)}showToast(e){if(!this.shadowRoot)return;let t=document.createElement("div");t.className="gb-toast",t.textContent=e,this.shadowRoot.appendChild(t),requestAnimationFrame(()=>{t.classList.add("gb-show")}),setTimeout(()=>{t.classList.remove("gb-show"),setTimeout(()=>t.remove(),300)},2e3)}unmount(){this.unsubscribers.forEach(e=>e()),this.unsubscribers=[],this.hostElement?.remove(),this.hostElement=null,this.shadowRoot=null,this.panel=null,this.badge=null,this.reportList=null}};var c=null,h=null,d=[],H=null,$=new Set,M=!1,N,O;function he(r,e){return e?{maxReports:e.maxReports??r.maxReports,maxBreadcrumbs:e.maxBreadcrumbs??r.maxBreadcrumbs,maxClicks:e.maxClicks??r.maxClicks,widget:e.widget??r.widget,collectors:{...r.collectors,...e.collectors},rateLimit:{...r.rateLimit,...e.rateLimit},beforeReport:e.beforeReport??r.beforeReport,debug:e.debug??r.debug,screenshotFn:e.screenshotFn}:{...r}}function W(r){if(M){r?.debug&&console.warn("[ghostbug] Already initialized. Call destroy() first.");return}let e=he(I,r);c=new b;let t=new C(()=>({user:N,tags:O}));if(h=new y(c,t,e),e.collectors.errors&&d.push(new w(c)),e.collectors.console&&d.push(new x(c)),e.collectors.network&&d.push(new E(c)),e.collectors.clicks&&d.push(new k(c,e.maxClicks)),e.collectors.interactions&&d.push(new S(c)),e.collectors.performance&&d.push(new B(c)),e.collectors.memory&&d.push(new R(c)),d.push(t),d.forEach(o=>o.setup()),c.on("report:created",o=>{$.forEach(n=>{try{n(o)}catch{}})}),e.widget){let o=typeof e.widget=="object"?{position:e.widget.position||"bottom-right",collapsed:e.widget.collapsed??!0,zIndex:e.widget.zIndex??2147483647}:{position:"bottom-right",collapsed:!0,zIndex:2147483647};H=new P(c,h,o),H.mount()}M=!0}function J(){return _(),h.getReports()}function V(r="ghostbug-report.json"){_();let e=T(h.getReports()),t=new Blob([e],{type:"application/json"}),o=URL.createObjectURL(t),n=document.createElement("a");n.href=o,n.download=r,n.click(),URL.revokeObjectURL(o)}function Y(){return _(),L(h.getReports())}function K(r){return $.add(r),()=>$.delete(r)}function Q(r){N=r}function Z(r){O={...O,...r}}function ee(){H?.unmount(),H=null,d.forEach(r=>r.teardown()),d=[],c?.clear(),c=null,h?.clear(),h=null,$.clear(),N=void 0,O=void 0,M=!1}function _(){if(!M)throw new Error("[ghostbug] Not initialized. Call ghostbug.init() first.")}var ge={init:W,getReports:J,download:V,toMarkdown:Y,onBug:K,setUser:Q,setTags:Z,destroy:ee};return se(fe);})();
//# sourceMappingURL=index.iife.js.map

@@ -1,3 +0,3 @@

var f="0.1.0",N={maxReports:50,maxBreadcrumbs:20,maxClicks:20,widget:false,collectors:{errors:true,console:true,network:true,clicks:true},rateLimit:{maxEvents:10,windowMs:1e3},beforeReport:e=>e,debug:false};var b=class{constructor(){this.listeners=new Map;}on(t,o){return this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(o),()=>this.off(t,o)}off(t,o){this.listeners.get(t)?.delete(o);}emit(t,o){this.listeners.get(t)?.forEach(r=>{try{r(o);}catch{}});}clear(){this.listeners.clear();}};var h=class{constructor(t){this.capacity=t;this.head=0;this._size=0;this.buffer=new Array(t);}push(t){this.buffer[this.head]=t,this.head=(this.head+1)%this.capacity,this._size<this.capacity&&this._size++;}toArray(){if(this._size===0)return [];let t=[],o=this._size<this.capacity?0:this.head;for(let r=0;r<this._size;r++){let n=(o+r)%this.capacity;t.push(this.buffer[n]);}return t}get size(){return this._size}get isFull(){return this._size===this.capacity}peek(){if(this._size===0)return;let t=(this.head-1+this.capacity)%this.capacity;return this.buffer[t]}find(t){return this.toArray().find(t)}forEach(t){this.toArray().forEach(t);}clear(){this.buffer=new Array(this.capacity),this.head=0,this._size=0;}};var y=class{constructor(t,o){this.maxEvents=t;this.windowMs=o;this.timestamps=[];}allow(){let t=Date.now();return this.timestamps=this.timestamps.filter(o=>t-o<this.windowMs),this.timestamps.length>=this.maxEvents?false:(this.timestamps.push(t),true)}reset(){this.timestamps=[];}};function _(e){let t=5381;for(let o=0;o<e.length;o++)t=(t<<5)+t+e.charCodeAt(o)&4294967295;return (t>>>0).toString(36)}function P(e){let t;switch(e.kind){case "error":{let o=e.stack?.split(`
`)[1]?.trim()||"";t=`${e.name}:${e.message}:${o}`;break}case "console":t=`console:${e.level}:${e.args.join(",")}`;break;case "network":t=`network:${e.method}:${e.url}:${e.status}`;break}return _(t)}function M(){let e=new Uint8Array(8);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(36).padStart(2,"0")).join("").slice(0,12)}var v=class{constructor(t,o,r){this.eventBus=t;this.contextCollector=o;this.options=r;this.unsubscribers=[];this.reports=new h(r.maxReports),this.breadcrumbs=new h(r.maxBreadcrumbs),this.rateLimiter=new y(r.rateLimit.maxEvents,r.rateLimit.windowMs),this.subscribe();}subscribe(){this.unsubscribers.push(this.eventBus.on("error:captured",t=>{this.addBreadcrumb({category:"error",message:t.message}),this.handleCapturedEvent("error",t);}),this.eventBus.on("console:captured",t=>{this.addBreadcrumb({category:"console",message:`console.${t.level}: ${t.args.join(", ")}`}),t.level==="error"&&this.handleCapturedEvent("console",t);}),this.eventBus.on("network:captured",t=>{this.handleCapturedEvent("network",t);}),this.eventBus.on("breadcrumb:added",t=>{this.addBreadcrumb(t);}));}handleCapturedEvent(t,o){if(!this.rateLimiter.allow())return;let r=P(o),n=this.reports.find(l=>l.fingerprint===r);if(n){n.count++,n.timestamp=new Date().toISOString(),this.eventBus.emit("report:deduplicated",n);return}let s={id:M(),fingerprint:r,type:t,timestamp:new Date().toISOString(),count:1,payload:o,breadcrumbs:this.breadcrumbs.toArray(),context:this.contextCollector.snapshot()},i=this.options.beforeReport(s);i&&(s=i,this.reports.push(s),this.eventBus.emit("report:created",s));}addBreadcrumb(t){this.breadcrumbs.push({...t,timestamp:new Date().toISOString()});}getReports(){return this.reports.toArray()}clear(){this.reports.clear(),this.breadcrumbs.clear(),this.unsubscribers.forEach(t=>t()),this.unsubscribers=[];}get reportCount(){return this.reports.size}};var w=class{constructor(t){this.eventBus=t;this.name="error";this.originalOnError=null;this.rejectionHandler=null;}setup(){this.originalOnError=window.onerror,window.onerror=(t,o,r,n,s)=>{let i={kind:"error",message:String(t),stack:s?.stack,filename:o??void 0,lineno:r??void 0,colno:n??void 0,name:s?.name};return this.eventBus.emit("error:captured",i),this.originalOnError?this.originalOnError.call(window,t,o,r,n,s):false},this.rejectionHandler=t=>{let o=t.reason,r={kind:"error",message:o instanceof Error?o.message:String(o),stack:o instanceof Error?o.stack:void 0,name:o instanceof Error?o.name:"UnhandledRejection"};this.eventBus.emit("error:captured",r);},window.addEventListener("unhandledrejection",this.rejectionHandler);}teardown(){window.onerror=this.originalOnError,this.originalOnError=null,this.rejectionHandler&&(window.removeEventListener("unhandledrejection",this.rejectionHandler),this.rejectionHandler=null);}};function g(e,t){let o=new WeakSet;return JSON.stringify(e,(r,n)=>{if(typeof n=="object"&&n!==null){if(o.has(n))return "[Circular]";o.add(n);}return typeof n=="function"?"[Function]":typeof n=="symbol"?n.toString():n instanceof Error?{name:n.name,message:n.message,stack:n.stack}:n},t)}var x=class{constructor(t){this.eventBus=t;this.name="console";this.originalError=null;this.originalWarn=null;}setup(){this.originalError=console.error,this.originalWarn=console.warn,console.error=(...t)=>{let o={kind:"console",level:"error",args:t.map(r=>g(r))};this.eventBus.emit("console:captured",o),this.originalError.apply(console,t);},console.warn=(...t)=>{let o={kind:"console",level:"warn",args:t.map(r=>g(r))};this.eventBus.emit("console:captured",o),this.originalWarn.apply(console,t);};}teardown(){this.originalError&&(console.error=this.originalError),this.originalWarn&&(console.warn=this.originalWarn),this.originalError=null,this.originalWarn=null;}};var E=class{constructor(t){this.eventBus=t;this.name="network";this.originalFetch=null;this.originalXhrOpen=null;this.originalXhrSend=null;}setup(){this.patchFetch(),this.patchXHR();}patchFetch(){this.originalFetch=window.fetch;let t=this.eventBus,o=this.originalFetch;window.fetch=function(r,n){let s=n?.method?.toUpperCase()||"GET",i=typeof r=="string"?r:r instanceof URL?r.href:r.url,l=performance.now();return o.call(window,r,n).then(a=>{let c=Math.round(performance.now()-l);if(a.status>=400){let d={kind:"network",method:s,url:i,status:a.status,statusText:a.statusText,duration:c};t.emit("network:captured",d);}return t.emit("breadcrumb:added",{category:"network",message:`${s} ${i} -> ${a.status}`}),a},a=>{let c=Math.round(performance.now()-l),d={kind:"network",method:s,url:i,status:0,statusText:a.message||"Network Error",duration:c};throw t.emit("network:captured",d),a})};}patchXHR(){this.originalXhrOpen=XMLHttpRequest.prototype.open,this.originalXhrSend=XMLHttpRequest.prototype.send;let t=this.eventBus,o=this.originalXhrOpen,r=this.originalXhrSend;XMLHttpRequest.prototype.open=function(n,s,...i){return this.__ghostbug_method=n.toUpperCase(),this.__ghostbug_url=String(s),o.apply(this,[n,s,...i])},XMLHttpRequest.prototype.send=function(n){let s=performance.now(),i=this;return i.addEventListener("loadend",function(){let l=Math.round(performance.now()-s),a=i.__ghostbug_method||"UNKNOWN",c=i.__ghostbug_url||"";if(i.status>=400||i.status===0){let d={kind:"network",method:a,url:c,status:i.status,statusText:i.statusText,duration:l};t.emit("network:captured",d);}t.emit("breadcrumb:added",{category:"network",message:`${a} ${c} -> ${i.status}`});}),r.call(this,n)};}teardown(){this.originalFetch&&(window.fetch=this.originalFetch,this.originalFetch=null),this.originalXhrOpen&&(XMLHttpRequest.prototype.open=this.originalXhrOpen,this.originalXhrOpen=null),this.originalXhrSend&&(XMLHttpRequest.prototype.send=this.originalXhrSend,this.originalXhrSend=null);}};function H(e){if(e.id)return `#${e.id}`;let t=e.getAttribute("data-testid");if(t)return `[data-testid="${t}"]`;let o=[],r=e,n=0;for(;r&&r!==document.documentElement&&n<5;){let s=r.tagName.toLowerCase();if(r.id){o.unshift(`#${r.id}`);break}let i=Array.from(r.classList).slice(0,2);i.length>0&&(s+="."+i.join("."));let l=r.parentElement;if(l){let a=r.tagName,c=Array.from(l.children).filter(d=>d.tagName===a);if(c.length>1){let d=c.indexOf(r)+1;s+=`:nth-child(${d})`;}}o.unshift(s),r=l,n++;}return o.join(" > ")}var k=class{constructor(t,o){this.eventBus=t;this.name="click";this.handler=null;this.clicks=new h(o);}setup(){this.handler=t=>{let o=t.target;if(!o)return;let r={timestamp:new Date().toISOString(),selector:H(o),tagName:o.tagName.toLowerCase(),text:(o.textContent||"").trim().slice(0,100),position:{x:t.clientX,y:t.clientY}};this.clicks.push(r),this.eventBus.emit("click:captured",r),this.eventBus.emit("breadcrumb:added",{category:"click",message:`Clicked ${r.tagName} "${r.text}"`,data:{selector:r.selector}});},document.addEventListener("click",this.handler,true);}getClickTrail(){return this.clicks.toArray()}teardown(){this.handler&&(document.removeEventListener("click",this.handler,true),this.handler=null),this.clicks.clear();}};var C=class{constructor(){this.name="context";}setup(){}teardown(){}snapshot(){return {url:window.location.href,referrer:document.referrer,userAgent:navigator.userAgent,language:navigator.language,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:window.screen.width,height:window.screen.height},devicePixelRatio:window.devicePixelRatio||1,timestamp:new Date().toISOString(),memory:performance.memory?{usedJSHeapSize:performance.memory.usedJSHeapSize,totalJSHeapSize:performance.memory.totalJSHeapSize}:void 0}}};var z=`
var f="0.1.0",_={maxReports:50,maxBreadcrumbs:20,maxClicks:20,widget:false,collectors:{errors:true,console:true,network:true,clicks:true,interactions:true,performance:true,memory:true},rateLimit:{maxEvents:10,windowMs:1e3},beforeReport:r=>r,debug:false};var b=class{constructor(){this.listeners=new Map;}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>this.off(e,t)}off(e,t){this.listeners.get(e)?.delete(t);}emit(e,t){this.listeners.get(e)?.forEach(o=>{try{o(t);}catch{}});}clear(){this.listeners.clear();}};var m=class{constructor(e){this.capacity=e;this.head=0;this._size=0;this.buffer=new Array(e);}push(e){this.buffer[this.head]=e,this.head=(this.head+1)%this.capacity,this._size<this.capacity&&this._size++;}toArray(){if(this._size===0)return [];let e=[],t=this._size<this.capacity?0:this.head;for(let o=0;o<this._size;o++){let n=(t+o)%this.capacity;e.push(this.buffer[n]);}return e}get size(){return this._size}get isFull(){return this._size===this.capacity}peek(){if(this._size===0)return;let e=(this.head-1+this.capacity)%this.capacity;return this.buffer[e]}find(e){return this.toArray().find(e)}forEach(e){this.toArray().forEach(e);}clear(){this.buffer=new Array(this.capacity),this.head=0,this._size=0;}};var v=class{constructor(e,t){this.maxEvents=e;this.windowMs=t;this.timestamps=[];}allow(){let e=Date.now();return this.timestamps=this.timestamps.filter(t=>e-t<this.windowMs),this.timestamps.length>=this.maxEvents?false:(this.timestamps.push(e),true)}reset(){this.timestamps=[];}};function q(r){let e=5381;for(let t=0;t<r.length;t++)e=(e<<5)+e+r.charCodeAt(t)&4294967295;return (e>>>0).toString(36)}function I(r){let e;switch(r.kind){case "error":{let t=r.stack?.split(`
`)[1]?.trim()||"";e=`${r.name}:${r.message}:${t}`;break}case "console":e=`console:${r.level}:${r.args.join(",")}`;break;case "network":e=`network:${r.method}:${r.url}:${r.status}`;break;case "performance":e=`performance:${r.metric}:${Math.floor(r.value/100)*100}`;break;case "memory":e=`memory:${Math.floor(r.heapUsagePercent*10)/10}`;break}return q(e)}function A(){let r=new Uint8Array(8);return crypto.getRandomValues(r),Array.from(r,e=>e.toString(36).padStart(2,"0")).join("").slice(0,12)}var W=3e3,y=class{constructor(e,t,o){this.eventBus=e;this.contextCollector=t;this.options=o;this.unsubscribers=[];this.reports=new m(o.maxReports),this.breadcrumbs=new m(o.maxBreadcrumbs),this.rateLimiter=new v(o.rateLimit.maxEvents,o.rateLimit.windowMs),this.subscribe();}subscribe(){this.unsubscribers.push(this.eventBus.on("error:captured",e=>{this.addBreadcrumb({category:"error",message:e.message}),this.handleCapturedEvent("error",e);}),this.eventBus.on("console:captured",e=>{this.addBreadcrumb({category:"console",message:`console.${e.level}: ${e.args.join(", ")}`}),e.level==="error"&&this.handleCapturedEvent("console",e);}),this.eventBus.on("network:captured",e=>{this.handleCapturedEvent("network",e);}),this.eventBus.on("performance:captured",e=>{this.addBreadcrumb({category:"performance",message:`${e.metric}: ${e.value}ms`}),this.handleCapturedEvent("performance",e);}),this.eventBus.on("memory:captured",e=>{this.handleCapturedEvent("memory",e);}),this.eventBus.on("breadcrumb:added",e=>{this.addBreadcrumb(e);}));}async handleCapturedEvent(e,t){if(!this.rateLimiter.allow())return;let o=I(t),n=this.reports.find(l=>l.fingerprint===o);if(n){n.count++,n.timestamp=new Date().toISOString(),this.eventBus.emit("report:deduplicated",n);return}let i={id:A(),fingerprint:o,type:e,timestamp:new Date().toISOString(),count:1,payload:t,breadcrumbs:this.breadcrumbs.toArray(),context:this.contextCollector.snapshot()};if(this.options.screenshotFn)try{i.screenshot=await Promise.race([this.options.screenshotFn(),new Promise((l,a)=>setTimeout(()=>a(new Error("screenshot timeout")),W))]);}catch{}let s=this.options.beforeReport(i);s&&(i=s,this.reports.push(i),this.eventBus.emit("report:created",i));}addBreadcrumb(e){this.breadcrumbs.push({...e,timestamp:new Date().toISOString()});}getReports(){return this.reports.toArray()}clear(){this.reports.clear(),this.breadcrumbs.clear(),this.unsubscribers.forEach(e=>e()),this.unsubscribers=[];}get reportCount(){return this.reports.size}};var w=class{constructor(e){this.eventBus=e;this.name="error";this.originalOnError=null;this.rejectionHandler=null;}setup(){this.originalOnError=window.onerror,window.onerror=(e,t,o,n,i)=>{let s={kind:"error",message:String(e),stack:i?.stack,filename:t??void 0,lineno:o??void 0,colno:n??void 0,name:i?.name};return this.eventBus.emit("error:captured",s),this.originalOnError?this.originalOnError.call(window,e,t,o,n,i):false},this.rejectionHandler=e=>{let t=e.reason,o={kind:"error",message:t instanceof Error?t.message:String(t),stack:t instanceof Error?t.stack:void 0,name:t instanceof Error?t.name:"UnhandledRejection"};this.eventBus.emit("error:captured",o);},window.addEventListener("unhandledrejection",this.rejectionHandler);}teardown(){window.onerror=this.originalOnError,this.originalOnError=null,this.rejectionHandler&&(window.removeEventListener("unhandledrejection",this.rejectionHandler),this.rejectionHandler=null);}};function g(r,e){let t=new WeakSet;return JSON.stringify(r,(o,n)=>{if(typeof n=="object"&&n!==null){if(t.has(n))return "[Circular]";t.add(n);}return typeof n=="function"?"[Function]":typeof n=="symbol"?n.toString():n instanceof Error?{name:n.name,message:n.message,stack:n.stack}:n},e)}var x=class{constructor(e){this.eventBus=e;this.name="console";this.originalError=null;this.originalWarn=null;}setup(){this.originalError=console.error,this.originalWarn=console.warn,console.error=(...e)=>{let t={kind:"console",level:"error",args:e.map(o=>g(o))};this.eventBus.emit("console:captured",t),this.originalError.apply(console,e);},console.warn=(...e)=>{let t={kind:"console",level:"warn",args:e.map(o=>g(o))};this.eventBus.emit("console:captured",t),this.originalWarn.apply(console,e);};}teardown(){this.originalError&&(console.error=this.originalError),this.originalWarn&&(console.warn=this.originalWarn),this.originalError=null,this.originalWarn=null;}};var E=class{constructor(e){this.eventBus=e;this.name="network";this.originalFetch=null;this.originalXhrOpen=null;this.originalXhrSend=null;}setup(){this.patchFetch(),this.patchXHR();}patchFetch(){this.originalFetch=window.fetch;let e=this.eventBus,t=this.originalFetch;window.fetch=function(o,n){let i=n?.method?.toUpperCase()||"GET",s=typeof o=="string"?o:o instanceof URL?o.href:o.url,l=performance.now();return t.call(window,o,n).then(a=>{let p=Math.round(performance.now()-l);if(a.status>=400){let u={kind:"network",method:i,url:s,status:a.status,statusText:a.statusText,duration:p};e.emit("network:captured",u);}return e.emit("breadcrumb:added",{category:"network",message:`${i} ${s} -> ${a.status}`}),a},a=>{let p=Math.round(performance.now()-l),u={kind:"network",method:i,url:s,status:0,statusText:a.message||"Network Error",duration:p};throw e.emit("network:captured",u),a})};}patchXHR(){this.originalXhrOpen=XMLHttpRequest.prototype.open,this.originalXhrSend=XMLHttpRequest.prototype.send;let e=this.eventBus,t=this.originalXhrOpen,o=this.originalXhrSend;XMLHttpRequest.prototype.open=function(n,i,...s){return this.__ghostbug_method=n.toUpperCase(),this.__ghostbug_url=String(i),t.apply(this,[n,i,...s])},XMLHttpRequest.prototype.send=function(n){let i=performance.now(),s=this;return s.addEventListener("loadend",function(){let l=Math.round(performance.now()-i),a=s.__ghostbug_method||"UNKNOWN",p=s.__ghostbug_url||"";if(s.status>=400||s.status===0){let u={kind:"network",method:a,url:p,status:s.status,statusText:s.statusText,duration:l};e.emit("network:captured",u);}e.emit("breadcrumb:added",{category:"network",message:`${a} ${p} -> ${s.status}`});}),o.call(this,n)};}teardown(){this.originalFetch&&(window.fetch=this.originalFetch,this.originalFetch=null),this.originalXhrOpen&&(XMLHttpRequest.prototype.open=this.originalXhrOpen,this.originalXhrOpen=null),this.originalXhrSend&&(XMLHttpRequest.prototype.send=this.originalXhrSend,this.originalXhrSend=null);}};function F(r){if(r.id)return `#${r.id}`;let e=r.getAttribute("data-testid");if(e)return `[data-testid="${e}"]`;let t=[],o=r,n=0;for(;o&&o!==document.documentElement&&n<5;){let i=o.tagName.toLowerCase();if(o.id){t.unshift(`#${o.id}`);break}let s=Array.from(o.classList).slice(0,2);s.length>0&&(i+="."+s.join("."));let l=o.parentElement;if(l){let a=o.tagName,p=Array.from(l.children).filter(u=>u.tagName===a);if(p.length>1){let u=p.indexOf(o)+1;i+=`:nth-child(${u})`;}}t.unshift(i),o=l,n++;}return t.join(" > ")}var k=class{constructor(e,t){this.eventBus=e;this.name="click";this.handler=null;this.clicks=new m(t);}setup(){this.handler=e=>{let t=e.target;if(!t)return;let o={timestamp:new Date().toISOString(),selector:F(t),tagName:t.tagName.toLowerCase(),text:(t.textContent||"").trim().slice(0,100),position:{x:e.clientX,y:e.clientY}};this.clicks.push(o),this.eventBus.emit("click:captured",o),this.eventBus.emit("breadcrumb:added",{category:"click",message:`Clicked ${o.tagName} "${o.text}"`,data:{selector:o.selector}});},document.addEventListener("click",this.handler,true);}getClickTrail(){return this.clicks.toArray()}teardown(){this.handler&&(document.removeEventListener("click",this.handler,true),this.handler=null),this.clicks.clear();}};var C=class{constructor(e){this.getMeta=e;this.name="context";}setup(){}teardown(){}snapshot(){let e=this.getMeta?.();return {url:window.location.href,referrer:document.referrer,userAgent:navigator.userAgent,language:navigator.language,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:window.screen.width,height:window.screen.height},devicePixelRatio:window.devicePixelRatio||1,timestamp:new Date().toISOString(),memory:performance.memory?{usedJSHeapSize:performance.memory.usedJSHeapSize,totalJSHeapSize:performance.memory.totalJSHeapSize}:void 0,user:e?.user,tags:e?.tags}}};var S=class{constructor(e){this.eventBus=e;this.name="interactions";this.handlers=[];this.scrollTimer=null;this.resizeTimer=null;}setup(){this.addHandler(window,"scroll",this.onScroll.bind(this),{passive:true,capture:true}),this.addHandler(document,"input",this.onInput.bind(this),true),this.addHandler(document,"change",this.onChange.bind(this),true),this.addHandler(window,"popstate",this.onPopState.bind(this)),this.addHandler(window,"hashchange",this.onHashChange.bind(this)),this.addHandler(document,"visibilitychange",this.onVisibilityChange.bind(this)),this.addHandler(window,"resize",this.onResize.bind(this),{passive:true});}addHandler(e,t,o,n){e.addEventListener(t,o,n),this.handlers.push({target:e,event:t,handler:o});}onScroll(){this.scrollTimer&&clearTimeout(this.scrollTimer),this.scrollTimer=setTimeout(()=>{this.eventBus.emit("breadcrumb:added",{category:"interaction",message:"Scrolled",data:{x:window.scrollX,y:window.scrollY}});},300);}onInput(e){let t=e.target;if(!t)return;let o=t.tagName.toLowerCase(),n=t.id?`#${t.id}`:"",i=t.type?`[type="${t.type}"]`:"";this.eventBus.emit("breadcrumb:added",{category:"interaction",message:`Input on ${o}${n}${i}`});}onChange(e){let t=e.target;if(!t)return;let o=t.tagName.toLowerCase(),n=t.id?`#${t.id}`:"";this.eventBus.emit("breadcrumb:added",{category:"interaction",message:`Change on ${o}${n}`});}onPopState(){this.eventBus.emit("breadcrumb:added",{category:"navigation",message:`Navigated to ${window.location.href}`});}onHashChange(){this.eventBus.emit("breadcrumb:added",{category:"navigation",message:`Hash changed to ${window.location.hash}`});}onVisibilityChange(){this.eventBus.emit("breadcrumb:added",{category:"visibility",message:document.hidden?"Tab hidden":"Tab visible"});}onResize(){this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=setTimeout(()=>{this.eventBus.emit("breadcrumb:added",{category:"interaction",message:"Window resized",data:{width:window.innerWidth,height:window.innerHeight}});},300);}teardown(){this.scrollTimer&&clearTimeout(this.scrollTimer),this.resizeTimer&&clearTimeout(this.resizeTimer),this.handlers.forEach(({target:e,event:t,handler:o})=>{e.removeEventListener(t,o);}),this.handlers=[];}};var B=class{constructor(e){this.eventBus=e;this.name="performance";this.observers=[];}setup(){typeof PerformanceObserver>"u"||(this.observe("longtask",e=>{e.forEach(t=>{if(t.duration<50)return;let o={kind:"performance",metric:"longtask",value:Math.round(t.duration),entries:[{name:t.name,duration:t.duration,startTime:t.startTime}]};this.eventBus.emit("performance:captured",o),this.eventBus.emit("breadcrumb:added",{category:"performance",message:`Long task: ${Math.round(t.duration)}ms`});});}),this.observe("largest-contentful-paint",e=>{let t=e[e.length-1];t&&this.eventBus.emit("breadcrumb:added",{category:"performance",message:`LCP: ${Math.round(t.startTime)}ms`,data:{value:t.startTime}});}),this.observe("paint",e=>{e.forEach(t=>{t.name==="first-contentful-paint"&&this.eventBus.emit("breadcrumb:added",{category:"performance",message:`FCP: ${Math.round(t.startTime)}ms`,data:{value:t.startTime}});});}),this.observe("layout-shift",e=>{e.forEach(t=>{let o=t.value;o>.1&&this.eventBus.emit("breadcrumb:added",{category:"performance",message:`Layout shift: ${o.toFixed(4)}`,data:{cls:o}});});}));}observe(e,t){try{let o=new PerformanceObserver(n=>{t(n.getEntries());});o.observe({type:e,buffered:!0}),this.observers.push(o);}catch{}}teardown(){this.observers.forEach(e=>e.disconnect()),this.observers=[];}};function j(){let r=performance.memory;return !r||typeof r.usedJSHeapSize!="number"?null:r}var R=class{constructor(e){this.eventBus=e;this.name="memory";this.intervalId=null;this.baselineUsed=null;}setup(){let e=j();e&&(this.baselineUsed=e.usedJSHeapSize,this.intervalId=setInterval(()=>{let t=j();if(!t)return;let o=t.usedJSHeapSize/t.jsHeapSizeLimit,n=this.baselineUsed>0?(t.usedJSHeapSize-this.baselineUsed)/this.baselineUsed:0;this.eventBus.emit("breadcrumb:added",{category:"memory",message:`Heap: ${(o*100).toFixed(1)}% used (${(t.usedJSHeapSize/1048576).toFixed(1)}MB)`,data:{usedJSHeapSize:t.usedJSHeapSize,jsHeapSizeLimit:t.jsHeapSizeLimit}});let i=o>=.9,s=n>=.5;if(i||s){let a={kind:"memory",message:i?`Heap usage critical: ${(o*100).toFixed(1)}% of limit`:`Heap growth spike: ${(n*100).toFixed(1)}% since init`,usedJSHeapSize:t.usedJSHeapSize,totalJSHeapSize:t.totalJSHeapSize,jsHeapSizeLimit:t.jsHeapSizeLimit,heapUsagePercent:o,heapGrowthPercent:n};this.eventBus.emit("memory:captured",a);}},1e4));}teardown(){this.intervalId!==null&&(clearInterval(this.intervalId),this.intervalId=null),this.baselineUsed=null;}};var U=`
:host {

@@ -204,2 +204,12 @@ all: initial;

.gb-type-performance {
background: #e8f5e9;
color: #2e7d32;
}
.gb-type-memory {
background: #f3e5f5;
color: #6a1b9a;
}
.gb-report-message {

@@ -247,4 +257,4 @@ font-size: 13px;

}
`;var q='<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5s-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z"/></svg>';function A(){let e=document.createElement("button");e.className="gb-fab",e.setAttribute("aria-label","ghostbug - bug reports");let t=document.createElement("span");t.innerHTML=q,e.appendChild(t);let o=document.createElement("span");return o.className="gb-badge",o.setAttribute("data-count","0"),o.textContent="0",e.appendChild(o),e}function j(e){let t=document.createElement("div");t.className=`gb-panel gb-pos-${e}`;let o=document.createElement("div");o.className="gb-header";let r=document.createElement("span");r.className="gb-header-title",r.textContent="ghostbug",o.appendChild(r);let n=document.createElement("button");n.className="gb-header-btn gb-copy-btn",n.textContent="Copy MD",o.appendChild(n);let s=document.createElement("button");s.className="gb-header-btn gb-download-btn",s.textContent="Export",o.appendChild(s);let i=document.createElement("button");i.className="gb-close-btn",i.textContent="\xD7",i.setAttribute("aria-label","Close"),o.appendChild(i),t.appendChild(o);let l=document.createElement("div");l.className="gb-report-list";let a=document.createElement("div");return a.className="gb-empty",a.textContent="No bugs captured yet.",l.appendChild(a),t.appendChild(l),t}function I(e){let t=document.createElement("div");t.className="gb-report-item";let o=document.createElement("span");if(o.className=`gb-report-type gb-type-${e.payload.kind==="error"?"error":e.payload.kind}`,o.textContent=e.type,t.appendChild(o),e.count>1){let i=document.createElement("span");i.className="gb-report-count",i.textContent=`\xD7${e.count}`,t.appendChild(i);}let r=document.createElement("div");r.className="gb-report-message",r.textContent=F(e),t.appendChild(r);let n=document.createElement("div");n.className="gb-report-meta";let s=e.timestamp.split("T")[1]?.split(".")[0]||e.timestamp;return n.textContent=`${s} \xB7 ${e.context.url}`,t.appendChild(n),t}function F(e){switch(e.payload.kind){case "error":return e.payload.message;case "console":return e.payload.args.join(", ");case "network":return `${e.payload.method} ${e.payload.url} \u2192 ${e.payload.status}`}}function R(e){return g({generator:"ghostbug",version:f,exportedAt:new Date().toISOString(),reportCount:e.length,reports:e},2)}function B(e){let t=[];return t.push(`# Bug Report \u2014 ghostbug v${f}`),t.push(`**Generated:** ${new Date().toISOString()}`),t.push(`**Reports:** ${e.length}`),t.push(""),t.push("---"),t.push(""),e.forEach((o,r)=>{t.push(`## ${r+1}. ${X(o)}`),t.push(""),t.push(`- **Type:** ${o.type}`),t.push(`- **Time:** ${o.timestamp}`),t.push(`- **Occurrences:** ${o.count}`),t.push(`- **URL:** ${o.context.url}`),t.push(`- **Browser:** ${U(o.context.userAgent)}`),t.push(`- **Viewport:** ${o.context.viewport.width}x${o.context.viewport.height}`),t.push(""),t.push(...D(o.payload)),t.push(""),o.breadcrumbs.length>0&&(t.push("### Breadcrumbs"),t.push(""),t.push("| Time | Category | Event |"),t.push("|------|----------|-------|"),o.breadcrumbs.forEach(n=>{let s=n.timestamp.split("T")[1]?.split(".")[0]||n.timestamp;t.push(`| ${s} | ${n.category} | ${n.message} |`);}),t.push("")),t.push("---"),t.push("");}),t.join(`
`)}function X(e){switch(e.payload.kind){case "error":return `${e.payload.name||"Error"}: ${e.payload.message}`;case "console":return `Console ${e.payload.level}: ${e.payload.args[0]||""}`;case "network":return `${e.payload.method} ${e.payload.url} \u2192 ${e.payload.status}`}}function D(e){let t=[];switch(e.kind){case "error":e.stack&&(t.push("### Stack Trace"),t.push(""),t.push("```"),t.push(e.stack),t.push("```")),e.filename&&t.push(`**File:** ${e.filename}:${e.lineno}:${e.colno}`);break;case "console":t.push("### Console Output"),t.push(""),t.push("```"),e.args.forEach(o=>t.push(o)),t.push("```");break;case "network":t.push("### Network Details"),t.push(""),t.push(`- **Method:** ${e.method}`),t.push(`- **URL:** ${e.url}`),t.push(`- **Status:** ${e.status} ${e.statusText}`),t.push(`- **Duration:** ${e.duration}ms`);break}return t}function U(e){if(e.includes("Chrome")){let t=e.match(/Chrome\/(\d+)/);return t?`Chrome ${t[1]}`:"Chrome"}if(e.includes("Firefox")){let t=e.match(/Firefox\/(\d+)/);return t?`Firefox ${t[1]}`:"Firefox"}if(e.includes("Safari")&&!e.includes("Chrome")){let t=e.match(/Version\/(\d+)/);return t?`Safari ${t[1]}`:"Safari"}return e.slice(0,50)}var S=class{constructor(t,o,r){this.eventBus=t;this.reportManager=o;this.options=r;this.hostElement=null;this.shadowRoot=null;this.panel=null;this.badge=null;this.reportList=null;this.isExpanded=false;this.unsubscribers=[];}mount(){this.hostElement=document.createElement("div"),this.hostElement.id="ghostbug-widget";let t=this.hostElement.style;t.position="fixed",t.zIndex=String(this.options.zIndex),t.margin="0",t.padding="0",this.applyPosition(t),this.shadowRoot=this.hostElement.attachShadow({mode:"closed"});let o=document.createElement("style");o.textContent=z,this.shadowRoot.appendChild(o);let r=document.createElement("div");r.className="gb-container";let n=A();this.badge=n.querySelector(".gb-badge"),n.addEventListener("click",()=>this.toggle()),r.appendChild(n),this.panel=j(this.options.position),r.appendChild(this.panel),this.panel.querySelector(".gb-close-btn")?.addEventListener("click",()=>this.toggle()),this.panel.querySelector(".gb-copy-btn")?.addEventListener("click",()=>this.copyMarkdown()),this.panel.querySelector(".gb-download-btn")?.addEventListener("click",()=>this.downloadJSON()),this.reportList=this.panel.querySelector(".gb-report-list"),this.shadowRoot.appendChild(r),document.body.appendChild(this.hostElement),this.unsubscribers.push(this.eventBus.on("report:created",()=>this.update()),this.eventBus.on("report:deduplicated",()=>this.update())),this.options.collapsed||this.toggle();}applyPosition(t){let o=this.options.position;t.top=o.startsWith("top")?"16px":"auto",t.bottom=o.startsWith("bottom")?"16px":"auto",t.left=o.endsWith("left")?"16px":"auto",t.right=o.endsWith("right")?"16px":"auto";}toggle(){this.isExpanded=!this.isExpanded,this.isExpanded?(this.panel?.classList.add("gb-open"),this.renderReportList()):this.panel?.classList.remove("gb-open");}update(){this.updateBadge(),this.isExpanded&&this.renderReportList();}updateBadge(){if(!this.badge)return;let t=this.reportManager.reportCount;this.badge.textContent=String(t),this.badge.setAttribute("data-count",String(t));}renderReportList(){if(!this.reportList)return;this.reportList.textContent="";let t=this.reportManager.getReports();if(t.length===0){let r=document.createElement("div");r.className="gb-empty",r.textContent="No bugs captured yet.",this.reportList.appendChild(r);return}[...t].reverse().forEach(r=>{let n=I(r);this.reportList.appendChild(n);});}copyMarkdown(){let t=B(this.reportManager.getReports());navigator.clipboard.writeText(t).then(()=>this.showToast("Copied to clipboard!"),()=>this.showToast("Copy failed"));}downloadJSON(){let t=R(this.reportManager.getReports()),o=new Blob([t],{type:"application/json"}),r=URL.createObjectURL(o),n=document.createElement("a");n.href=r,n.download="ghostbug-report.json",n.click(),URL.revokeObjectURL(r);}showToast(t){if(!this.shadowRoot)return;let o=document.createElement("div");o.className="gb-toast",o.textContent=t,this.shadowRoot.appendChild(o),requestAnimationFrame(()=>{o.classList.add("gb-show");}),setTimeout(()=>{o.classList.remove("gb-show"),setTimeout(()=>o.remove(),300);},2e3);}unmount(){this.unsubscribers.forEach(t=>t()),this.unsubscribers=[],this.hostElement?.remove(),this.hostElement=null,this.shadowRoot=null,this.panel=null,this.badge=null,this.reportList=null;}};var p=null,m=null,u=[],L=null,$=new Set,O=false;function W(e,t){return t?{maxReports:t.maxReports??e.maxReports,maxBreadcrumbs:t.maxBreadcrumbs??e.maxBreadcrumbs,maxClicks:t.maxClicks??e.maxClicks,widget:t.widget??e.widget,collectors:{...e.collectors,...t.collectors},rateLimit:{...e.rateLimit,...t.rateLimit},beforeReport:t.beforeReport??e.beforeReport,debug:t.debug??e.debug}:{...e}}function G(e){if(O){e?.debug&&console.warn("[ghostbug] Already initialized. Call destroy() first.");return}let t=W(N,e);p=new b;let o=new C;if(m=new v(p,o,t),t.collectors.errors&&u.push(new w(p)),t.collectors.console&&u.push(new x(p)),t.collectors.network&&u.push(new E(p)),t.collectors.clicks&&u.push(new k(p,t.maxClicks)),u.push(o),u.forEach(r=>r.setup()),p.on("report:created",r=>{$.forEach(n=>{try{n(r);}catch{}});}),t.widget){let r=typeof t.widget=="object"?{position:t.widget.position||"bottom-right",collapsed:t.widget.collapsed??true,zIndex:t.widget.zIndex??2147483647}:{position:"bottom-right",collapsed:true,zIndex:2147483647};L=new S(p,m,r),L.mount();}O=true;}function J(){return T(),m.getReports()}function V(e="ghostbug-report.json"){T();let t=R(m.getReports()),o=new Blob([t],{type:"application/json"}),r=URL.createObjectURL(o),n=document.createElement("a");n.href=r,n.download=e,n.click(),URL.revokeObjectURL(r);}function Y(){return T(),B(m.getReports())}function K(e){return $.add(e),()=>$.delete(e)}function Q(){L?.unmount(),L=null,u.forEach(e=>e.teardown()),u=[],p?.clear(),p=null,m?.clear(),m=null,$.clear(),O=false;}function T(){if(!O)throw new Error("[ghostbug] Not initialized. Call ghostbug.init() first.")}var Xt={init:G,getReports:J,download:V,toMarkdown:Y,onBug:K,destroy:Q};export{Xt as default,Q as destroy,V as download,J as getReports,G as init,K as onBug,Y as toMarkdown};//# sourceMappingURL=index.js.map
`;var J='<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5s-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z"/></svg>';function D(){let r=document.createElement("button");r.className="gb-fab",r.setAttribute("aria-label","ghostbug - bug reports");let e=document.createElement("span");e.innerHTML=J,r.appendChild(e);let t=document.createElement("span");return t.className="gb-badge",t.setAttribute("data-count","0"),t.textContent="0",r.appendChild(t),r}function G(r){let e=document.createElement("div");e.className=`gb-panel gb-pos-${r}`;let t=document.createElement("div");t.className="gb-header";let o=document.createElement("span");o.className="gb-header-title",o.textContent="ghostbug",t.appendChild(o);let n=document.createElement("button");n.className="gb-header-btn gb-copy-btn",n.textContent="Copy MD",t.appendChild(n);let i=document.createElement("button");i.className="gb-header-btn gb-download-btn",i.textContent="Export",t.appendChild(i);let s=document.createElement("button");s.className="gb-close-btn",s.textContent="\xD7",s.setAttribute("aria-label","Close"),t.appendChild(s),e.appendChild(t);let l=document.createElement("div");l.className="gb-report-list";let a=document.createElement("div");return a.className="gb-empty",a.textContent="No bugs captured yet.",l.appendChild(a),e.appendChild(l),e}function X(r){let e=document.createElement("div");e.className="gb-report-item";let t=document.createElement("span");if(t.className=`gb-report-type gb-type-${r.payload.kind==="error"?"error":r.payload.kind}`,t.textContent=r.type,e.appendChild(t),r.count>1){let s=document.createElement("span");s.className="gb-report-count",s.textContent=`\xD7${r.count}`,e.appendChild(s);}let o=document.createElement("div");o.className="gb-report-message",o.textContent=V(r),e.appendChild(o);let n=document.createElement("div");n.className="gb-report-meta";let i=r.timestamp.split("T")[1]?.split(".")[0]||r.timestamp;return n.textContent=`${i} \xB7 ${r.context.url}`,e.appendChild(n),e}function V(r){switch(r.payload.kind){case "error":return r.payload.message;case "console":return r.payload.args.join(", ");case "network":return `${r.payload.method} ${r.payload.url} \u2192 ${r.payload.status}`;case "performance":return `${r.payload.metric}: ${r.payload.value}ms`;case "memory":return r.payload.message}}function T(r){return g({generator:"ghostbug",version:f,exportedAt:new Date().toISOString(),reportCount:r.length,reports:r},2)}function L(r){let e=[];return e.push(`# Bug Report \u2014 ghostbug v${f}`),e.push(`**Generated:** ${new Date().toISOString()}`),e.push(`**Reports:** ${r.length}`),e.push(""),e.push("---"),e.push(""),r.forEach((t,o)=>{e.push(`## ${o+1}. ${Y(t)}`),e.push(""),e.push(`- **Type:** ${t.type}`),e.push(`- **Time:** ${t.timestamp}`),e.push(`- **Occurrences:** ${t.count}`),e.push(`- **URL:** ${t.context.url}`),e.push(`- **Browser:** ${Q(t.context.userAgent)}`),e.push(`- **Viewport:** ${t.context.viewport.width}x${t.context.viewport.height}`),e.push(""),e.push(...K(t.payload)),e.push(""),t.breadcrumbs.length>0&&(e.push("### Breadcrumbs"),e.push(""),e.push("| Time | Category | Event |"),e.push("|------|----------|-------|"),t.breadcrumbs.forEach(n=>{let i=n.timestamp.split("T")[1]?.split(".")[0]||n.timestamp;e.push(`| ${i} | ${n.category} | ${n.message} |`);}),e.push("")),e.push("---"),e.push("");}),e.join(`
`)}function Y(r){switch(r.payload.kind){case "error":return `${r.payload.name||"Error"}: ${r.payload.message}`;case "console":return `Console ${r.payload.level}: ${r.payload.args[0]||""}`;case "network":return `${r.payload.method} ${r.payload.url} \u2192 ${r.payload.status}`;case "performance":return `Performance: ${r.payload.metric} ${r.payload.value}ms`;case "memory":return `Memory: ${r.payload.message}`}}function K(r){let e=[];switch(r.kind){case "error":r.stack&&(e.push("### Stack Trace"),e.push(""),e.push("```"),e.push(r.stack),e.push("```")),r.filename&&e.push(`**File:** ${r.filename}:${r.lineno}:${r.colno}`);break;case "console":e.push("### Console Output"),e.push(""),e.push("```"),r.args.forEach(t=>e.push(t)),e.push("```");break;case "network":e.push("### Network Details"),e.push(""),e.push(`- **Method:** ${r.method}`),e.push(`- **URL:** ${r.url}`),e.push(`- **Status:** ${r.status} ${r.statusText}`),e.push(`- **Duration:** ${r.duration}ms`);break;case "performance":e.push("### Performance Details"),e.push(""),e.push(`- **Metric:** ${r.metric}`),e.push(`- **Value:** ${r.value}ms`),r.entries.length>0&&e.push(`- **Start Time:** ${Math.round(r.entries[0].startTime)}ms`);break;case "memory":e.push("### Memory Details"),e.push(""),e.push(`- **Used:** ${(r.usedJSHeapSize/1048576).toFixed(1)}MB`),e.push(`- **Limit:** ${(r.jsHeapSizeLimit/1048576).toFixed(1)}MB`),e.push(`- **Usage:** ${(r.heapUsagePercent*100).toFixed(1)}%`),e.push(`- **Growth since init:** ${(r.heapGrowthPercent*100).toFixed(1)}%`);break}return e}function Q(r){if(r.includes("Chrome")){let e=r.match(/Chrome\/(\d+)/);return e?`Chrome ${e[1]}`:"Chrome"}if(r.includes("Firefox")){let e=r.match(/Firefox\/(\d+)/);return e?`Firefox ${e[1]}`:"Firefox"}if(r.includes("Safari")&&!r.includes("Chrome")){let e=r.match(/Version\/(\d+)/);return e?`Safari ${e[1]}`:"Safari"}return r.slice(0,50)}var P=class{constructor(e,t,o){this.eventBus=e;this.reportManager=t;this.options=o;this.hostElement=null;this.shadowRoot=null;this.panel=null;this.badge=null;this.reportList=null;this.isExpanded=false;this.unsubscribers=[];}mount(){this.hostElement=document.createElement("div"),this.hostElement.id="ghostbug-widget";let e=this.hostElement.style;e.position="fixed",e.zIndex=String(this.options.zIndex),e.margin="0",e.padding="0",this.applyPosition(e),this.shadowRoot=this.hostElement.attachShadow({mode:"closed"});let t=document.createElement("style");t.textContent=U,this.shadowRoot.appendChild(t);let o=document.createElement("div");o.className="gb-container";let n=D();this.badge=n.querySelector(".gb-badge"),n.addEventListener("click",()=>this.toggle()),o.appendChild(n),this.panel=G(this.options.position),o.appendChild(this.panel),this.panel.querySelector(".gb-close-btn")?.addEventListener("click",()=>this.toggle()),this.panel.querySelector(".gb-copy-btn")?.addEventListener("click",()=>this.copyMarkdown()),this.panel.querySelector(".gb-download-btn")?.addEventListener("click",()=>this.downloadJSON()),this.reportList=this.panel.querySelector(".gb-report-list"),this.shadowRoot.appendChild(o),document.body.appendChild(this.hostElement),this.unsubscribers.push(this.eventBus.on("report:created",()=>this.update()),this.eventBus.on("report:deduplicated",()=>this.update())),this.options.collapsed||this.toggle();}applyPosition(e){let t=this.options.position;e.top=t.startsWith("top")?"16px":"auto",e.bottom=t.startsWith("bottom")?"16px":"auto",e.left=t.endsWith("left")?"16px":"auto",e.right=t.endsWith("right")?"16px":"auto";}toggle(){this.isExpanded=!this.isExpanded,this.isExpanded?(this.panel?.classList.add("gb-open"),this.renderReportList()):this.panel?.classList.remove("gb-open");}update(){this.updateBadge(),this.isExpanded&&this.renderReportList();}updateBadge(){if(!this.badge)return;let e=this.reportManager.reportCount;this.badge.textContent=String(e),this.badge.setAttribute("data-count",String(e));}renderReportList(){if(!this.reportList)return;this.reportList.textContent="";let e=this.reportManager.getReports();if(e.length===0){let o=document.createElement("div");o.className="gb-empty",o.textContent="No bugs captured yet.",this.reportList.appendChild(o);return}[...e].reverse().forEach(o=>{let n=X(o);this.reportList.appendChild(n);});}copyMarkdown(){let e=L(this.reportManager.getReports());navigator.clipboard.writeText(e).then(()=>this.showToast("Copied to clipboard!"),()=>this.showToast("Copy failed"));}downloadJSON(){let e=T(this.reportManager.getReports()),t=new Blob([e],{type:"application/json"}),o=URL.createObjectURL(t),n=document.createElement("a");n.href=o,n.download="ghostbug-report.json",n.click(),URL.revokeObjectURL(o);}showToast(e){if(!this.shadowRoot)return;let t=document.createElement("div");t.className="gb-toast",t.textContent=e,this.shadowRoot.appendChild(t),requestAnimationFrame(()=>{t.classList.add("gb-show");}),setTimeout(()=>{t.classList.remove("gb-show"),setTimeout(()=>t.remove(),300);},2e3);}unmount(){this.unsubscribers.forEach(e=>e()),this.unsubscribers=[],this.hostElement?.remove(),this.hostElement=null,this.shadowRoot=null,this.panel=null,this.badge=null,this.reportList=null;}};var c=null,h=null,d=[],H=null,$=new Set,M=false,z,O;function Z(r,e){return e?{maxReports:e.maxReports??r.maxReports,maxBreadcrumbs:e.maxBreadcrumbs??r.maxBreadcrumbs,maxClicks:e.maxClicks??r.maxClicks,widget:e.widget??r.widget,collectors:{...r.collectors,...e.collectors},rateLimit:{...r.rateLimit,...e.rateLimit},beforeReport:e.beforeReport??r.beforeReport,debug:e.debug??r.debug,screenshotFn:e.screenshotFn}:{...r}}function ee(r){if(M){r?.debug&&console.warn("[ghostbug] Already initialized. Call destroy() first.");return}let e=Z(_,r);c=new b;let t=new C(()=>({user:z,tags:O}));if(h=new y(c,t,e),e.collectors.errors&&d.push(new w(c)),e.collectors.console&&d.push(new x(c)),e.collectors.network&&d.push(new E(c)),e.collectors.clicks&&d.push(new k(c,e.maxClicks)),e.collectors.interactions&&d.push(new S(c)),e.collectors.performance&&d.push(new B(c)),e.collectors.memory&&d.push(new R(c)),d.push(t),d.forEach(o=>o.setup()),c.on("report:created",o=>{$.forEach(n=>{try{n(o);}catch{}});}),e.widget){let o=typeof e.widget=="object"?{position:e.widget.position||"bottom-right",collapsed:e.widget.collapsed??true,zIndex:e.widget.zIndex??2147483647}:{position:"bottom-right",collapsed:true,zIndex:2147483647};H=new P(c,h,o),H.mount();}M=true;}function te(){return N(),h.getReports()}function re(r="ghostbug-report.json"){N();let e=T(h.getReports()),t=new Blob([e],{type:"application/json"}),o=URL.createObjectURL(t),n=document.createElement("a");n.href=o,n.download=r,n.click(),URL.revokeObjectURL(o);}function oe(){return N(),L(h.getReports())}function ne(r){return $.add(r),()=>$.delete(r)}function ie(r){z=r;}function se(r){O={...O,...r};}function ae(){H?.unmount(),H=null,d.forEach(r=>r.teardown()),d=[],c?.clear(),c=null,h?.clear(),h=null,$.clear(),z=void 0,O=void 0,M=false;}function N(){if(!M)throw new Error("[ghostbug] Not initialized. Call ghostbug.init() first.")}var nt={init:ee,getReports:te,download:re,toMarkdown:oe,onBug:ne,setUser:ie,setTags:se,destroy:ae};export{nt as default,ae as destroy,re as download,te as getReports,ee as init,ne as onBug,se as setTags,ie as setUser,oe as toMarkdown};//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map
{
"name": "ghostbug",
"version": "0.1.0",
"version": "0.2.0-beta.0",
"description": "Zero-config automatic bug context collector SDK for the browser",

@@ -59,11 +59,8 @@ "author": "Sounak Das",

"typecheck": "tsc --noEmit",
"size": "size-limit",
"prepublishOnly": "npm run lint && npm run test && npm run build && npm run size"
"prepublishOnly": "npm run lint && npm run test && npm run build"
},
"devDependencies": {
"@size-limit/preset-small-lib": "^11.0.0",
"eslint": "^9.0.0",
"jsdom": "^28.1.0",
"prettier": "^3.0.0",
"size-limit": "^11.0.0",
"tsup": "^8.0.0",

@@ -73,10 +70,3 @@ "typescript": "^5.5.0",

"vitest": "^2.0.0"
},
"size-limit": [
{
"path": "dist/index.js",
"limit": "8 KB",
"gzip": true
}
]
}
}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display