@sphoro/bugcatch-web-sdk 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/bugcatch.es.js +1849 -1640
- package/dist/bugcatch.es.js.map +1 -1
- package/dist/bugcatch.umd.js +140 -117
- package/dist/bugcatch.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/index.js +83 -8
- package/src/references.js +155 -3
- package/src/updates.js +36 -6
- package/src/widget.js +207 -48
package/dist/bugcatch.umd.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
(function(Y,se){typeof exports=="object"&&typeof module<"u"?module.exports=se():typeof define=="function"&&define.amd?define(se):(Y=typeof globalThis<"u"?globalThis:Y||self,Y.BugCatch=se())})(this,function(){"use strict";var oo=Y=>{throw TypeError(Y)};var hr=(Y,se,Ee)=>se.has(Y)||oo("Cannot "+Ee);var ao=(Y,se,Ee)=>se.has(Y)?oo("Cannot add the same private member more than once"):se instanceof WeakSet?se.add(Y):se.set(Y,Ee);var H=(Y,se,Ee)=>(hr(Y,se,"access private method"),Ee);var E,vt,Te,ro,Yt,xt,kt,io,so,co,St,lo;const Y="[REDACTED]",se=new Set(["auth","bearer","session","sid","phpsessid","otp","pass","passwd","pwd","sig","codeverifier"]),Ee=["token","secret","password","passwd","apikey","signature","credential","sessionid","privatekey","accesskey","authorization"],uo=new Set(["key","code","state","nonce","salt","hash"]),Xt=[/eyJ[\w-]{8,}\.[\w-]{8,}\.[\w-]+/g,/(?:AKIA|ASIA|AROA|AIDA|AGPA|ANPA|ANVA|APKA)[0-9A-Z]{16}/g,/AIza[\w-]{35}/g,/gh[pousr]_[A-Za-z0-9]{36,}/g,/github_pat_\w{22,}/g,/[sprk]k_(?:live|test)_[0-9A-Za-z]{10,}/g,/xox[abposr]-[A-Za-z0-9-]{10,}/g,/sk-ant-[\w-]{20,}/g,/sk-[\w-]{20,}/g,/glpat-[\w-]{20,}/g,/shp(?:at|ss|ca|pa)_[A-Za-z0-9]{32}/g],po=/\bBearer\s+[\w.~+/=-]{8,}/gi,ho=/^([A-Za-z][A-Za-z0-9+.-]*:\/\/)([^/?#@]+)@/;function Jt(t){try{return decodeURIComponent(t.replace(/\+/g," "))}catch{return t}}function fo(t){return Jt(t).toLowerCase().replace(/[^a-z0-9]/g,"")}function go(t){return t.length>=20?!0:Xt.some(e=>(e.lastIndex=0,e.test(t)))}function bo(t,e){const n=fo(t);if(!n)return!1;if(se.has(n))return!0;for(const o of Ee)if(n.includes(o))return!0;return uo.has(n)?go(Jt(e)):!1}function $t(t){return t.split("&").map(e=>{const n=e.indexOf("=");if(n===-1)return e;const o=e.slice(0,n),i=e.slice(n+1);return i&&bo(o,i)?`${o}=${Y}`:e}).join("&")}function Zt(t){let e=t;for(const n of Xt)n.lastIndex=0,e=e.replace(n,Y);return e}function Gt(t){if(t==null)return t;let e=String(t);if(!e)return e;e=e.replace(ho,`$1${Y}@`);const n=e.indexOf("#");let o=n===-1?e:e.slice(0,n),i=n===-1?"":e.slice(n);const a=o.indexOf("?");if(a!==-1&&(o=o.slice(0,a+1)+$t(o.slice(a+1))),i.length>1){const s=i.slice(1),l=s.indexOf("?");l!==-1?i=`#${s.slice(0,l+1)}${$t(s.slice(l+1))}`:s.includes("=")&&(i=`#${$t(s)}`)}return Zt(o+i)}function mo(t){if(t==null)return t;let e=String(t);return e&&(e=e.replace(/[A-Za-z][A-Za-z0-9+.-]{0,30}:\/\/[^\s"'<>)\]]+/g,n=>Gt(n)),e=e.replace(po,`Bearer ${Y}`),Zt(e))}function et(t){const e=[];return{push(n){e.push(n),e.length>t&&e.splice(0,e.length-t)},all:()=>e.slice(),clear:()=>{e.length=0},get size(){return e.length}}}const en=["log","info","warn","error","debug"];function yo(t,{levels:e=["warn","error","log","info"]}={}){const n={};for(const o of en)n[o]=console[o],e.includes(o)&&(console[o]=(...i)=>{try{t.push({level:o,text:i.map(on).join(" ").slice(0,2e3),at:new Date().toISOString()})}catch{}n[o].apply(console,i)});return()=>{for(const o of en)console[o]=n[o]}}function wo(t,{slowMs:e=2e3}={}){const n=window.fetch,o=XMLHttpRequest.prototype.open,i=XMLHttpRequest.prototype.send;return n&&(window.fetch=async function(...s){var b,f,m;const l=performance.now(),p=typeof s[0]=="string"?s[0]:(b=s[0])==null?void 0:b.url,h=((f=s[1])==null?void 0:f.method)||(typeof s[0]=="object"?(m=s[0])==null?void 0:m.method:"GET")||"GET";try{const g=await n.apply(this,s);return Ct(t,{url:p,method:h,status:g.status,ms:Math.round(performance.now()-l),slowMs:e}),g}catch(g){throw Ct(t,{url:p,method:h,status:0,error:String((g==null?void 0:g.message)||g),ms:Math.round(performance.now()-l),slowMs:e}),g}}),XMLHttpRequest.prototype.open=function(s,l,...p){return this.__bc={method:s,url:l,started:0},o.call(this,s,l,...p)},XMLHttpRequest.prototype.send=function(...s){return this.__bc&&(this.__bc.started=performance.now(),this.addEventListener("loadend",()=>{Ct(t,{url:this.__bc.url,method:this.__bc.method,status:this.status,ms:Math.round(performance.now()-this.__bc.started),slowMs:e})})),i.apply(this,s)},()=>{n&&(window.fetch=n),XMLHttpRequest.prototype.open=o,XMLHttpRequest.prototype.send=i}}function Ct(t,{url:e,method:n,status:o,ms:i,error:a,slowMs:s}){try{t.push({url:Gt(String(e)).slice(0,500),method:n,status:o,ms:i,error:a===void 0?void 0:mo(a),failed:o===0||o>=400,slow:i>=s,at:new Date().toISOString()})}catch{}}function vo(t){const e=o=>{const i=String(o.message||"Error"),a=o.filename?` (${o.filename}:${o.lineno}:${o.colno})`:"";t.push({level:"error",text:(/^uncaught/i.test(i)?i:`Uncaught ${i}`)+a,at:new Date().toISOString()})},n=o=>{t.push({level:"error",text:`Unhandled rejection: ${on(o.reason)}`,at:new Date().toISOString()})};return window.addEventListener("error",e),window.addEventListener("unhandledrejection",n),()=>{window.removeEventListener("error",e),window.removeEventListener("unhandledrejection",n)}}async function tn(){const t=nn();try{if(navigator.getBattery){const e=await navigator.getBattery();t.battery=Math.round(e.level*100),t.charging=e.charging}}catch{}return t}function nn(){var e,n,o,i,a,s,l,p,h;const t=window.navigator||{};return{userAgent:t.userAgent,platform:t.platform,language:t.language,languages:t.languages?[...t.languages]:null,online:t.onLine,cookieEnabled:t.cookieEnabled,maxTouchPoints:t.maxTouchPoints??null,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:(e=window.screen)==null?void 0:e.width,height:(n=window.screen)==null?void 0:n.height,availWidth:(o=window.screen)==null?void 0:o.availWidth,availHeight:(i=window.screen)==null?void 0:i.availHeight,colorDepth:(a=window.screen)==null?void 0:a.colorDepth,orientation:((l=(s=window.screen)==null?void 0:s.orientation)==null?void 0:l.type)||null},devicePixelRatio:window.devicePixelRatio,referrer:document.referrer||null,title:document.title,capturedAt:new Date().toISOString(),timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,timezoneOffsetMinutes:new Date().getTimezoneOffset(),browserMode:t.webdriver?"Automated":"Normal",doNotTrack:t.doNotTrack||null,hardwareConcurrency:t.hardwareConcurrency??null,deviceMemory:t.deviceMemory??null,connection:t.connection?{effectiveType:t.connection.effectiveType,downlink:t.connection.downlink,rtt:t.connection.rtt,saveData:t.connection.saveData}:null,prefersColorScheme:(p=window.matchMedia)!=null&&p.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light",prefersReducedMotion:((h=window.matchMedia)==null?void 0:h.call(window,"(prefers-reduced-motion: reduce)").matches)||!1}}function on(t){if(typeof t=="string")return t;if(t instanceof Error)return`${t.name}: ${t.message}`;try{return JSON.stringify(t)}catch{return String(t)}}const xo=typeof window<"u"&&window.fetch?window.fetch.bind(window):null,ko=typeof XMLHttpRequest<"u"?XMLHttpRequest.prototype.open:null,So=typeof XMLHttpRequest<"u"?XMLHttpRequest.prototype.send:null,an=["image/png","image/jpeg","image/webp","image/gif","video/webm","video/mp4","audio/webm","audio/ogg","audio/mpeg","audio/mp4","audio/wav","application/pdf","text/plain","text/csv","application/json","application/zip","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"],tt=["image/png","image/jpeg","image/webp","video/webm","video/mp4"],$o=()=>{var t;return!!((t=navigator==null?void 0:navigator.mediaDevices)!=null&&t.getUserMedia&&typeof MediaRecorder<"u")},Co=()=>{var t;return!!((t=navigator==null?void 0:navigator.mediaDevices)!=null&&t.getDisplayMedia&&typeof MediaRecorder<"u")},To=()=>{var t;return!!((t=navigator==null?void 0:navigator.mediaDevices)!=null&&t.getDisplayMedia)};function nt(t,e=an){const n=String(t||"").split(";")[0].trim().toLowerCase();return e.includes(n)?n:null}async function Eo(){const t=await navigator.mediaDevices.getDisplayMedia({video:{frameRate:1},audio:!1});try{const e=t.getVideoTracks()[0],n=document.createElement("video");n.srcObject=t,n.muted=!0,n.playsInline=!0,await n.play(),await new Promise(l=>requestAnimationFrame(()=>requestAnimationFrame(l)));const{width:o,height:i}=e.getSettings(),a=document.createElement("canvas");a.width=o||n.videoWidth,a.height=i||n.videoHeight,a.getContext("2d").drawImage(n,0,0,a.width,a.height);const s=await new Promise(l=>a.toBlob(l,"image/png"));if(!s)throw new Error("The browser returned an empty screenshot.");return{blob:s,mime:"image/png",kind:"SCREENSHOT"}}finally{t.getTracks().forEach(e=>e.stop())}}async function Io({maxMs:t=12e4,onTick:e,onAutoStop:n}={}){const o=await navigator.mediaDevices.getDisplayMedia({video:{frameRate:15},audio:!1}),i=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm"].find(g=>MediaRecorder.isTypeSupported(g))||"video/webm",a=new MediaRecorder(o,{mimeType:i,videoBitsPerSecond:25e5}),s=[];a.ondataavailable=g=>{g.data.size&&s.push(g.data)},a.start(1e3);const l=Date.now(),p=setInterval(()=>e==null?void 0:e(Math.floor((Date.now()-l)/1e3)),500),h=()=>{clearInterval(p),clearTimeout(m),o.getTracks().forEach(g=>g.stop())},b=new Promise(g=>{a.onstop=()=>{h(),g(new Blob(s,{type:i}))}}),f=()=>{a.state!=="inactive"&&a.stop(),n==null||n()};o.getVideoTracks()[0].addEventListener("ended",f);const m=setTimeout(f,t);return{mime:i,maxMs:t,async stop(){return clearTimeout(m),a.state!=="inactive"&&a.stop(),{blob:await b,mime:i,kind:"VIDEO"}},cancel(){h(),a.state!=="inactive"&&a.stop()}}}async function Mo({maxMs:t=12e4,onTick:e,onAutoStop:n}={}){const o=await navigator.mediaDevices.getUserMedia({audio:!0}),i=["audio/webm;codecs=opus","audio/webm","audio/mp4","audio/ogg"].find(g=>MediaRecorder.isTypeSupported(g))||"",a=new MediaRecorder(o,i?{mimeType:i}:void 0),s=[];a.ondataavailable=g=>{g.data.size&&s.push(g.data)},a.start(1e3);const l=Date.now(),p=setInterval(()=>e==null?void 0:e(Math.floor((Date.now()-l)/1e3)),500),h=()=>{clearInterval(p),clearTimeout(m),o.getTracks().forEach(g=>g.stop())},b=new Promise(g=>{a.onstop=()=>{h(),g(new Blob(s,{type:a.mimeType||i}))}}),m=setTimeout(()=>{a.state!=="inactive"&&a.stop(),n==null||n()},t);return{mime:a.mimeType||i,maxMs:t,async stop(){clearTimeout(m),a.state!=="inactive"&&a.stop();const g=await b;return{blob:g,mime:g.type||a.mimeType||i,kind:"AUDIO"}},cancel(){h(),a.state!=="inactive"&&a.stop()}}}async function Ao({apiBase:t,apiKey:e,blob:n,mime:o,onProgress:i}){const a=nt(o||n.type);if(!a)throw new Error(`[BugCatch] ${o||n.type||"that file"} can't be attached.`);const s=await xo(`${t}/ingest/presign`,{method:"POST",headers:{"Content-Type":"application/json","X-BugCatch-Key":e},body:JSON.stringify({mime:a})});if(!s.ok)throw new Error(`[BugCatch] could not start the upload (HTTP ${s.status}).`);const{key:l,uploadUrl:p}=await s.json();return await Lo(p,n,a,i),{storageKey:l,mime:a}}function Lo(t,e,n,o){return new Promise((i,a)=>{const s=new XMLHttpRequest;ko.call(s,"PUT",t,!0),s.setRequestHeader("Content-Type",n),s.upload.onprogress=l=>{l.lengthComputable&&(o==null||o(l.loaded/l.total))},s.onload=()=>{s.status>=200&&s.status<300?i():a(new Error(`[BugCatch] upload failed (HTTP ${s.status}).`))},s.onerror=()=>a(new Error("[BugCatch] the browser blocked the upload to storage. If this is a new environment, the media bucket is probably missing its CORS policy.")),s.onabort=()=>a(new Error("[BugCatch] upload cancelled.")),So.call(s,e)})}function Be(t){return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(0)} KB`:`${(t/1024/1024).toFixed(1)} MB`}function ot(t){const e=Math.floor(t/60),n=t%60;return`${e}:${String(n).padStart(2,"0")}`}const Bo=7*24*60*60*1e3;let at;function Ro(){return at||(at=new Promise((t,e)=>{const n=indexedDB.open("bugcatch-drafts",1);n.onupgradeneeded=()=>n.result.createObjectStore("drafts"),n.onsuccess=()=>t(n.result),n.onerror=()=>e(n.error),n.onblocked=()=>e(new Error("Draft storage is blocked."))}).catch(t=>{throw at=null,t})),at}function jo(t,e){var n,o;return JSON.stringify([t.apiBase,t.projectId,e||((n=t.user)==null?void 0:n.email)||((o=t.user)==null?void 0:o.id)||"anonymous"])}async function rt(t,e){const n=await Ro();return new Promise((o,i)=>{const a=n.transaction("drafts",e===void 0?"readonly":"readwrite"),s=a.objectStore("drafts"),l=e===void 0?s.get(t):e===null?s.delete(t):s.put({...e,savedAt:Date.now()},t);a.oncomplete=()=>o(l.result),a.onerror=()=>i(a.error),a.onabort=()=>i(a.error||new Error("Draft was not saved."))})}async function zo(t){const e=await rt(t);return e&&Date.now()-e.savedAt>Bo?(await rt(t,null),null):e||null}const Qo="bugcatch.session.",Tt=t=>`${Qo}${t}`,Et=new Map;function ke(t){var e;if(!t)return null;try{const n=(e=window.localStorage)==null?void 0:e.getItem(Tt(t));if(n){const o=JSON.parse(n);if(o!=null&&o.token)return o}}catch{}return Et.get(t)||null}function Oo(t,e){var o;if(!t||!(e!=null&&e.token))return;const n={token:e.token,email:e.email||null,name:e.name||null};Et.set(t,n);try{(o=window.localStorage)==null||o.setItem(Tt(t),JSON.stringify(n))}catch{}}function It(t){var e;if(t){Et.delete(t);try{(e=window.localStorage)==null||e.removeItem(Tt(t))}catch{}}}function it({apiKey:t,token:e}){return{"Content-Type":"application/json","X-BugCatch-Key":t,...e?{"X-BugCatch-Session":e}:{}}}async function rn(t){try{const e=await t.json(),n=Array.isArray(e.message)?e.message.join(", "):e.message;if(n)return n}catch{}return`Request failed (HTTP ${t.status})`}async function Ho({apiBase:t,apiKey:e,projectId:n,token:o}){const i={mode:"off",signedIn:null,signedOutReason:null};try{const a=await fetch(`${t}/ingest/login?projectId=${encodeURIComponent(n)}`,{headers:it({apiKey:e,token:o})});if(!a.ok)return i;const s=await a.json();return{mode:s.mode==="optional"||s.mode==="required"?s.mode:"off",signedIn:s.signedIn||null,signedOutReason:s.signedOutReason||null}}catch{return i}}async function qo({apiBase:t,apiKey:e,projectId:n,email:o,name:i}){const a=await fetch(`${t}/ingest/login/start`,{method:"POST",headers:it({apiKey:e}),body:JSON.stringify({projectId:n,email:o,...i?{name:i}:{}})});if(!a.ok)throw new Error(await rn(a));return a.json()}async function Do({apiBase:t,apiKey:e,projectId:n,email:o,code:i}){const a=await fetch(`${t}/ingest/login`,{method:"POST",headers:it({apiKey:e}),body:JSON.stringify({projectId:n,email:o,code:i})});if(!a.ok)throw new Error(await rn(a));const s=await a.json(),l={token:s.sessionToken,email:s.email,name:s.name};return Oo(n,l),l}async function No({apiBase:t,apiKey:e,projectId:n,token:o}){if(It(n),!o)return{signedOut:!0};try{await fetch(`${t}/ingest/logout`,{method:"POST",headers:it({apiKey:e,token:o}),body:JSON.stringify({projectId:n})})}catch{}return{signedOut:!0}}const Mt="bugcatch.watch",sn=[2e3,5e3,15e3,3e4,6e4],Uo=5e3;function ce(){var t;try{return((t=window.localStorage)==null?void 0:t.getItem(Mt))||null}catch{return null}}function At(t){var e;if(t)try{(e=window.localStorage)==null||e.setItem(Mt,t)}catch{}}function Ie(){var t;try{(t=window.localStorage)==null||t.removeItem(Mt)}catch{}cn()}const st="bugcatch.unread";function Ko(t){return[(t==null?void 0:t.bugId)||"report",(t==null?void 0:t.kind)||"status",(t==null?void 0:t.at)||""].join("|")}function qe(){var t;try{const e=(t=window.localStorage)==null?void 0:t.getItem(st),n=e?JSON.parse(e):[];return Array.isArray(n)?n.filter(o=>o&&typeof o.id=="string"):[]}catch{return[]}}function ct(t){var e,n;try{t.length?(e=window.localStorage)==null||e.setItem(st,JSON.stringify(t)):(n=window.localStorage)==null||n.removeItem(st)}catch{}}function Po(t){const e={...t,id:Ko(t)},n=qe().filter(o=>o.id!==e.id);return n.push(e),ct(n.slice(-20)),e}function _o(t){const e=qe().filter(n=>n.id!==t);return ct(e),e}function Vo(t){const e=qe().filter(n=>n.bugId!==t);return ct(e),e}function cn(){return ct([]),[]}function Fo(t,e){let n=t,o=n.indexOf(`
|
|
1
|
+
(function(Z,pe){typeof exports=="object"&&typeof module<"u"?module.exports=pe():typeof define=="function"&&define.amd?define(pe):(Z=typeof globalThis<"u"?globalThis:Z||self,Z.BugCatch=pe())})(this,function(){"use strict";var $o=Z=>{throw TypeError(Z)};var Or=(Z,pe,Le)=>pe.has(Z)||$o("Cannot "+Le);var Co=(Z,pe,Le)=>pe.has(Z)?$o("Cannot add the same private member more than once"):pe instanceof WeakSet?pe.add(Z):pe.set(Z,Le);var N=(Z,pe,Le)=>(Or(Z,pe,"access private method"),Le);var L,Ct,To,Me,Eo,rn,Tt,Et,sn,Io,Mo,Lo,It,Ao;const Z="[REDACTED]",pe=new Set(["auth","bearer","session","sid","phpsessid","otp","pass","passwd","pwd","sig","codeverifier"]),Le=["token","secret","password","passwd","apikey","signature","credential","sessionid","privatekey","accesskey","authorization"],Bo=new Set(["key","code","state","nonce","salt","hash"]),cn=[/eyJ[\w-]{8,}\.[\w-]{8,}\.[\w-]+/g,/(?:AKIA|ASIA|AROA|AIDA|AGPA|ANPA|ANVA|APKA)[0-9A-Z]{16}/g,/AIza[\w-]{35}/g,/gh[pousr]_[A-Za-z0-9]{36,}/g,/github_pat_\w{22,}/g,/[sprk]k_(?:live|test)_[0-9A-Za-z]{10,}/g,/xox[abposr]-[A-Za-z0-9-]{10,}/g,/sk-ant-[\w-]{20,}/g,/sk-[\w-]{20,}/g,/glpat-[\w-]{20,}/g,/shp(?:at|ss|ca|pa)_[A-Za-z0-9]{32}/g],jo=/\bBearer\s+[\w.~+/=-]{8,}/gi,Ro=/^([A-Za-z][A-Za-z0-9+.-]*:\/\/)([^/?#@]+)@/;function ln(t){try{return decodeURIComponent(t.replace(/\+/g," "))}catch{return t}}function zo(t){return ln(t).toLowerCase().replace(/[^a-z0-9]/g,"")}function Oo(t){return t.length>=20?!0:cn.some(e=>(e.lastIndex=0,e.test(t)))}function Qo(t,e){const n=zo(t);if(!n)return!1;if(pe.has(n))return!0;for(const o of Le)if(n.includes(o))return!0;return Bo.has(n)?Oo(ln(e)):!1}function Mt(t){return t.split("&").map(e=>{const n=e.indexOf("=");if(n===-1)return e;const o=e.slice(0,n),i=e.slice(n+1);return i&&Qo(o,i)?`${o}=${Z}`:e}).join("&")}function dn(t){let e=t;for(const n of cn)n.lastIndex=0,e=e.replace(n,Z);return e}function un(t){if(t==null)return t;let e=String(t);if(!e)return e;e=e.replace(Ro,`$1${Z}@`);const n=e.indexOf("#");let o=n===-1?e:e.slice(0,n),i=n===-1?"":e.slice(n);const r=o.indexOf("?");if(r!==-1&&(o=o.slice(0,r+1)+Mt(o.slice(r+1))),i.length>1){const s=i.slice(1),l=s.indexOf("?");l!==-1?i=`#${s.slice(0,l+1)}${Mt(s.slice(l+1))}`:s.includes("=")&&(i=`#${Mt(s)}`)}return dn(o+i)}function Ho(t){if(t==null)return t;let e=String(t);return e&&(e=e.replace(/[A-Za-z][A-Za-z0-9+.-]{0,30}:\/\/[^\s"'<>)\]]+/g,n=>un(n)),e=e.replace(jo,`Bearer ${Z}`),dn(e))}function st(t){const e=[];return{push(n){e.push(n),e.length>t&&e.splice(0,e.length-t)},all:()=>e.slice(),clear:()=>{e.length=0},get size(){return e.length}}}const pn=["log","info","warn","error","debug"];function qo(t,{levels:e=["warn","error","log","info"]}={}){const n={};for(const o of pn)n[o]=console[o],e.includes(o)&&(console[o]=(...i)=>{try{t.push({level:o,text:i.map(gn).join(" ").slice(0,2e3),at:new Date().toISOString()})}catch{}n[o].apply(console,i)});return()=>{for(const o of pn)console[o]=n[o]}}function Do(t,{slowMs:e=2e3}={}){const n=window.fetch,o=XMLHttpRequest.prototype.open,i=XMLHttpRequest.prototype.send;return n&&(window.fetch=async function(...s){var m,b,h;const l=performance.now(),g=typeof s[0]=="string"?s[0]:(m=s[0])==null?void 0:m.url,f=((b=s[1])==null?void 0:b.method)||(typeof s[0]=="object"?(h=s[0])==null?void 0:h.method:"GET")||"GET";try{const u=await n.apply(this,s);return Lt(t,{url:g,method:f,status:u.status,ms:Math.round(performance.now()-l),slowMs:e}),u}catch(u){throw Lt(t,{url:g,method:f,status:0,error:String((u==null?void 0:u.message)||u),ms:Math.round(performance.now()-l),slowMs:e}),u}}),XMLHttpRequest.prototype.open=function(s,l,...g){return this.__bc={method:s,url:l,started:0},o.call(this,s,l,...g)},XMLHttpRequest.prototype.send=function(...s){return this.__bc&&(this.__bc.started=performance.now(),this.addEventListener("loadend",()=>{Lt(t,{url:this.__bc.url,method:this.__bc.method,status:this.status,ms:Math.round(performance.now()-this.__bc.started),slowMs:e})})),i.apply(this,s)},()=>{n&&(window.fetch=n),XMLHttpRequest.prototype.open=o,XMLHttpRequest.prototype.send=i}}function Lt(t,{url:e,method:n,status:o,ms:i,error:r,slowMs:s}){try{t.push({url:un(String(e)).slice(0,500),method:n,status:o,ms:i,error:r===void 0?void 0:Ho(r),failed:o===0||o>=400,slow:i>=s,at:new Date().toISOString()})}catch{}}function No(t){const e=o=>{const i=String(o.message||"Error"),r=o.filename?` (${o.filename}:${o.lineno}:${o.colno})`:"";t.push({level:"error",text:(/^uncaught/i.test(i)?i:`Uncaught ${i}`)+r,at:new Date().toISOString()})},n=o=>{t.push({level:"error",text:`Unhandled rejection: ${gn(o.reason)}`,at:new Date().toISOString()})};return window.addEventListener("error",e),window.addEventListener("unhandledrejection",n),()=>{window.removeEventListener("error",e),window.removeEventListener("unhandledrejection",n)}}async function hn(){const t=fn();try{if(navigator.getBattery){const e=await navigator.getBattery();t.battery=Math.round(e.level*100),t.charging=e.charging}}catch{}return t}function fn(){var e,n,o,i,r,s,l,g,f;const t=window.navigator||{};return{userAgent:t.userAgent,platform:t.platform,language:t.language,languages:t.languages?[...t.languages]:null,online:t.onLine,cookieEnabled:t.cookieEnabled,maxTouchPoints:t.maxTouchPoints??null,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:(e=window.screen)==null?void 0:e.width,height:(n=window.screen)==null?void 0:n.height,availWidth:(o=window.screen)==null?void 0:o.availWidth,availHeight:(i=window.screen)==null?void 0:i.availHeight,colorDepth:(r=window.screen)==null?void 0:r.colorDepth,orientation:((l=(s=window.screen)==null?void 0:s.orientation)==null?void 0:l.type)||null},devicePixelRatio:window.devicePixelRatio,referrer:document.referrer||null,title:document.title,capturedAt:new Date().toISOString(),timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,timezoneOffsetMinutes:new Date().getTimezoneOffset(),browserMode:t.webdriver?"Automated":"Normal",doNotTrack:t.doNotTrack||null,hardwareConcurrency:t.hardwareConcurrency??null,deviceMemory:t.deviceMemory??null,connection:t.connection?{effectiveType:t.connection.effectiveType,downlink:t.connection.downlink,rtt:t.connection.rtt,saveData:t.connection.saveData}:null,prefersColorScheme:(g=window.matchMedia)!=null&&g.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light",prefersReducedMotion:((f=window.matchMedia)==null?void 0:f.call(window,"(prefers-reduced-motion: reduce)").matches)||!1}}function gn(t){if(typeof t=="string")return t;if(t instanceof Error)return`${t.name}: ${t.message}`;try{return JSON.stringify(t)}catch{return String(t)}}const Uo=typeof window<"u"&&window.fetch?window.fetch.bind(window):null,Ko=typeof XMLHttpRequest<"u"?XMLHttpRequest.prototype.open:null,Po=typeof XMLHttpRequest<"u"?XMLHttpRequest.prototype.send:null,bn=["image/png","image/jpeg","image/webp","image/gif","video/webm","video/mp4","audio/webm","audio/ogg","audio/mpeg","audio/mp4","audio/wav","application/pdf","text/plain","text/csv","application/json","application/zip","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"],ct=["image/png","image/jpeg","image/webp","video/webm","video/mp4"],_o=()=>{var t;return!!((t=navigator==null?void 0:navigator.mediaDevices)!=null&&t.getUserMedia&&typeof MediaRecorder<"u")},Vo=()=>{var t;return!!((t=navigator==null?void 0:navigator.mediaDevices)!=null&&t.getDisplayMedia&&typeof MediaRecorder<"u")},Wo=()=>{var t;return!!((t=navigator==null?void 0:navigator.mediaDevices)!=null&&t.getDisplayMedia)};function lt(t,e=bn){const n=String(t||"").split(";")[0].trim().toLowerCase();return e.includes(n)?n:null}async function Fo(){const t=await navigator.mediaDevices.getDisplayMedia({video:{frameRate:1},audio:!1});try{const e=t.getVideoTracks()[0],n=document.createElement("video");n.srcObject=t,n.muted=!0,n.playsInline=!0,await n.play(),await new Promise(l=>requestAnimationFrame(()=>requestAnimationFrame(l)));const{width:o,height:i}=e.getSettings(),r=document.createElement("canvas");r.width=o||n.videoWidth,r.height=i||n.videoHeight,r.getContext("2d").drawImage(n,0,0,r.width,r.height);const s=await new Promise(l=>r.toBlob(l,"image/png"));if(!s)throw new Error("The browser returned an empty screenshot.");return{blob:s,mime:"image/png",kind:"SCREENSHOT"}}finally{t.getTracks().forEach(e=>e.stop())}}async function Yo({maxMs:t=12e4,onTick:e,onAutoStop:n}={}){const o=await navigator.mediaDevices.getDisplayMedia({video:{frameRate:15},audio:!1}),i=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm"].find(u=>MediaRecorder.isTypeSupported(u))||"video/webm",r=new MediaRecorder(o,{mimeType:i,videoBitsPerSecond:25e5}),s=[];r.ondataavailable=u=>{u.data.size&&s.push(u.data)},r.start(1e3);const l=Date.now(),g=setInterval(()=>e==null?void 0:e(Math.floor((Date.now()-l)/1e3)),500),f=()=>{clearInterval(g),clearTimeout(h),o.getTracks().forEach(u=>u.stop())},m=new Promise(u=>{r.onstop=()=>{f(),u(new Blob(s,{type:i}))}}),b=()=>{r.state!=="inactive"&&r.stop(),n==null||n()};o.getVideoTracks()[0].addEventListener("ended",b);const h=setTimeout(b,t);return{mime:i,maxMs:t,async stop(){return clearTimeout(h),r.state!=="inactive"&&r.stop(),{blob:await m,mime:i,kind:"VIDEO"}},cancel(){f(),r.state!=="inactive"&&r.stop()}}}async function Xo({maxMs:t=12e4,onTick:e,onAutoStop:n}={}){const o=await navigator.mediaDevices.getUserMedia({audio:!0}),i=["audio/webm;codecs=opus","audio/webm","audio/mp4","audio/ogg"].find(u=>MediaRecorder.isTypeSupported(u))||"",r=new MediaRecorder(o,i?{mimeType:i}:void 0),s=[];r.ondataavailable=u=>{u.data.size&&s.push(u.data)},r.start(1e3);const l=Date.now(),g=setInterval(()=>e==null?void 0:e(Math.floor((Date.now()-l)/1e3)),500),f=()=>{clearInterval(g),clearTimeout(h),o.getTracks().forEach(u=>u.stop())},m=new Promise(u=>{r.onstop=()=>{f(),u(new Blob(s,{type:r.mimeType||i}))}}),h=setTimeout(()=>{r.state!=="inactive"&&r.stop(),n==null||n()},t);return{mime:r.mimeType||i,maxMs:t,async stop(){clearTimeout(h),r.state!=="inactive"&&r.stop();const u=await m;return{blob:u,mime:u.type||r.mimeType||i,kind:"AUDIO"}},cancel(){f(),r.state!=="inactive"&&r.stop()}}}async function Jo({apiBase:t,apiKey:e,blob:n,mime:o,onProgress:i}){const r=lt(o||n.type);if(!r)throw new Error(`[BugCatch] ${o||n.type||"that file"} can't be attached.`);const s=await Uo(`${t}/ingest/presign`,{method:"POST",headers:{"Content-Type":"application/json","X-BugCatch-Key":e},body:JSON.stringify({mime:r})});if(!s.ok)throw new Error(`[BugCatch] could not start the upload (HTTP ${s.status}).`);const{key:l,uploadUrl:g}=await s.json();return await Zo(g,n,r,i),{storageKey:l,mime:r}}function Zo(t,e,n,o){return new Promise((i,r)=>{const s=new XMLHttpRequest;Ko.call(s,"PUT",t,!0),s.setRequestHeader("Content-Type",n),s.upload.onprogress=l=>{l.lengthComputable&&(o==null||o(l.loaded/l.total))},s.onload=()=>{s.status>=200&&s.status<300?i():r(new Error(`[BugCatch] upload failed (HTTP ${s.status}).`))},s.onerror=()=>r(new Error("[BugCatch] the browser blocked the upload to storage. If this is a new environment, the media bucket is probably missing its CORS policy.")),s.onabort=()=>r(new Error("[BugCatch] upload cancelled.")),Po.call(s,e)})}function Re(t){return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(0)} KB`:`${(t/1024/1024).toFixed(1)} MB`}function dt(t){const e=Math.floor(t/60),n=t%60;return`${e}:${String(n).padStart(2,"0")}`}const Go=7*24*60*60*1e3;let ut;function ea(){return ut||(ut=new Promise((t,e)=>{const n=indexedDB.open("bugcatch-drafts",1);n.onupgradeneeded=()=>n.result.createObjectStore("drafts"),n.onsuccess=()=>t(n.result),n.onerror=()=>e(n.error),n.onblocked=()=>e(new Error("Draft storage is blocked."))}).catch(t=>{throw ut=null,t})),ut}function ta(t,e){var n,o;return JSON.stringify([t.apiBase,t.projectId,e||((n=t.user)==null?void 0:n.email)||((o=t.user)==null?void 0:o.id)||"anonymous"])}async function pt(t,e){const n=await ea();return new Promise((o,i)=>{const r=n.transaction("drafts",e===void 0?"readonly":"readwrite"),s=r.objectStore("drafts"),l=e===void 0?s.get(t):e===null?s.delete(t):s.put({...e,savedAt:Date.now()},t);r.oncomplete=()=>o(l.result),r.onerror=()=>i(r.error),r.onabort=()=>i(r.error||new Error("Draft was not saved."))})}async function na(t){const e=await pt(t);return e&&Date.now()-e.savedAt>Go?(await pt(t,null),null):e||null}const oa="bugcatch.session.",At=t=>`${oa}${t}`,Bt=new Map;function Se(t){var e;if(!t)return null;try{const n=(e=window.localStorage)==null?void 0:e.getItem(At(t));if(n){const o=JSON.parse(n);if(o!=null&&o.token)return o}}catch{}return Bt.get(t)||null}function aa(t,e){var o;if(!t||!(e!=null&&e.token))return;const n={token:e.token,email:e.email||null,name:e.name||null};Bt.set(t,n);try{(o=window.localStorage)==null||o.setItem(At(t),JSON.stringify(n))}catch{}}function jt(t){var e;if(t){Bt.delete(t);try{(e=window.localStorage)==null||e.removeItem(At(t))}catch{}}}function ht({apiKey:t,token:e}){return{"Content-Type":"application/json","X-BugCatch-Key":t,...e?{"X-BugCatch-Session":e}:{}}}async function mn(t){try{const e=await t.json(),n=Array.isArray(e.message)?e.message.join(", "):e.message;if(n)return n}catch{}return`Request failed (HTTP ${t.status})`}async function ra({apiBase:t,apiKey:e,projectId:n,token:o}){const i={mode:"off",signedIn:null,signedOutReason:null};try{const r=await fetch(`${t}/ingest/login?projectId=${encodeURIComponent(n)}`,{headers:ht({apiKey:e,token:o})});if(!r.ok)return i;const s=await r.json();return{mode:s.mode==="optional"||s.mode==="required"?s.mode:"off",signedIn:s.signedIn||null,signedOutReason:s.signedOutReason||null}}catch{return i}}async function ia({apiBase:t,apiKey:e,projectId:n,email:o,name:i}){const r=await fetch(`${t}/ingest/login/start`,{method:"POST",headers:ht({apiKey:e}),body:JSON.stringify({projectId:n,email:o,...i?{name:i}:{}})});if(!r.ok)throw new Error(await mn(r));return r.json()}async function sa({apiBase:t,apiKey:e,projectId:n,email:o,code:i}){const r=await fetch(`${t}/ingest/login`,{method:"POST",headers:ht({apiKey:e}),body:JSON.stringify({projectId:n,email:o,code:i})});if(!r.ok)throw new Error(await mn(r));const s=await r.json(),l={token:s.sessionToken,email:s.email,name:s.name};return aa(n,l),l}async function ca({apiBase:t,apiKey:e,projectId:n,token:o}){if(jt(n),!o)return{signedOut:!0};try{await fetch(`${t}/ingest/logout`,{method:"POST",headers:ht({apiKey:e,token:o}),body:JSON.stringify({projectId:n})})}catch{}return{signedOut:!0}}const ft="bugcatch.watch",yn=[2e3,5e3,15e3,3e4,6e4],la=5e3;let Ke=null;function da(t){Ke=t||null}const Rt=()=>Ke?`${ft}:${Ke}`:ft;function zt(){return Ke?`?projectId=${encodeURIComponent(Ke)}`:""}function he(){try{const t=window.localStorage;return(t==null?void 0:t.getItem(Rt()))||(t==null?void 0:t.getItem(ft))||null}catch{return null}}function Ot(t){var e;if(t)try{(e=window.localStorage)==null||e.setItem(Rt(),t)}catch{}}function Ae(){var t,e;try{(t=window.localStorage)==null||t.removeItem(Rt()),(e=window.localStorage)==null||e.removeItem(ft)}catch{}wn()}const gt="bugcatch.unread";function ua(t){return[(t==null?void 0:t.bugId)||"report",(t==null?void 0:t.kind)||"status",(t==null?void 0:t.at)||""].join("|")}function Pe(){var t;try{const e=(t=window.localStorage)==null?void 0:t.getItem(gt),n=e?JSON.parse(e):[];return Array.isArray(n)?n.filter(o=>o&&typeof o.id=="string"):[]}catch{return[]}}function bt(t){var e,n;try{t.length?(e=window.localStorage)==null||e.setItem(gt,JSON.stringify(t)):(n=window.localStorage)==null||n.removeItem(gt)}catch{}}function pa(t){const e={...t,id:ua(t)},n=Pe().filter(o=>o.id!==e.id);return n.push(e),bt(n.slice(-20)),e}function ha(t){const e=Pe().filter(n=>n.id!==t);return bt(e),e}function fa(t){const e=Pe().filter(n=>n.bugId!==t);return bt(e),e}function wn(){return bt([]),[]}function ga(t,e){let n=t,o=n.indexOf(`
|
|
2
2
|
|
|
3
|
-
`);for(;o!==-1;){const i=n.slice(0,o);n=n.slice(o+2);const
|
|
3
|
+
`);for(;o!==-1;){const i=n.slice(0,o);n=n.slice(o+2);const r=i.split(`
|
|
4
4
|
`).filter(s=>s.startsWith("data:")).map(s=>s.slice(5).trim()).join(`
|
|
5
|
-
`);if(
|
|
5
|
+
`);if(r)try{e(JSON.parse(r))}catch{}o=n.indexOf(`
|
|
6
6
|
|
|
7
|
-
`)}return n}async function Wo({apiBase:t}){const e=ce();if(!e)return{reporter:null,reports:[]};const n=await fetch(`${t}/ingest/watch/reports`,{headers:{Authorization:`Bearer ${e}`}});if(n.status===401)return Ie(),{reporter:null,reports:[]};if(!n.ok)throw new Error(`[BugCatch] could not load your reports (HTTP ${n.status})`);return n.json()}async function Yo({apiBase:t,bugId:e}){const n=ce();if(!n)return null;const o=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}`,{headers:{Authorization:`Bearer ${n}`}});if(o.status===401)return Ie(),null;if(o.status===404)return null;if(!o.ok)throw new Error(`[BugCatch] could not load that report (HTTP ${o.status})`);return o.json()}async function ln({apiBase:t,bugId:e,body:n,attachments:o}){const i=ce();if(!i)throw new Error("[BugCatch] nothing filed from this browser yet.");const a=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/messages`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify({...n?{body:n}:{},...o!=null&&o.length?{attachments:o}:{}})});if(a.status===401)throw Ie(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(!a.ok){let s="";try{const l=await a.json();s=Array.isArray(l.message)?l.message.join(", "):l.message||""}catch{}throw new Error(s||`[BugCatch] could not send that (HTTP ${a.status}).`)}return a.json()}async function Xo({apiBase:t,apiKey:e,projectId:n}){const o={agent:!1,live:!1};try{const i=await fetch(`${t}/ingest/calls?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}});if(!i.ok)return o;const a=await i.json();return a!=null&&a.available?a.kinds&&typeof a.kinds=="object"?{agent:!1,live:!!a.kinds.live}:{agent:!1,live:a.kind==="live"}:o}catch{return o}}async function Jo({apiBase:t,apiKey:e,token:n,payload:o}){const i=await fetch(`${t}/ingest/calls`,{method:"POST",headers:{"Content-Type":"application/json","X-BugCatch-Key":e,...n?{"X-BugCatch-Session":n}:{}},body:JSON.stringify(o)});if(!i.ok){let a="";try{const l=await i.json();a=Array.isArray(l.message)?l.message.join(", "):l.message||""}catch{}const s=new Error(a||`[BugCatch] the call could not be started (HTTP ${i.status}).`);throw s.status=i.status,s}return i.json()}async function dn({apiBase:t,bugId:e}){const n=ce();if(!n)return!1;try{const o=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call`,{headers:{Authorization:`Bearer ${n}`}});if(!o.ok)return!1;const i=await o.json();return!!(i!=null&&i.offered)}catch{return!1}}async function Zo({apiBase:t,bugId:e}){const n=ce();if(!n)throw new Error("[BugCatch] nothing filed from this browser yet.");const o=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call`,{method:"POST",headers:{Authorization:`Bearer ${n}`}});if(o.status===401)throw Ie(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(!o.ok){let i="";try{const a=await o.json();i=Array.isArray(a.message)?a.message.join(", "):a.message||""}catch{}throw new Error(i||`[BugCatch] the call could not be started (HTTP ${o.status}).`)}return o.json()}async function Go({apiBase:t,bugId:e,callId:n}){const o=ce();if(o)try{await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/give-up`,{method:"POST",headers:{Authorization:`Bearer ${o}`}})}catch{}}async function ea({apiBase:t,bugId:e,callId:n}){const o=ce();if(!o)throw new Error("[BugCatch] nothing filed from this browser yet.");const i=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/answer`,{method:"POST",headers:{Authorization:`Bearer ${o}`}});if(i.status===401)throw Ie(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(i.status===409)throw new Error("[BugCatch] that call is no longer ringing.");if(!i.ok){let a="";try{const s=await i.json();a=Array.isArray(s.message)?s.message.join(", "):s.message||""}catch{}throw new Error(a||`[BugCatch] the call could not be answered (HTTP ${i.status}).`)}return i.json()}async function un({apiBase:t,bugId:e,callId:n}){const o=ce();if(o)try{await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/decline`,{method:"POST",headers:{Authorization:`Bearer ${o}`}})}catch{}}function ta({apiBase:t,onUpdate:e}){let n=!0,o=0,i=null;async function a(){const s=ce();if(!s)throw new Error("nothing filed from this browser yet");i=new AbortController;const l=await fetch(`${t}/ingest/watch/stream`,{headers:{Authorization:`Bearer ${s}`,Accept:"text/event-stream"},signal:i.signal});if(l.status===401)throw n=!1,Ie(),new Error("subscription no longer valid");if(!l.ok||!l.body)throw new Error(`stream failed (${l.status})`);const p=Date.now(),h=l.body.getReader(),b=new TextDecoder;let f="";try{for(;;){const{value:m,done:g}=await h.read();if(g)break;f+=b.decode(m,{stream:!0}),f=Fo(f,T=>{if(T.type!=="ping")try{e(T)}catch{}})}}finally{Date.now()-p>=Uo&&(o=0)}}return(async()=>{for(;n;){try{await a()}catch(l){if((l==null?void 0:l.name)==="AbortError")return}if(!n)return;const s=sn[Math.min(o,sn.length-1)];o+=1,await new Promise(l=>setTimeout(l,s))}})(),()=>{n=!1,i==null||i.abort(),i=null}}const na={OPEN:"is open",IN_PROGRESS:"is being worked on",RESOLVED:"has been fixed",CLOSED:"has been closed"},oa={status:null,severity:"#e8912a",assignment:"#4da3ff",reply:"#35b87f"};function pn(t){return t!=null&&t.summary?t.summary:`Your report ${na[t==null?void 0:t.status]||"was updated"}`}function aa(t){var e;return(t==null?void 0:t.kind)==="reply"&&((e=t.reply)!=null&&e.body)?`${t.reply.author?`${t.reply.author}: `:""}${t.reply.body}`:(t==null?void 0:t.title)||""}function ra(t){const e=Date.parse(t||"");if(!Number.isFinite(e))return"";const n=Math.round((Date.now()-e)/6e4);if(n<1)return"just now";if(n<60)return`${n}m ago`;const o=Math.round(n/60);if(o<24)return`${o}h ago`;const i=Math.round(o/24);return i===1?"yesterday":`${i}d ago`}function ia(){var t;try{const e=document.querySelector('[data-bugcatch="widget"]'),n=(t=e==null?void 0:e.shadowRoot)==null?void 0:t.querySelector(".dock"),o=(n==null?void 0:n.getBoundingClientRect().height)||0;return o?Math.round(o)+12:0}catch{return 0}}function sa({accent:t="#4F46E5",position:e="bottom-right",onRead:n=null,onReadAll:o=null,onCall:i=null}={}){const[a,s]=String(e).split("-"),l=a==="top",p=s==="left",h=new Map;let b=null,f=null;function m(){return b!=null&&b.isConnected||(b=document.createElement("div"),b.setAttribute("data-bugcatch","updates"),b.style.cssText=["position:fixed",`${l?"top":"bottom"}:${20+ia()}px`,`${p?"left":"right"}:20px`,"z-index:2147482998","display:flex","flex-direction:column","gap:10px",`align-items:${p?"flex-start":"flex-end"}`,"width:min(320px,calc(100vw - 40px))","pointer-events:none"].join(";"),document.body.appendChild(b)),b}function g($){if(!$._bcShown){$.remove();return}$.style.opacity="0",$.style.transform=`translateY(${l?-8:8}px)`,setTimeout(()=>$.remove(),250)}function T($,L){const B=document.createElement("button");return B.type="button",B.textContent=$,B.style.cssText=["padding:5px 11px",`border:${L?"0":"1px solid rgba(236,238,242,.24)"}`,"border-radius:6px",`background:${L?t:"transparent"}`,`color:${L?"#fff":"#eceef2"}`,"font:600 12px/1.4 inherit","cursor:pointer","white-space:nowrap"].join(";"),B}function Q($){var q;const L=document.createElement("div");L.setAttribute("role","status"),L.style.cssText=["box-sizing:border-box","width:100%","padding:12px 14px","border-radius:10px","background:#1b1e26","color:#eceef2",'font:13px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',"box-shadow:0 12px 30px rgba(0,0,0,0.45)",`border-left:3px solid ${oa[$==null?void 0:$.kind]||t}`,"opacity:0",`transform:translateY(${l?-8:8}px)`,"transition:opacity .2s ease,transform .2s ease","pointer-events:auto"].join(";");const B=document.createElement("div");B.style.cssText="font-weight:600;margin-bottom:2px",B.textContent=pn($);const j=document.createElement("div");j.style.cssText=($==null?void 0:$.kind)==="reply"?"color:#a4abba;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden":"color:#a4abba",j.textContent=aa($);const N=document.createElement("div");N.style.cssText="display:flex;align-items:center;gap:8px;margin-top:10px;flex-wrap:wrap";const S=document.createElement("span");S.style.cssText="color:#7b8394;font-size:11px;margin-right:auto",S.textContent=ra($==null?void 0:$.at);const U=T("Mark as read",!1);if(U.setAttribute("aria-label",`Mark as read: ${pn($)}`),U.addEventListener("click",()=>n==null?void 0:n($.id)),N.append(S,U),(q=$==null?void 0:$.call)!=null&&q.offered&&typeof i=="function"){const I=T("Talk it through",!0);I.addEventListener("click",()=>i($)),N.insertBefore(I,U)}return L.append(B,j,N),L}function V($){const L=document.createElement("div");L.style.cssText=["box-sizing:border-box","width:100%","display:flex","align-items:center","gap:8px","padding:8px 12px","border-radius:10px","background:#1b1e26","color:#a4abba",'font:12px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',"box-shadow:0 12px 30px rgba(0,0,0,0.45)","pointer-events:auto"].join(";");const B=document.createElement("span");B.style.cssText="margin-right:auto",B.textContent=`${$} more update${$===1?"":"s"}`;const j=T("Mark all as read",!1);return j.style.cssText+=";padding:4px 9px",j.addEventListener("click",()=>o==null?void 0:o()),L.append(B,j),L}return{render($){const L=Array.isArray($)?$:[];if(!L.length){for(const I of h.values())g(I);h.clear(),f==null||f.remove(),f=null,b==null||b.remove(),b=null;return}const B=L.slice(-3),j=new Set(B.map(I=>I.id)),N=m();for(const[I,Z]of h)j.has(I)||(g(Z),h.delete(I));const S=[];for(const I of B){if(h.has(I.id))continue;const Z=Q(I);h.set(I.id,Z),S.push(Z)}const U=l?[...B].reverse():B;for(const I of U)N.appendChild(h.get(I.id));const q=L.length-B.length;q>0?(f==null||f.remove(),f=V(q),l?N.appendChild(f):N.insertBefore(f,N.firstChild)):(f==null||f.remove(),f=null),requestAnimationFrame(()=>{for(const I of S)I.isConnected&&(I._bcShown=!0,I.style.opacity="1",I.style.transform="translateY(0)")})},destroy(){h.clear(),f=null,b==null||b.remove(),b=null}}}async function ca({apiBase:t,apiKey:e,projectId:n,sessionToken:o}){try{const i=await fetch(`${t}/ingest/known-issues?projectId=${encodeURIComponent(n)}`,{headers:Lt(e,o)});if(!i.ok)return[];const a=await i.json();return Array.isArray(a==null?void 0:a.issues)?a.issues:[]}catch{return[]}}async function la({apiBase:t,apiKey:e,projectId:n,q:o,sessionToken:i,signal:a}){try{const s=`${t}/ingest/known-issues/match?projectId=${encodeURIComponent(n)}&q=${encodeURIComponent(o)}`,l=await fetch(s,{headers:Lt(e,i),signal:a});if(!l.ok)return[];const p=await l.json();return Array.isArray(p==null?void 0:p.issues)?p.issues:[]}catch{return[]}}async function da({apiBase:t,apiKey:e,projectId:n,bugId:o,reporterEmail:i,reporterName:a,metadata:s,logs:l,sessionToken:p}){const h=await fetch(`${t}/ingest/known-issues/${encodeURIComponent(o)}/join`,{method:"POST",headers:Lt(e,p),body:JSON.stringify({projectId:n,reporterEmail:i,reporterName:a,metadata:s,logs:l})});if(!h.ok)throw new Error(await ua(h));const b=await h.json();return b!=null&&b.watchToken&&At(b.watchToken),b}function Lt(t,e){return{"Content-Type":"application/json","X-BugCatch-Key":t,...e?{"X-BugCatch-Session":e}:{}}}async function ua(t){try{const e=await t.json(),n=Array.isArray(e.message)?e.message.join(", "):e.message;if(n)return n}catch{}return`Could not add you to this issue (HTTP ${t.status})`}async function pa({apiBase:t,bugId:e,...n}){const o=ce();if(!o)throw new Error("This browser cannot access that report.");const i=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/verification`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`},body:JSON.stringify(n)}),a=await i.json().catch(()=>({}));if(!i.ok)throw new Error(a.message||"Could not record feedback. Please refresh and try again.");return a}const ha=2e4,hn=120,fn=200;function gn(t){if(typeof t!="string"||!t.trim()||t.length>400)return null;try{return new RegExp(t.trim(),"gi")}catch{return null}}const fa=t=>String(t).replace(/\s+/g," ").trim().slice(0,hn);function bn(t){const e=t.length>1&&t[1]!==void 0?t[1]:t[0];return typeof e!="string"||!e.trim()?null:{value:fa(e),start:t.index,end:t.index+t[0].length}}function ga(t,e){const n=[],o=new Set;for(const i of e||[]){const a=typeof i=="string"?i.slice(0,ha):"";if(!a)continue;const s=[],l=(p,h)=>s.some(([b,f])=>p<f&&h>b);for(const p of t||[]){if(!p||p.scan===!1)continue;const h=gn(p.pattern);if(!h)continue;let b,f=0;for(h.lastIndex=0;(b=h.exec(a))!==null&&!(++f>fn);){if(b[0]===""){h.lastIndex+=1;continue}const m=bn(b);if(m&&!l(m.start,m.end)){s.push([m.start,m.end]);const g=`${p.key}:${m.value.toLowerCase()}`;o.has(g)||(o.add(g),n.push({key:p.key,label:p.label,value:m.value}))}}}}return n}function ba(t,e){const n=typeof e=="string"?e.trim():"";if(!n||n.length>hn)return null;const o=gn(t&&(t.valuePattern||t.pattern));if(!o)return null;let i,a=0;for(o.lastIndex=0;(i=o.exec(n))!==null&&!(++a>fn);){if(i[0]===""){o.lastIndex+=1;continue}const s=i.index+i[0].length===n.length,l=i.index===0||i.index===1;if(s&&l){const p=bn(i);if(p)return p.value}}return null}async function ma({apiBase:t,apiKey:e,projectId:n}){const o={policy:"off",fields:[]};try{const i=await fetch(`${t}/ingest/reference-fields?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}});if(!i.ok)return o;const a=await i.json(),s=a.policy==="optional"||a.policy==="required"?a.policy:"off",l=Array.isArray(a.fields)?a.fields:[];return l.length?{policy:s,fields:l}:o}catch{return o}}const mn={"bottom-right":"bottom:20px;right:20px;","bottom-left":"bottom:20px;left:20px;","top-right":"top:20px;right:20px;","top-left":"top:20px;left:20px;"},yn=[{value:"LOW",label:"Low"},{value:"MEDIUM",label:"Medium"},{value:"HIGH",label:"High"},{value:"CRITICAL",label:"Critical"}],M={camera:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8.5A1.5 1.5 0 0 1 4.5 7h2.2a1 1 0 0 0 .83-.45l.94-1.4A1 1 0 0 1 9.3 4.7h5.4a1 1 0 0 1 .83.45l.94 1.4a1 1 0 0 0 .83.45h2.2A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z"/><circle cx="12" cy="13" r="3.4"/></svg>',video:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="6" width="12.5" height="12" rx="2.2"/><path d="M15.5 10.8l4.2-2.6a.6.6 0 0 1 .92.5v6.6a.6.6 0 0 1-.92.5l-4.2-2.6z"/></svg>',paperclip:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20 11.5l-7.6 7.6a4.6 4.6 0 0 1-6.5-6.5l8-8a3.2 3.2 0 0 1 4.5 4.5l-8 8a1.8 1.8 0 0 1-2.5-2.5l7.1-7.1"/></svg>',close:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>',mic:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="2.5" width="6" height="11" rx="3"/><path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21M9 21h6"/></svg>',send:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l16-8-6 16-2.6-6.2L4 12Z"/></svg>',stopSquare:'<svg viewBox="0 0 24 24" fill="currentColor"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>',back:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 5.5L8 12l6.5 6.5"/></svg>',phone:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.2 3.5h3l1.5 3.7-2 1.4a11.5 11.5 0 0 0 5.7 5.7l1.4-2 3.7 1.5v3a1.8 1.8 0 0 1-2 1.8A15.6 15.6 0 0 1 4.4 5.5a1.8 1.8 0 0 1 1.8-2z"/></svg>',phoneOff:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.2 3.5h3l1.5 3.7-2 1.4a11.5 11.5 0 0 0 5.7 5.7l1.4-2 3.7 1.5v3a1.8 1.8 0 0 1-2 1.8A15.6 15.6 0 0 1 4.4 5.5a1.8 1.8 0 0 1 1.8-2z"/><path d="M3 21L21 3"/></svg>',bug:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6a4 4 0 0 1 8 0"/><rect x="7" y="7.5" width="10" height="12" rx="5"/><path d="M7 11H3.5M7 15.5H4M17 11h3.5M17 15.5h3M12 8v11.5"/></svg>',check:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.8l4.6 4.4L19 7"/></svg>',retry:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 12a8 8 0 1 1-2.6-5.9M20 4v4.5h-4.5"/></svg>',sun:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4.2"/><path d="M12 2.6v2.2M12 19.2v2.2M2.6 12h2.2M19.2 12h2.2M5.4 5.4l1.6 1.6M17 17l1.6 1.6M18.6 5.4L17 7M7 17l-1.6 1.6"/></svg>',moon:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13.4A8.2 8.2 0 1 1 10.6 4a6.6 6.6 0 0 0 9.4 9.4z"/></svg>',auto:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2.8" y="4.4" width="18.4" height="12.6" rx="2.2"/><path d="M8.6 20.2h6.8"/><path d="M12 4.4v12.6"/><path d="M12 7.2a3.6 3.6 0 0 1 0 7.2z" fill="currentColor" stroke="none"/></svg>',sparkle:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.5c.5 4.6 2.9 7 7.5 7.5v.1c-4.6.5-7 2.9-7.5 7.5h-.1c-.5-4.6-2.9-7-7.5-7.5V10c4.6-.5 7-2.9 7.5-7.5z"/><path d="M18.6 15.2c.2 1.9 1.2 2.9 3.1 3.1v.1c-1.9.2-2.9 1.2-3.1 3.1h-.1c-.2-1.9-1.2-2.9-3.1-3.1v-.1c1.9-.2 2.9-1.2 3.1-3.1z" opacity=".7"/></svg>',chat:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 11.5a7.5 7 0 0 1 7.5-7h1a7.5 7 0 0 1 0 14H9l-4.2 2.6a.5.5 0 0 1-.76-.5l.5-3.1A7 7 0 0 1 4 11.5z"/><path d="M8.5 11.5h.01M12 11.5h.01M15.5 11.5h.01" stroke-width="2.6"/></svg>',chevronDown:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9.5l6 6 6-6"/></svg>',chevronRight:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.5 6l6 6-6 6"/></svg>',alert:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7.5v5.2M12 16.3h.01"/></svg>',inbox:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 13.5l2.6-7.2A1.5 1.5 0 0 1 7.5 5.3h9a1.5 1.5 0 0 1 1.4 1L20.5 13.5V18a1.5 1.5 0 0 1-1.5 1.5H5A1.5 1.5 0 0 1 3.5 18z"/><path d="M3.5 13.5h4.8l1.2 2.2h5l1.2-2.2h4.8"/></svg>'},ya='<svg class="bc-brand" viewBox="0 0 254 60" fill="none" role="img" aria-label="sphoro BugCatch"><g fill="currentColor"><path transform="translate(0.00 40.00) scale(0.04000 -0.04000)" d="M276.00 -14.00Q179.00 -14.00 117.00 28.00Q55.00 70.00 42.00 148.00L158.00 178.00Q165.00 143.00 181.50 123.00Q198.00 103.00 222.50 94.50Q247.00 86.00 276.00 86.00Q320.00 86.00 341.00 101.50Q362.00 117.00 362.00 140.00Q362.00 163.00 342.00 175.50Q322.00 188.00 278.00 196.00L250.00 201.00Q198.00 211.00 155.00 228.50Q112.00 246.00 86.00 277.00Q60.00 308.00 60.00 357.00Q60.00 431.00 114.00 470.50Q168.00 510.00 256.00 510.00Q339.00 510.00 394.00 473.00Q449.00 436.00 466.00 376.00L349.00 340.00Q341.00 378.00 316.50 394.00Q292.00 410.00 256.00 410.00Q220.00 410.00 201.00 397.50Q182.00 385.00 182.00 363.00Q182.00 339.00 202.00 327.50Q222.00 316.00 256.00 310.00L284.00 305.00Q340.00 295.00 385.50 278.50Q431.00 262.00 457.50 231.50Q484.00 201.00 484.00 149.00Q484.00 71.00 427.50 28.50Q371.00 -14.00 276.00 -14.00Z"/><path transform="translate(19.56 40.00) scale(0.04000 -0.04000)" d="M70.00 -200.00V496.00H194.00V436.00H212.00Q229.00 465.00 265.00 487.50Q301.00 510.00 368.00 510.00Q428.00 510.00 479.00 480.50Q530.00 451.00 561.00 394.00Q592.00 337.00 592.00 256.00V240.00Q592.00 159.00 561.00 102.00Q530.00 45.00 479.00 15.50Q428.00 -14.00 368.00 -14.00Q323.00 -14.00 292.50 -3.50Q262.00 7.00 243.50 23.50Q225.00 40.00 214.00 57.00H196.00V-200.00ZM330.00 96.00Q389.00 96.00 427.50 133.50Q466.00 171.00 466.00 243.00V253.00Q466.00 325.00 427.00 362.50Q388.00 400.00 330.00 400.00Q272.00 400.00 233.00 362.50Q194.00 325.00 194.00 253.00V243.00Q194.00 171.00 233.00 133.50Q272.00 96.00 330.00 96.00Z"/><path transform="translate(43.68 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V700.00H196.00V435.00H214.00Q222.00 451.00 239.00 467.00Q256.00 483.00 284.50 493.50Q313.00 504.00 357.00 504.00Q415.00 504.00 458.50 477.50Q502.00 451.00 526.00 404.50Q550.00 358.00 550.00 296.00V0.00H424.00V286.00Q424.00 342.00 396.50 370.00Q369.00 398.00 318.00 398.00Q260.00 398.00 228.00 359.50Q196.00 321.00 196.00 252.00V0.00Z"/><path transform="translate(66.92 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/><path transform="translate(90.00 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V496.00H194.00V440.00H212.00Q223.00 470.00 248.50 484.00Q274.00 498.00 308.00 498.00H368.00V386.00H306.00Q258.00 386.00 227.00 360.50Q196.00 335.00 196.00 282.00V0.00Z"/><path transform="translate(104.44 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/></g><rect x="139.52" y="16" width="1.6" height="26" rx="0.8" fill="var(--bc-brand-mark, #5647ee)" opacity="0.4"/><g fill="var(--bc-brand-mark, #5647ee)"><path transform="translate(154.52 35.00) scale(0.01400 -0.01400)" d="M46.35 0.00V105.85H139.75V594.15H46.35V700.00H404.08Q467.38 700.00 514.79 678.41Q562.20 656.83 588.70 617.33Q615.20 577.83 615.20 523.35V513.70Q615.20 465.52 597.03 434.76Q578.85 404.00 553.91 387.24Q528.98 370.48 506.28 363.30V346.35Q528.98 340.35 555.24 323.50Q581.50 306.65 600.00 275.48Q618.50 244.30 618.50 194.48V184.48Q618.50 126.65 591.41 85.24Q564.33 43.83 516.83 21.91Q469.33 0.00 406.85 0.00ZM259.85 109.15H392.60Q441.20 109.15 469.80 132.60Q498.40 156.05 498.40 198.55V208.20Q498.40 250.70 470.21 274.15Q442.02 297.60 392.60 297.60H259.85ZM259.85 406.75H391.65Q437.55 406.75 466.32 430.11Q495.10 453.48 495.10 493.80V503.80Q495.10 544.95 466.74 567.90Q438.37 590.85 391.65 590.85H259.85Z"/><path transform="translate(167.00 35.00) scale(0.01400 -0.01400)" d="M335.30 -14.00Q251.22 -14.00 190.60 16.63Q129.97 47.25 97.56 104.96Q65.15 162.68 65.15 243.03V700.00H185.25V239.73Q185.25 170.48 224.03 131.99Q262.80 93.50 335.30 93.50Q407.80 93.50 446.57 131.99Q485.35 170.48 485.35 239.73V700.00H605.45V243.03Q605.45 162.68 573.13 104.96Q540.80 47.25 480.09 16.63Q419.38 -14.00 335.30 -14.00Z"/><path transform="translate(179.60 35.00) scale(0.01400 -0.01400)" d="M311.85 -14.00Q238.45 -14.00 179.69 18.50Q120.92 51.00 86.69 113.67Q52.45 176.35 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.23 645.59Q598.33 577.17 598.33 460.87V456.70H479.87V464.52Q479.87 504.67 463.76 536.86Q447.65 569.05 414.99 587.77Q382.32 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 138.89Q257.63 91.85 334.00 91.85Q410.02 91.85 445.12 132.83Q480.22 173.80 480.22 237.92V249.67H302.85V351.88H598.33V0.00H487.52V69.10H470.57Q462.70 50.87 446.06 31.44Q429.42 12.00 397.64 -1.00Q365.85 -14.00 311.85 -14.00Z"/><path transform="translate(192.05 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(204.25 35.00) scale(0.01400 -0.01400)" d="M19.75 0.00 211.62 700.00H421.33L613.20 0.00H489.27L447.42 159.60H185.53L143.68 0.00ZM214.25 270.40H418.70L324.95 624.87H308.00Z"/><path transform="translate(216.31 35.00) scale(0.01400 -0.01400)" d="M233.95 0.00V590.85H24.70V700.00H563.30V590.85H354.05V0.00Z"/><path transform="translate(227.75 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(239.95 35.00) scale(0.01400 -0.01400)" d="M69.50 0.00V700.00H189.60V405.58H466.40V700.00H586.50V0.00H466.40V296.42H189.60V0.00Z"/></g></svg>',wn=[{value:"light",label:"Light",icon:M.sun},{value:"dark",label:"Dark",icon:M.moon},{value:"auto",label:"System default",icon:M.auto}],vn="bugcatch:theme";function wa(){try{const t=localStorage.getItem(vn);return wn.some(e=>e.value===t)?t:null}catch{return null}}function va(t){try{localStorage.setItem(vn,t)}catch{}}const xa=t=>`
|
|
7
|
+
`)}return n}async function ba({apiBase:t}){const e=he();if(!e)return{reporter:null,reports:[]};const n=await fetch(`${t}/ingest/watch/reports${zt()}`,{headers:{Authorization:`Bearer ${e}`}});if(n.status===401)return Ae(),{reporter:null,reports:[]};if(!n.ok)throw new Error(`[BugCatch] could not load your reports (HTTP ${n.status})`);return n.json()}async function ma({apiBase:t,bugId:e}){const n=he();if(!n)return null;const o=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}${zt()}`,{headers:{Authorization:`Bearer ${n}`}});if(o.status===401)return Ae(),null;if(o.status===404)return null;if(!o.ok)throw new Error(`[BugCatch] could not load that report (HTTP ${o.status})`);return o.json()}async function vn({apiBase:t,bugId:e,body:n,attachments:o}){const i=he();if(!i)throw new Error("[BugCatch] nothing filed from this browser yet.");const r=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/messages`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify({...n?{body:n}:{},...o!=null&&o.length?{attachments:o}:{}})});if(r.status===401)throw Ae(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(!r.ok){let s="";try{const l=await r.json();s=Array.isArray(l.message)?l.message.join(", "):l.message||""}catch{}throw new Error(s||`[BugCatch] could not send that (HTTP ${r.status}).`)}return r.json()}async function ya({apiBase:t,apiKey:e,projectId:n}){const o={agent:!1,live:!1};try{const i=await fetch(`${t}/ingest/calls?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}});if(!i.ok)return o;const r=await i.json();return r!=null&&r.available?r.kinds&&typeof r.kinds=="object"?{agent:!1,live:!!r.kinds.live}:{agent:!1,live:r.kind==="live"}:o}catch{return o}}async function wa({apiBase:t,apiKey:e,token:n,payload:o}){const i=await fetch(`${t}/ingest/calls`,{method:"POST",headers:{"Content-Type":"application/json","X-BugCatch-Key":e,...n?{"X-BugCatch-Session":n}:{}},body:JSON.stringify(o)});if(!i.ok){let r="";try{const l=await i.json();r=Array.isArray(l.message)?l.message.join(", "):l.message||""}catch{}const s=new Error(r||`[BugCatch] the call could not be started (HTTP ${i.status}).`);throw s.status=i.status,s}return i.json()}async function xn({apiBase:t,bugId:e}){const n=he();if(!n)return!1;try{const o=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call`,{headers:{Authorization:`Bearer ${n}`}});if(!o.ok)return!1;const i=await o.json();return!!(i!=null&&i.offered)}catch{return!1}}async function va({apiBase:t,bugId:e}){const n=he();if(!n)throw new Error("[BugCatch] nothing filed from this browser yet.");const o=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call`,{method:"POST",headers:{Authorization:`Bearer ${n}`}});if(o.status===401)throw Ae(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(!o.ok){let i="";try{const r=await o.json();i=Array.isArray(r.message)?r.message.join(", "):r.message||""}catch{}throw new Error(i||`[BugCatch] the call could not be started (HTTP ${o.status}).`)}return o.json()}async function xa({apiBase:t,bugId:e,callId:n}){const o=he();if(o)try{await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/give-up`,{method:"POST",headers:{Authorization:`Bearer ${o}`}})}catch{}}async function ka({apiBase:t,bugId:e,callId:n}){const o=he();if(!o)throw new Error("[BugCatch] nothing filed from this browser yet.");const i=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/answer`,{method:"POST",headers:{Authorization:`Bearer ${o}`}});if(i.status===401)throw Ae(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(i.status===409)throw new Error("[BugCatch] that call is no longer ringing.");if(!i.ok){let r="";try{const s=await i.json();r=Array.isArray(s.message)?s.message.join(", "):s.message||""}catch{}throw new Error(r||`[BugCatch] the call could not be answered (HTTP ${i.status}).`)}return i.json()}async function kn({apiBase:t,bugId:e,callId:n}){const o=he();if(o)try{await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/decline`,{method:"POST",headers:{Authorization:`Bearer ${o}`}})}catch{}}function Sa({apiBase:t,onUpdate:e}){let n=!0,o=0,i=null;async function r(){const s=he();if(!s)throw new Error("nothing filed from this browser yet");i=new AbortController;const l=await fetch(`${t}/ingest/watch/stream${zt()}`,{headers:{Authorization:`Bearer ${s}`,Accept:"text/event-stream"},signal:i.signal});if(l.status===401)throw n=!1,Ae(),new Error("subscription no longer valid");if(!l.ok||!l.body)throw new Error(`stream failed (${l.status})`);const g=Date.now(),f=l.body.getReader(),m=new TextDecoder;let b="";try{for(;;){const{value:h,done:u}=await f.read();if(u)break;b+=m.decode(h,{stream:!0}),b=ga(b,k=>{if(k.type!=="ping")try{e(k)}catch{}})}}finally{Date.now()-g>=la&&(o=0)}}return(async()=>{for(;n;){try{await r()}catch(l){if((l==null?void 0:l.name)==="AbortError")return}if(!n)return;const s=yn[Math.min(o,yn.length-1)];o+=1,await new Promise(l=>setTimeout(l,s))}})(),()=>{n=!1,i==null||i.abort(),i=null}}const $a={OPEN:"is open",IN_PROGRESS:"is being worked on",RESOLVED:"has been fixed",CLOSED:"has been closed"},Ca={status:null,severity:"#e8912a",assignment:"#4da3ff",reply:"#35b87f"};function Sn(t){return t!=null&&t.summary?t.summary:`Your report ${$a[t==null?void 0:t.status]||"was updated"}`}function Ta(t){var e;return(t==null?void 0:t.kind)==="reply"&&((e=t.reply)!=null&&e.body)?`${t.reply.author?`${t.reply.author}: `:""}${t.reply.body}`:(t==null?void 0:t.title)||""}function Ea(t){const e=Date.parse(t||"");if(!Number.isFinite(e))return"";const n=Math.round((Date.now()-e)/6e4);if(n<1)return"just now";if(n<60)return`${n}m ago`;const o=Math.round(n/60);if(o<24)return`${o}h ago`;const i=Math.round(o/24);return i===1?"yesterday":`${i}d ago`}function Ia(){var t;try{const e=document.querySelector('[data-bugcatch="widget"]'),n=(t=e==null?void 0:e.shadowRoot)==null?void 0:t.querySelector(".dock"),o=(n==null?void 0:n.getBoundingClientRect().height)||0;return o?Math.round(o)+12:0}catch{return 0}}function Ma({accent:t="#4F46E5",position:e="bottom-right",onRead:n=null,onReadAll:o=null,onCall:i=null}={}){const[r,s]=String(e).split("-"),l=r==="top",g=s==="left",f=new Map;let m=null,b=null;function h(){return m!=null&&m.isConnected||(m=document.createElement("div"),m.setAttribute("data-bugcatch","updates"),m.style.cssText=["position:fixed",`${l?"top":"bottom"}:${20+Ia()}px`,`${g?"left":"right"}:20px`,"z-index:2147482998","display:flex","flex-direction:column","gap:10px",`align-items:${g?"flex-start":"flex-end"}`,"width:min(320px,calc(100vw - 40px))","pointer-events:none"].join(";"),document.body.appendChild(m)),m}function u(S){if(!S._bcShown){S.remove();return}S.style.opacity="0",S.style.transform=`translateY(${l?-8:8}px)`,setTimeout(()=>S.remove(),250)}function k(S,M){const I=document.createElement("button");return I.type="button",I.textContent=S,I.style.cssText=["padding:5px 11px",`border:${M?"0":"1px solid rgba(236,238,242,.24)"}`,"border-radius:6px",`background:${M?t:"transparent"}`,`color:${M?"#fff":"#eceef2"}`,"font:600 12px/1.4 inherit","cursor:pointer","white-space:nowrap"].join(";"),I}function R(S){var Q;const M=document.createElement("div");M.setAttribute("role","status"),M.style.cssText=["box-sizing:border-box","width:100%","padding:12px 14px","border-radius:10px","background:#1b1e26","color:#eceef2",'font:13px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',"box-shadow:0 12px 30px rgba(0,0,0,0.45)",`border-left:3px solid ${Ca[S==null?void 0:S.kind]||t}`,"opacity:0",`transform:translateY(${l?-8:8}px)`,"transition:opacity .2s ease,transform .2s ease","pointer-events:auto"].join(";");const I=document.createElement("div");I.style.cssText="font-weight:600;margin-bottom:2px",I.textContent=Sn(S);const A=document.createElement("div");A.style.cssText=(S==null?void 0:S.kind)==="reply"?"color:#a4abba;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden":"color:#a4abba",A.textContent=Ta(S);const H=document.createElement("div");H.style.cssText="display:flex;align-items:center;gap:8px;margin-top:10px;flex-wrap:wrap";const U=document.createElement("span");U.style.cssText="color:#7b8394;font-size:11px;margin-right:auto",U.textContent=Ea(S==null?void 0:S.at);const T=k("Mark as read",!1);if(T.setAttribute("aria-label",`Mark as read: ${Sn(S)}`),T.addEventListener("click",()=>n==null?void 0:n(S.id)),H.append(U,T),(Q=S==null?void 0:S.call)!=null&&Q.offered&&typeof i=="function"){const $=k("Talk it through",!0);$.addEventListener("click",()=>i(S)),H.insertBefore($,T)}return M.append(I,A,H),M}function z(S){const M=document.createElement("div");M.style.cssText=["box-sizing:border-box","width:100%","display:flex","align-items:center","gap:8px","padding:8px 12px","border-radius:10px","background:#1b1e26","color:#a4abba",'font:12px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',"box-shadow:0 12px 30px rgba(0,0,0,0.45)","pointer-events:auto"].join(";");const I=document.createElement("span");I.style.cssText="margin-right:auto",I.textContent=`${S} more update${S===1?"":"s"}`;const A=k("Mark all as read",!1);return A.style.cssText+=";padding:4px 9px",A.addEventListener("click",()=>o==null?void 0:o()),M.append(I,A),M}return{render(S){const M=Array.isArray(S)?S:[];if(!M.length){for(const $ of f.values())u($);f.clear(),b==null||b.remove(),b=null,m==null||m.remove(),m=null;return}const I=M.slice(-3),A=new Set(I.map($=>$.id)),H=h();for(const[$,Y]of f)A.has($)||(u(Y),f.delete($));const U=[];for(const $ of I){if(f.has($.id))continue;const Y=R($);f.set($.id,Y),U.push(Y)}const T=l?[...I].reverse():I;for(const $ of T)H.appendChild(f.get($.id));const Q=M.length-I.length;Q>0?(b==null||b.remove(),b=z(Q),l?H.appendChild(b):H.insertBefore(b,H.firstChild)):(b==null||b.remove(),b=null),requestAnimationFrame(()=>{for(const $ of U)$.isConnected&&($._bcShown=!0,$.style.opacity="1",$.style.transform="translateY(0)")})},destroy(){f.clear(),b=null,m==null||m.remove(),m=null}}}async function La({apiBase:t,apiKey:e,projectId:n,sessionToken:o}){try{const i=await fetch(`${t}/ingest/known-issues?projectId=${encodeURIComponent(n)}`,{headers:Qt(e,o)});if(!i.ok)return[];const r=await i.json();return Array.isArray(r==null?void 0:r.issues)?r.issues:[]}catch{return[]}}async function Aa({apiBase:t,apiKey:e,projectId:n,q:o,sessionToken:i,signal:r}){try{const s=`${t}/ingest/known-issues/match?projectId=${encodeURIComponent(n)}&q=${encodeURIComponent(o)}`,l=await fetch(s,{headers:Qt(e,i),signal:r});if(!l.ok)return[];const g=await l.json();return Array.isArray(g==null?void 0:g.issues)?g.issues:[]}catch{return[]}}async function Ba({apiBase:t,apiKey:e,projectId:n,bugId:o,reporterEmail:i,reporterName:r,metadata:s,logs:l,sessionToken:g}){const f=await fetch(`${t}/ingest/known-issues/${encodeURIComponent(o)}/join`,{method:"POST",headers:Qt(e,g),body:JSON.stringify({projectId:n,reporterEmail:i,reporterName:r,metadata:s,logs:l})});if(!f.ok)throw new Error(await ja(f));const m=await f.json();return m!=null&&m.watchToken&&Ot(m.watchToken),m}function Qt(t,e){return{"Content-Type":"application/json","X-BugCatch-Key":t,...e?{"X-BugCatch-Session":e}:{}}}async function ja(t){try{const e=await t.json(),n=Array.isArray(e.message)?e.message.join(", "):e.message;if(n)return n}catch{}return`Could not add you to this issue (HTTP ${t.status})`}async function Ra({apiBase:t,bugId:e,...n}){const o=he();if(!o)throw new Error("This browser cannot access that report.");const i=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/verification`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`},body:JSON.stringify(n)}),r=await i.json().catch(()=>({}));if(!i.ok)throw new Error(r.message||"Could not record feedback. Please refresh and try again.");return r}const za=2e4,$n=120,Ht=200;function Cn(t){if(typeof t!="string"||!t.trim()||t.length>400)return null;try{return new RegExp(t.trim(),"gi")}catch{return null}}const Tn=t=>String(t).replace(/\s+/g," ").trim().slice(0,$n);function En(t,e){const n=t&&t.normalize;if(n==="phone"){const o=e.replace(/\D/g,"");return o.length===10?o:o.length===12&&o.startsWith("91")?o.slice(2):o.length===11&&o.startsWith("0")?o.slice(1):e}return n==="upper"?e.toUpperCase():e}function In(t){const e=t.length>1&&t[1]!==void 0?t[1]:t[0];return typeof e!="string"||!e.trim()?null:{value:Tn(e),start:t.index,end:t.index+t[0].length}}function Oa(t,e){return((t.slice(e.start,e.valueStart)+t.slice(e.valueEnd,e.end)).match(/[a-z]/gi)||[]).length}const Qa=/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|[A-Za-z0-9][\w-]{5,40}/gi,Mn=/[\w-]/;function Ha(t,e){const n=(t||[]).filter(h=>h&&h.scan!==!1&&h.pattern),o=[],i=[],r=(e||[]).map(h=>typeof h=="string"?h.slice(0,za):"");r.forEach((h,u)=>{h&&n.forEach((k,R)=>{const z=Cn(k.pattern);if(!z)return;let S,M=0;for(z.lastIndex=0;(S=z.exec(h))!==null&&!(++M>Ht);){if(S[0]===""){z.lastIndex+=1;continue}const I=In(S);if(!I)continue;const A=S.length>1&&S[1]!==void 0?S[1]:S[0],H=S.index+Math.max(0,S[0].indexOf(A)),U={block:u,order:R,key:k.key,label:k.label,value:En(k,I.value),start:I.start,end:I.end,valueStart:H,valueEnd:H+A.length};U.weight=Oa(h,U),o.push(U)}})});const s=o.filter(h=>!o.some(u=>u!==h&&u.block===h.block&&u.key!==h.key&&u.valueStart<=h.valueStart&&u.valueEnd>=h.valueEnd&&u.weight>h.weight)),l=new Map;for(const h of s){const u=h.value.toLowerCase();l.has(u)||l.set(u,{value:h.value,keys:new Map});const k=l.get(u);k.keys.has(h.key)||k.keys.set(h.key,{key:h.key,label:h.label,order:h.order})}const g=[],f=[],m=new Map;for(const h of l.values()){const u=[...h.keys.values()].sort((z,S)=>z.order-S.order);if(u.length>1){f.push({value:h.value,kinds:u.map(({key:z,label:S})=>({key:z,label:S}))});continue}const[{key:k,label:R}]=u;m.has(k)||m.set(k,[]),m.get(k).push({key:k,label:R,value:h.value})}for(const h of m.values())if(h.length===1)g.push(h[0]);else for(const u of h)f.push({value:u.value,kinds:[{key:u.key,label:u.label}]});const b=new Set(l.keys());return r.forEach((h,u)=>{if(!h)return;const k=o.filter(M=>M.block===u),R=new RegExp(Qa.source,"gi");let z,S=0;for(;(z=R.exec(h))!==null&&++S<=Ht;){const M=z.index,I=M+z[0].length;if(k.some($=>M<$.end&&I>$.start))continue;const A=h[M-1]||"",H=h[I]||"";if(Mn.test(A)||Mn.test(H)||A==="/"||A==="@"||H==="@"||A==="."||H==="."&&/\w/.test(h[I+1]||"")||!/\d/.test(z[0]))continue;const U=Tn(z[0]),T=U.toLowerCase();if(b.has(T))continue;const Q=(t||[]).filter($=>$&&Ln($,U)).map(({key:$,label:Y})=>({key:$,label:Y}));Q.length&&(b.add(T),i.push({value:U,kinds:Q}))}}),{found:g,conflicts:f,loose:i}}function Ln(t,e){const n=typeof e=="string"?e.trim():"";if(!n||n.length>$n)return null;const o=Cn(t&&(t.valuePattern||t.pattern));if(!o)return null;let i,r=0;for(o.lastIndex=0;(i=o.exec(n))!==null&&!(++r>Ht);){if(i[0]===""){o.lastIndex+=1;continue}const s=i.index+i[0].length===n.length,l=i.index===0||i.index===1;if(s&&l){const g=In(i);if(g)return En(t,g.value)}}return null}async function qa({apiBase:t,apiKey:e,projectId:n}){const o={policy:"off",fields:[]};try{const i=await fetch(`${t}/ingest/reference-fields?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}});if(!i.ok)return o;const r=await i.json(),s=r.policy==="optional"||r.policy==="required"?r.policy:"off",l=Array.isArray(r.fields)?r.fields:[];return l.length?{policy:s,fields:l}:o}catch{return o}}const An={"bottom-right":"bottom:20px;right:20px;","bottom-left":"bottom:20px;left:20px;","top-right":"top:20px;right:20px;","top-left":"top:20px;left:20px;"},Bn=[{value:"LOW",label:"Low"},{value:"MEDIUM",label:"Medium"},{value:"HIGH",label:"High"},{value:"CRITICAL",label:"Critical"}],B={camera:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8.5A1.5 1.5 0 0 1 4.5 7h2.2a1 1 0 0 0 .83-.45l.94-1.4A1 1 0 0 1 9.3 4.7h5.4a1 1 0 0 1 .83.45l.94 1.4a1 1 0 0 0 .83.45h2.2A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z"/><circle cx="12" cy="13" r="3.4"/></svg>',video:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="6" width="12.5" height="12" rx="2.2"/><path d="M15.5 10.8l4.2-2.6a.6.6 0 0 1 .92.5v6.6a.6.6 0 0 1-.92.5l-4.2-2.6z"/></svg>',paperclip:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20 11.5l-7.6 7.6a4.6 4.6 0 0 1-6.5-6.5l8-8a3.2 3.2 0 0 1 4.5 4.5l-8 8a1.8 1.8 0 0 1-2.5-2.5l7.1-7.1"/></svg>',close:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>',mic:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="2.5" width="6" height="11" rx="3"/><path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21M9 21h6"/></svg>',send:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l16-8-6 16-2.6-6.2L4 12Z"/></svg>',stopSquare:'<svg viewBox="0 0 24 24" fill="currentColor"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>',back:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 5.5L8 12l6.5 6.5"/></svg>',phone:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.2 3.5h3l1.5 3.7-2 1.4a11.5 11.5 0 0 0 5.7 5.7l1.4-2 3.7 1.5v3a1.8 1.8 0 0 1-2 1.8A15.6 15.6 0 0 1 4.4 5.5a1.8 1.8 0 0 1 1.8-2z"/></svg>',phoneOff:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.2 3.5h3l1.5 3.7-2 1.4a11.5 11.5 0 0 0 5.7 5.7l1.4-2 3.7 1.5v3a1.8 1.8 0 0 1-2 1.8A15.6 15.6 0 0 1 4.4 5.5a1.8 1.8 0 0 1 1.8-2z"/><path d="M3 21L21 3"/></svg>',bug:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6a4 4 0 0 1 8 0"/><rect x="7" y="7.5" width="10" height="12" rx="5"/><path d="M7 11H3.5M7 15.5H4M17 11h3.5M17 15.5h3M12 8v11.5"/></svg>',check:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.8l4.6 4.4L19 7"/></svg>',retry:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 12a8 8 0 1 1-2.6-5.9M20 4v4.5h-4.5"/></svg>',sun:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4.2"/><path d="M12 2.6v2.2M12 19.2v2.2M2.6 12h2.2M19.2 12h2.2M5.4 5.4l1.6 1.6M17 17l1.6 1.6M18.6 5.4L17 7M7 17l-1.6 1.6"/></svg>',moon:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13.4A8.2 8.2 0 1 1 10.6 4a6.6 6.6 0 0 0 9.4 9.4z"/></svg>',auto:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2.8" y="4.4" width="18.4" height="12.6" rx="2.2"/><path d="M8.6 20.2h6.8"/><path d="M12 4.4v12.6"/><path d="M12 7.2a3.6 3.6 0 0 1 0 7.2z" fill="currentColor" stroke="none"/></svg>',sparkle:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.5c.5 4.6 2.9 7 7.5 7.5v.1c-4.6.5-7 2.9-7.5 7.5h-.1c-.5-4.6-2.9-7-7.5-7.5V10c4.6-.5 7-2.9 7.5-7.5z"/><path d="M18.6 15.2c.2 1.9 1.2 2.9 3.1 3.1v.1c-1.9.2-2.9 1.2-3.1 3.1h-.1c-.2-1.9-1.2-2.9-3.1-3.1v-.1c1.9-.2 2.9-1.2 3.1-3.1z" opacity=".7"/></svg>',chat:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 11.5a7.5 7 0 0 1 7.5-7h1a7.5 7 0 0 1 0 14H9l-4.2 2.6a.5.5 0 0 1-.76-.5l.5-3.1A7 7 0 0 1 4 11.5z"/><path d="M8.5 11.5h.01M12 11.5h.01M15.5 11.5h.01" stroke-width="2.6"/></svg>',chevronDown:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9.5l6 6 6-6"/></svg>',chevronRight:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.5 6l6 6-6 6"/></svg>',alert:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7.5v5.2M12 16.3h.01"/></svg>',inbox:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 13.5l2.6-7.2A1.5 1.5 0 0 1 7.5 5.3h9a1.5 1.5 0 0 1 1.4 1L20.5 13.5V18a1.5 1.5 0 0 1-1.5 1.5H5A1.5 1.5 0 0 1 3.5 18z"/><path d="M3.5 13.5h4.8l1.2 2.2h5l1.2-2.2h4.8"/></svg>'},Da='<svg class="bc-brand" viewBox="0 0 254 60" fill="none" role="img" aria-label="sphoro BugCatch"><g fill="currentColor"><path transform="translate(0.00 40.00) scale(0.04000 -0.04000)" d="M276.00 -14.00Q179.00 -14.00 117.00 28.00Q55.00 70.00 42.00 148.00L158.00 178.00Q165.00 143.00 181.50 123.00Q198.00 103.00 222.50 94.50Q247.00 86.00 276.00 86.00Q320.00 86.00 341.00 101.50Q362.00 117.00 362.00 140.00Q362.00 163.00 342.00 175.50Q322.00 188.00 278.00 196.00L250.00 201.00Q198.00 211.00 155.00 228.50Q112.00 246.00 86.00 277.00Q60.00 308.00 60.00 357.00Q60.00 431.00 114.00 470.50Q168.00 510.00 256.00 510.00Q339.00 510.00 394.00 473.00Q449.00 436.00 466.00 376.00L349.00 340.00Q341.00 378.00 316.50 394.00Q292.00 410.00 256.00 410.00Q220.00 410.00 201.00 397.50Q182.00 385.00 182.00 363.00Q182.00 339.00 202.00 327.50Q222.00 316.00 256.00 310.00L284.00 305.00Q340.00 295.00 385.50 278.50Q431.00 262.00 457.50 231.50Q484.00 201.00 484.00 149.00Q484.00 71.00 427.50 28.50Q371.00 -14.00 276.00 -14.00Z"/><path transform="translate(19.56 40.00) scale(0.04000 -0.04000)" d="M70.00 -200.00V496.00H194.00V436.00H212.00Q229.00 465.00 265.00 487.50Q301.00 510.00 368.00 510.00Q428.00 510.00 479.00 480.50Q530.00 451.00 561.00 394.00Q592.00 337.00 592.00 256.00V240.00Q592.00 159.00 561.00 102.00Q530.00 45.00 479.00 15.50Q428.00 -14.00 368.00 -14.00Q323.00 -14.00 292.50 -3.50Q262.00 7.00 243.50 23.50Q225.00 40.00 214.00 57.00H196.00V-200.00ZM330.00 96.00Q389.00 96.00 427.50 133.50Q466.00 171.00 466.00 243.00V253.00Q466.00 325.00 427.00 362.50Q388.00 400.00 330.00 400.00Q272.00 400.00 233.00 362.50Q194.00 325.00 194.00 253.00V243.00Q194.00 171.00 233.00 133.50Q272.00 96.00 330.00 96.00Z"/><path transform="translate(43.68 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V700.00H196.00V435.00H214.00Q222.00 451.00 239.00 467.00Q256.00 483.00 284.50 493.50Q313.00 504.00 357.00 504.00Q415.00 504.00 458.50 477.50Q502.00 451.00 526.00 404.50Q550.00 358.00 550.00 296.00V0.00H424.00V286.00Q424.00 342.00 396.50 370.00Q369.00 398.00 318.00 398.00Q260.00 398.00 228.00 359.50Q196.00 321.00 196.00 252.00V0.00Z"/><path transform="translate(66.92 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/><path transform="translate(90.00 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V496.00H194.00V440.00H212.00Q223.00 470.00 248.50 484.00Q274.00 498.00 308.00 498.00H368.00V386.00H306.00Q258.00 386.00 227.00 360.50Q196.00 335.00 196.00 282.00V0.00Z"/><path transform="translate(104.44 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/></g><rect x="139.52" y="16" width="1.6" height="26" rx="0.8" fill="var(--bc-brand-mark, #5647ee)" opacity="0.4"/><g fill="var(--bc-brand-mark, #5647ee)"><path transform="translate(154.52 35.00) scale(0.01400 -0.01400)" d="M46.35 0.00V105.85H139.75V594.15H46.35V700.00H404.08Q467.38 700.00 514.79 678.41Q562.20 656.83 588.70 617.33Q615.20 577.83 615.20 523.35V513.70Q615.20 465.52 597.03 434.76Q578.85 404.00 553.91 387.24Q528.98 370.48 506.28 363.30V346.35Q528.98 340.35 555.24 323.50Q581.50 306.65 600.00 275.48Q618.50 244.30 618.50 194.48V184.48Q618.50 126.65 591.41 85.24Q564.33 43.83 516.83 21.91Q469.33 0.00 406.85 0.00ZM259.85 109.15H392.60Q441.20 109.15 469.80 132.60Q498.40 156.05 498.40 198.55V208.20Q498.40 250.70 470.21 274.15Q442.02 297.60 392.60 297.60H259.85ZM259.85 406.75H391.65Q437.55 406.75 466.32 430.11Q495.10 453.48 495.10 493.80V503.80Q495.10 544.95 466.74 567.90Q438.37 590.85 391.65 590.85H259.85Z"/><path transform="translate(167.00 35.00) scale(0.01400 -0.01400)" d="M335.30 -14.00Q251.22 -14.00 190.60 16.63Q129.97 47.25 97.56 104.96Q65.15 162.68 65.15 243.03V700.00H185.25V239.73Q185.25 170.48 224.03 131.99Q262.80 93.50 335.30 93.50Q407.80 93.50 446.57 131.99Q485.35 170.48 485.35 239.73V700.00H605.45V243.03Q605.45 162.68 573.13 104.96Q540.80 47.25 480.09 16.63Q419.38 -14.00 335.30 -14.00Z"/><path transform="translate(179.60 35.00) scale(0.01400 -0.01400)" d="M311.85 -14.00Q238.45 -14.00 179.69 18.50Q120.92 51.00 86.69 113.67Q52.45 176.35 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.23 645.59Q598.33 577.17 598.33 460.87V456.70H479.87V464.52Q479.87 504.67 463.76 536.86Q447.65 569.05 414.99 587.77Q382.32 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 138.89Q257.63 91.85 334.00 91.85Q410.02 91.85 445.12 132.83Q480.22 173.80 480.22 237.92V249.67H302.85V351.88H598.33V0.00H487.52V69.10H470.57Q462.70 50.87 446.06 31.44Q429.42 12.00 397.64 -1.00Q365.85 -14.00 311.85 -14.00Z"/><path transform="translate(192.05 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(204.25 35.00) scale(0.01400 -0.01400)" d="M19.75 0.00 211.62 700.00H421.33L613.20 0.00H489.27L447.42 159.60H185.53L143.68 0.00ZM214.25 270.40H418.70L324.95 624.87H308.00Z"/><path transform="translate(216.31 35.00) scale(0.01400 -0.01400)" d="M233.95 0.00V590.85H24.70V700.00H563.30V590.85H354.05V0.00Z"/><path transform="translate(227.75 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(239.95 35.00) scale(0.01400 -0.01400)" d="M69.50 0.00V700.00H189.60V405.58H466.40V700.00H586.50V0.00H466.40V296.42H189.60V0.00Z"/></g></svg>',jn=[{value:"light",label:"Light",icon:B.sun},{value:"dark",label:"Dark",icon:B.moon},{value:"auto",label:"System default",icon:B.auto}],Rn="bugcatch:theme";function Na(){try{const t=localStorage.getItem(Rn);return jn.some(e=>e.value===t)?t:null}catch{return null}}function Ua(t){try{localStorage.setItem(Rn,t)}catch{}}const Ka=t=>`
|
|
8
8
|
:host { all: initial; }
|
|
9
9
|
:host {
|
|
10
10
|
--bc-accent: ${t};
|
|
@@ -407,6 +407,14 @@ textarea { min-height: 88px; resize: vertical; }
|
|
|
407
407
|
.refs .err { color: var(--bc-danger); font-weight: 550; }
|
|
408
408
|
.refs .link { margin-top: 10px; font-size: 12px; color: var(--bc-muted); }
|
|
409
409
|
.refs .link:hover { color: var(--bc-fg); }
|
|
410
|
+
.refs .chips.cands button { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-weight: 550; }
|
|
411
|
+
/* "We read your ID" — under the description, while they type. */
|
|
412
|
+
.ref-found {
|
|
413
|
+
display: flex; align-items: center; gap: 6px;
|
|
414
|
+
margin: -6px 0 14px; font-size: 12px; line-height: 1.45; color: var(--bc-muted);
|
|
415
|
+
}
|
|
416
|
+
.ref-found svg { width: 14px; height: 14px; flex: none; color: var(--bc-ok); }
|
|
417
|
+
.ref-found b { font-weight: 600; color: var(--bc-fg); }
|
|
410
418
|
|
|
411
419
|
/* ---------- severity ---------- */
|
|
412
420
|
.seg { display: grid; grid-template-columns: repeat(4, 1fr); gap: 3px; padding: 3px; background: var(--bc-subtle); border: 1px solid var(--bc-border); border-radius: var(--bc-r-md); }
|
|
@@ -760,6 +768,10 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
760
768
|
background: var(--bc-accent-soft); border-color: var(--bc-accent-line);
|
|
761
769
|
}
|
|
762
770
|
.assistant.resolved { background: color-mix(in srgb, var(--bc-ok) 9%, var(--bc-bg)); border-color: color-mix(in srgb, var(--bc-ok) 35%, var(--bc-border)); }
|
|
771
|
+
/* On a call: the call's own card is what they are watching. This one states
|
|
772
|
+
what is happening and stops moving — no spinner, no travelling bar. */
|
|
773
|
+
.assistant.calling { background: var(--bc-bg); }
|
|
774
|
+
.assistant.calling .as-progress i { transition: none; }
|
|
763
775
|
.as-body.entering { animation: bc-rise 360ms var(--bc-ease) both; }
|
|
764
776
|
.as-top { display: flex; gap: 11px; align-items: center; }
|
|
765
777
|
.as-orb {
|
|
@@ -953,6 +965,7 @@ button.quiet:hover { color: var(--bc-accent); }
|
|
|
953
965
|
animation: bc-rise 240ms var(--bc-ease) both;
|
|
954
966
|
}
|
|
955
967
|
.livecall .who { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
968
|
+
.livecall .call-kept { font-size: 11px; opacity: .75; }
|
|
956
969
|
.livecall .secs { font-variant-numeric: tabular-nums; color: var(--bc-muted); }
|
|
957
970
|
.livecall .act {
|
|
958
971
|
padding: 5px 11px; border-radius: 999px; border: 1px solid var(--bc-border);
|
|
@@ -1106,9 +1119,9 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
1106
1119
|
.launcher:hover { transform: none; filter: none; }
|
|
1107
1120
|
.tool:hover:not(:disabled), .themer button:hover { transform: none; }
|
|
1108
1121
|
}
|
|
1109
|
-
`;function
|
|
1122
|
+
`;function Pa(t){const e=document.createElement("div");e.setAttribute("data-bugcatch","widget");let n=Na()||_a(t.config.theme);e.className=zn(n);const o=e.attachShadow({mode:"open"}),i=document.createElement("style");i.textContent=Ka(t.config.accent||"#4F46E5"),o.appendChild(i);const r=An[t.config.widgetPosition]?t.config.widgetPosition:"bottom-right",s=document.createElement("div");s.className=`dock ${r.includes("right")?"at-right":"at-left"}`+(r.startsWith("top")?" at-top":""),s.style.cssText=An[r];const l=document.createElement("div");l.className="themer",l.setAttribute("role","group"),l.setAttribute("aria-label","Report widget theme"),l.innerHTML=jn.map(m=>`<button type="button" data-theme="${m.value}" title="${m.label}" aria-label="${m.label}" aria-pressed="${m.value===n}">${m.icon}</button>`).join(""),l.addEventListener("click",m=>{const b=m.target.closest("button[data-theme]");!b||b.dataset.theme===n||(n=b.dataset.theme,e.className=zn(n),Ua(n),l.querySelectorAll("button").forEach(h=>{h.setAttribute("aria-pressed",String(h.dataset.theme===n))}))});const g=document.createElement("button");g.className="launcher",g.type="button",g.innerHTML=`<span class="ico" aria-hidden="true"><span class="when-closed">${B.chat}</span><span class="when-open">${B.chevronDown}</span></span><span>Report a bug</span>`,g.setAttribute("aria-haspopup","dialog"),g.setAttribute("aria-expanded","false");let f=null;return g.addEventListener("click",()=>{if(f){f.close();return}s.classList.add("over"),g.setAttribute("aria-expanded","true"),f=Va({root:o,host:e,dock:s,client:t,onClose:()=>{f=null,s.classList.remove("over"),g.setAttribute("aria-expanded","false")}})}),s.append(l,g),o.appendChild(s),document.body.appendChild(e),t.widgetControls={open:()=>{f||g.click()},close:()=>{f==null||f.close()},isOpen:()=>!!f},()=>{f==null||f.destroy(),e.remove(),t.widgetControls=null}}function _a(t){return t==="dark"||t==="light"?t:"auto"}function zn(t){return t==="dark"?"bc-dark":t==="light"?"bc-light":"bc-auto"}function Va({root:t,host:e,dock:n,client:o,onClose:i}){var yo,wo,vo,xo,ko,So;const r=o.config,s=r.attachments!==!1,l=s&&Wo(),g=s&&Vo(),f=[];let m="MEDIUM",b=null,h=!1;const u=document.createElement("div");u.className=`scrim ${n.classList.contains("at-left")?"at-left":"at-right"} ${n.classList.contains("at-top")?"at-top":"at-bottom"}`,u.style.setProperty("--bc-dock-h",`${Math.round(n.getBoundingClientRect().height)}px`),u.innerHTML=`
|
|
1110
1123
|
<div class="panel" role="dialog" aria-modal="true" aria-labelledby="bc-h">
|
|
1111
|
-
${
|
|
1124
|
+
${qt({id:"bc-h",title:"Tell us what went wrong",sub:"Our assistant starts looking right away. We attach the page details for you."})}
|
|
1112
1125
|
<div class="body">
|
|
1113
1126
|
<div class="slot" role="alert"></div>
|
|
1114
1127
|
<div class="whoami" hidden></div>
|
|
@@ -1132,8 +1145,8 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
1132
1145
|
<div class="field">
|
|
1133
1146
|
<label id="bc-prio-l">How much is it getting in your way?</label>
|
|
1134
1147
|
<div class="seg" role="group" aria-labelledby="bc-prio-l">
|
|
1135
|
-
${
|
|
1136
|
-
<button type="button" data-prio="${
|
|
1148
|
+
${Bn.map(a=>`
|
|
1149
|
+
<button type="button" data-prio="${a.value}" aria-pressed="${a.value===m}">${a.label}</button>
|
|
1137
1150
|
`).join("")}
|
|
1138
1151
|
</div>
|
|
1139
1152
|
</div>
|
|
@@ -1144,12 +1157,12 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
1144
1157
|
<span class="count" aria-live="polite"></span>
|
|
1145
1158
|
</div>
|
|
1146
1159
|
<div class="tools" role="group" aria-labelledby="bc-att-l">
|
|
1147
|
-
${l?`<button class="tool" type="button" data-act="shot">${
|
|
1148
|
-
${
|
|
1149
|
-
<button class="tool" type="button" data-act="file">${
|
|
1160
|
+
${l?`<button class="tool" type="button" data-act="shot">${B.camera}Screenshot</button>`:""}
|
|
1161
|
+
${g?`<button class="tool" type="button" data-act="rec">${B.video}Record screen</button>`:""}
|
|
1162
|
+
<button class="tool" type="button" data-act="file">${B.paperclip}Upload file</button>
|
|
1150
1163
|
</div>
|
|
1151
1164
|
<div class="thumbs"></div>
|
|
1152
|
-
<input type="file" accept="${
|
|
1165
|
+
<input type="file" accept="${ct.join(",")}" multiple hidden />
|
|
1153
1166
|
</div>`:""}
|
|
1154
1167
|
</div>
|
|
1155
1168
|
</div>
|
|
@@ -1161,209 +1174,219 @@ div.done { padding: 44px 26px 44px; text-align: center; animation: bc-fade-in 24
|
|
|
1161
1174
|
most cannot. Drawn here rather than as a second launcher because it
|
|
1162
1175
|
is the same errand as Send report — the difference is only whether
|
|
1163
1176
|
the reporter would rather say it than type it. -->
|
|
1164
|
-
<button class="ghost" type="button" data-act="call" hidden>${
|
|
1165
|
-
<button class="primary" type="button" data-act="send">Send report ${
|
|
1177
|
+
<button class="ghost" type="button" data-act="call" hidden>${B.phone}Talk to the team</button>
|
|
1178
|
+
<button class="primary" type="button" data-act="send">Send report ${B.send}</button>
|
|
1166
1179
|
</div>
|
|
1167
1180
|
<div class="powered">Powered by
|
|
1168
|
-
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${
|
|
1181
|
+
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${Da}</a>
|
|
1169
1182
|
</div>
|
|
1170
|
-
</div>`;const
|
|
1183
|
+
</div>`;const k=a=>u.querySelector(a),R=k("#bc-title"),z=k("#bc-desc"),S=k(".slot"),M=k(".thumbs"),I=u.querySelector("input[type=file]"),A=k('[data-act="send"]'),H=k('[data-act="call"]'),U=k(".note"),T=k(".compose"),Q=k(".whoami"),$=k(".refs"),Y=k(".known"),ze=k('[data-act="history"]'),fe=document.createElement("div");fe.setAttribute("role","status"),fe.className="note",T.prepend(fe);const Oe=ta(r,(yo=Se(r.projectId))==null?void 0:yo.email);let Qe=r.drafts===!1,xt=!1,G=Promise.resolve(),ge;function xe(){if(clearTimeout(ge),!Qe||xt||r.drafts===!1)return G;const a=R.value||z.value||f.length?{title:R.value,description:z.value,priority:m,items:f.map(({blob:c,mime:p,kind:d})=>({blob:c,mime:p,kind:d}))}:null;return G=G.catch(()=>{}).then(()=>pt(Oe,a)).then(()=>{fe.textContent=a?"Draft saved on this device":""}).catch(()=>{fe.textContent="Draft could not be saved. Keep this tab open."}),G}function Ye(){clearTimeout(ge),ge=setTimeout(xe,250)}T.addEventListener("input",Ye),T.addEventListener("change",Ye);const Xe=()=>{xe()};window.addEventListener("pagehide",Xe);function Je(){f.filter(a=>a.status==="failed").forEach(nt)}window.addEventListener("online",Je),r.drafts!==!1&&(T.inert=!0,na(Oe).then(a=>{Be||!a||(fe.innerHTML='<span>You have an unfinished report on this device.</span> <button type="button" data-resume>Resume report</button> <button type="button" data-discard>Discard</button>',fe.querySelector("[data-resume]").onclick=()=>{R.value=a.title||"",z.value=a.description||"",m=Bn.some(c=>c.value===a.priority)?a.priority:"MEDIUM",u.querySelectorAll("[data-prio]").forEach(c=>c.setAttribute("aria-pressed",String(c.dataset.prio===m)));for(const c of(a.items||[]).slice(0,r.maxAttachments??5))y(c);Qe=!0,xe()},fe.querySelector("[data-discard]").onclick=()=>{Qe=!0,xe()})}).catch(()=>{fe.textContent="Draft storage is unavailable. Keep this tab open."}).finally(()=>{T.inert=!1,fe.querySelector("[data-resume]")||(Qe=!0)}));const Ee=document.activeElement,Ze=document.documentElement.style,Ft=Ze.overflow;Ze.overflow="hidden";let Be=!1,je=null;function Ge(){var a;Be||(xe(),Be=!0,clearTimeout(ge),window.removeEventListener("pagehide",Xe),window.removeEventListener("online",Je),b==null||b.cancel(),je==null||je(),f.forEach(c=>c.previewUrl&&URL.revokeObjectURL(c.previewUrl)),Ze.overflow=Ft,document.removeEventListener("keydown",et,!0),u.remove(),(a=t.querySelector(".recbar"))==null||a.remove(),n.hidden=!1,e.style.opacity="",i==null||i())}function be(){var a;if(!Be){u.classList.add("closing"),setTimeout(Ge,160);try{(a=Ee==null?void 0:Ee.focus)==null||a.call(Ee)}catch{}}}function et(a){if(a.key==="Escape"){if(a.stopPropagation(),b){q({keep:!1});return}h||be();return}if(a.key!=="Tab"||b)return;const c=[...u.querySelectorAll("button:not(:disabled), input:not([hidden]), textarea, select, [href]")].filter(x=>x.offsetParent!==null||x===document.activeElement);if(!c.length)return;const p=c[0],d=c[c.length-1],w=u.getRootNode().activeElement;a.shiftKey&&w===p?(a.preventDefault(),d.focus()):!a.shiftKey&&w===d&&(a.preventDefault(),p.focus())}document.addEventListener("keydown",et,!0),u.addEventListener("click",a=>{a.target===u&&!h&&be()}),k('[data-act="close"]').addEventListener("click",be),u.querySelectorAll("[data-prio]").forEach(a=>{a.addEventListener("click",()=>{m=a.dataset.prio,Ye(),u.querySelectorAll("[data-prio]").forEach(c=>{c.setAttribute("aria-pressed",String(c===a))})})});function ee(a,c="err"){S.innerHTML=a?`<div class="msg ${c}">${c==="err"?B.alert:""}<span>${v(a)}</span></div>`:""}const kt=k("#bc-title-err");function St(a){kt.hidden=!a,kt.innerHTML=a?`${B.alert}<span>${v(a)}</span>`:"",R.classList.toggle("invalid",!!a),R.setAttribute("aria-invalid",String(!!a))}R.addEventListener("input",()=>{R.value.trim()&&St("")});function me(){const a=f.some(d=>d.status==="uploading");A.disabled=h||a||f.some(d=>d.status==="failed"),U.textContent=a?"Waiting for the upload to finish…":f.some(d=>d.status==="failed")?"Retry or remove failed attachments before sending.":"";const c=r.maxAttachments??5;u.querySelectorAll(".tool").forEach(d=>{d.disabled=h||f.length>=c});const p=k(".field-head .count");p&&(p.textContent=f.length?`${f.length} of ${c}`:"")}function tt(a){var x;const c=a.el,p=a.kind==="VIDEO"?"Video":"Shot",d=a.kind==="VIDEO"?`<video src="${a.previewUrl}" muted playsinline preload="metadata"></video>`:`<img src="${a.previewUrl}" alt="" />`;let w="";a.status==="uploading"?w=`<div class="veil"><div class="spinner"></div><div class="bar"><i style="width:${Math.round(a.progress*100)}%"></i></div></div>`:a.status==="failed"&&(w=`<div class="veil err"><button type="button" data-act="retry" aria-label="Retry upload">${B.retry}</button>Failed</div>`),c.innerHTML=`
|
|
1171
1184
|
${d}
|
|
1172
|
-
<span class="kind">${
|
|
1173
|
-
<button class="drop" type="button" data-act="drop" aria-label="Remove ${
|
|
1174
|
-
${
|
|
1185
|
+
<span class="kind">${p} · ${Re(a.size)}</span>
|
|
1186
|
+
<button class="drop" type="button" data-act="drop" aria-label="Remove ${p.toLowerCase()}">${B.close}</button>
|
|
1187
|
+
${w}`,c.querySelector('[data-act="drop"]').addEventListener("click",()=>Yt(a)),(x=c.querySelector('[data-act="retry"]'))==null||x.addEventListener("click",()=>nt(a))}function Yt(a){const c=f.indexOf(a);c>=0&&f.splice(c,1),a.previewUrl&&URL.revokeObjectURL(a.previewUrl),a.el.remove(),xe(),me()}async function nt(a){a.status="uploading",a.progress=0,tt(a),me();try{const{storageKey:c,mime:p}=await o.uploadAttachment(a.blob,a.mime,d=>{a.progress=d;const w=a.el.querySelector(".bar i");w&&(w.style.width=`${Math.round(d*100)}%`)});a.storageKey=c,a.mime=p,a.status="ready"}catch(c){a.status="failed",ee(c.message.replace("[BugCatch] ",""))}tt(a),me()}function y({blob:a,mime:c,kind:p}){const d=r.maxAttachmentBytes??26214400;if(a.size>d){ee(`That file is ${Re(a.size)} — the limit is ${Re(d)}.`);return}const w=lt(c||a.type,ct);if(!w){ee("Only PNG, JPEG, WebP, WebM and MP4 files can be attached to a report.");return}const x={blob:a,kind:p,mime:w,size:a.size,previewUrl:URL.createObjectURL(a),status:"uploading",progress:0,storageKey:null,el:document.createElement("div")};x.el.className="thumb",f.push(x),M.appendChild(x.el),ee(""),xe(),nt(x)}async function E(a){e.style.opacity="0",e.style.pointerEvents="none",await new Promise(c=>requestAnimationFrame(()=>requestAnimationFrame(c)));try{return await a()}finally{e.style.opacity="",e.style.pointerEvents=""}}(wo=u.querySelector('[data-act="shot"]'))==null||wo.addEventListener("click",async()=>{try{const a=await E(Fo);y(a)}catch(a){(a==null?void 0:a.name)!=="NotAllowedError"&&ee(`Screenshot failed: ${a.message}`)}}),(vo=u.querySelector('[data-act="file"]'))==null||vo.addEventListener("click",()=>I.click()),I==null||I.addEventListener("change",()=>{const a=(r.maxAttachments??5)-f.length;[...I.files].slice(0,Math.max(a,0)).forEach(c=>{y({blob:c,mime:c.type,kind:c.type.startsWith("video/")?"VIDEO":"SCREENSHOT"})}),I.value=""}),(xo=u.querySelector('[data-act="rec"]'))==null||xo.addEventListener("click",async()=>{const a=r.maxRecordingMs??12e4;let c;try{b=await Yo({maxMs:a,onTick:p=>{c&&(c.querySelector(".time").textContent=dt(p))},onAutoStop:()=>{b&&q({keep:!0})}})}catch(p){(p==null?void 0:p.name)!=="NotAllowedError"&&ee(`Recording failed: ${p.message}`);return}u.style.display="none",n.hidden=!0,c=document.createElement("div"),c.className="recbar",c.innerHTML=`
|
|
1175
1188
|
<span class="dot"></span>
|
|
1176
1189
|
<span class="time">0:00</span>
|
|
1177
|
-
<span class="hint">Recording — up to ${
|
|
1190
|
+
<span class="hint">Recording — up to ${dt(Math.round(a/1e3))}</span>
|
|
1178
1191
|
<button class="stop" type="button">Stop</button>
|
|
1179
|
-
<button class="ghost" type="button">Discard</button>`,c.querySelector(".stop").addEventListener("click",()=>
|
|
1192
|
+
<button class="ghost" type="button">Discard</button>`,c.querySelector(".stop").addEventListener("click",()=>q({keep:!0})),c.querySelector(".ghost").addEventListener("click",()=>q({keep:!1})),t.appendChild(c),c.querySelector(".stop").focus()});async function q({keep:a}){var p;const c=b;if(c){if(b=null,(p=t.querySelector(".recbar"))==null||p.remove(),u.style.display="",n.hidden=!1,!a){c.cancel(),R.focus();return}try{const d=await c.stop();d.blob.size?y(d):ee("That recording came back empty — nothing was captured.")}catch(d){ee(`Recording failed: ${d.message}`)}R.focus()}}let K={policy:"off",fields:[]},_=!1,te=null,se="",ae="",X=[],Xt="ask",eo=!1,He=!1;o.referenceFields().then(a=>{K=a,oo()}).catch(()=>{});function Jt(){return K.policy==="off"||!K.fields.length?{found:[],conflicts:[],loose:[]}:Ha(K.fields,[R.value,z.value])}function to(a=Jt()){return a.found.length>0&&a.conflicts.length===0}function Zt(){return!te||!se.trim()?[]:[{key:te,value:se.trim().slice(0,120)}]}const Ie=document.createElement("p");Ie.className="ref-found",Ie.setAttribute("aria-live","polite"),Ie.hidden=!0,z.closest(".field").after(Ie);let no;function oo(){const a=Jt();if(to(a)){const c=a.found.slice(0,2).map(p=>`${v(p.label)} <b>${v(ro(p.value))}</b>`).join(", ");Ie.innerHTML=`${B.check}<span>Found your ${c} — no need to add it again.</span>`,Ie.hidden=!1,_&&!Zt().length&&(_=!1,Ce())}else Ie.hidden=!0,Ie.innerHTML=""}const ao=()=>{clearTimeout(no),no=setTimeout(oo,250)};R.addEventListener("input",ao),z.addEventListener("input",ao);function ro(a){return a.length>20?`${a.slice(0,8)}…${a.slice(-4)}`:a}function Cr(a){const c=a.trim().toLowerCase();return X.find(p=>p.value.toLowerCase()===c)||null}function io(a){se=a.value,a.kinds.length===1?te=a.kinds[0].key:a.kinds.some(c=>c.key===te)||(te=null),ae="",He=!1}function Ce(){var W,ne;if(!_){$.hidden=!0,$.innerHTML="";return}const a=K.fields.find(C=>C.key===te)||null,c=K.policy!=="required",p=Cr(se),d=p&&p.kinds.length>1?K.fields.filter(C=>p.kinds.some(oe=>oe.key===C.key)):K.fields,w=X.length>1&&X.every(C=>C.kinds.length===1&&C.kinds[0].key===X[0].kinds[0].key),x={confirm:X.length>1?["Which one is this about?","We found more than one ID in your message. Pick the one this problem is about."]:["Is this the right ID?","This could be more than one kind of ID. Tell us which it is."],suggest:["Is this your ID?","We spotted this in your message. Tell us what it is so we can find your record."],ask:c?["One more thing","So we can find your record — this helps us answer faster."]:["We need one detail","We need one of these to look this up."]}[Xt];$.hidden=!1;const D=d.length>6;$.innerHTML=`
|
|
1180
1193
|
<div class="ask-head">
|
|
1181
|
-
<span class="avatar" aria-hidden="true">${
|
|
1194
|
+
<span class="avatar" aria-hidden="true">${B.sparkle}</span>
|
|
1182
1195
|
<div>
|
|
1183
|
-
<strong>${
|
|
1184
|
-
<p class="why">${v(
|
|
1196
|
+
<strong>${v(x[0])}</strong>
|
|
1197
|
+
<p class="why">${v(x[1])}</p>
|
|
1185
1198
|
</div>
|
|
1186
1199
|
</div>
|
|
1187
|
-
${
|
|
1200
|
+
${X.length>1?`
|
|
1201
|
+
<div class="chips cands" role="group" aria-label="IDs found in your message">
|
|
1202
|
+
${X.map((C,oe)=>`
|
|
1203
|
+
<button type="button" data-ref-cand="${oe}" title="${v(C.value)}"
|
|
1204
|
+
aria-pressed="${!!p&&p===C}">${v(ro(C.value))}</button>
|
|
1205
|
+
`).join("")}
|
|
1206
|
+
</div>`:""}
|
|
1207
|
+
${d.length>1&&!D&&!w?`
|
|
1188
1208
|
<div class="chips" role="group" aria-label="Which detail you are giving">
|
|
1189
|
-
${
|
|
1190
|
-
<button type="button" data-ref-kind="${v(C.key)}" aria-pressed="${C.key===
|
|
1209
|
+
${d.map(C=>`
|
|
1210
|
+
<button type="button" data-ref-kind="${v(C.key)}" aria-pressed="${!!a&&C.key===a.key}">${v(C.label)}</button>
|
|
1191
1211
|
`).join("")}
|
|
1192
1212
|
</div>`:""}
|
|
1193
1213
|
<div class="row">
|
|
1194
|
-
${
|
|
1214
|
+
${D?`
|
|
1195
1215
|
<select class="ref-kind" aria-label="Which detail you are giving">
|
|
1196
|
-
${
|
|
1197
|
-
|
|
1216
|
+
${a?"":'<option value="" selected disabled>What is it?</option>'}
|
|
1217
|
+
${d.map(C=>`
|
|
1218
|
+
<option value="${v(C.key)}" ${a&&C.key===a.key?"selected":""}>${v(C.label)}</option>
|
|
1198
1219
|
`).join("")}
|
|
1199
1220
|
</select>`:""}
|
|
1200
|
-
<input class="ref-value${
|
|
1201
|
-
inputmode="${v(
|
|
1202
|
-
value="${v(
|
|
1203
|
-
placeholder="${v(
|
|
1204
|
-
aria-label="${v(
|
|
1221
|
+
<input class="ref-value${ae?" invalid":""}" type="${(a==null?void 0:a.inputMode)==="email"?"email":"text"}"
|
|
1222
|
+
inputmode="${v((a==null?void 0:a.inputMode)==="numeric"||(a==null?void 0:a.inputMode)==="tel"?"numeric":"text")}"
|
|
1223
|
+
value="${v(se)}"
|
|
1224
|
+
placeholder="${v(a?a.placeholder||a.label:"Your ID")}"
|
|
1225
|
+
aria-label="${v(a?a.label:"Your ID")}" ${ae?'aria-invalid="true"':""} />
|
|
1205
1226
|
</div>
|
|
1206
|
-
${
|
|
1207
|
-
${
|
|
1208
|
-
${c?`<button type="button" class="link" data-act="ref-skip"
|
|
1227
|
+
${a!=null&&a.hint?`<p class="hint">${v(a.hint)}</p>`:""}
|
|
1228
|
+
${ae?`<p class="field-err" role="alert">${B.alert}<span>${v(ae)}</span></p>`:""}
|
|
1229
|
+
${c?`<button type="button" class="link" data-act="ref-skip">${Xt==="ask"?"I don't have this — send without it":"Not sure — send as it is"}</button>`:""}`,$.querySelectorAll("[data-ref-cand]").forEach(C=>{C.addEventListener("click",()=>{io(X[Number(C.dataset.refCand)]),Ce()})}),$.querySelectorAll("[data-ref-kind]").forEach(C=>{C.addEventListener("click",()=>{te=C.dataset.refKind,ae="",He=!1,Ce()})});const j=$.querySelector(".ref-value");j.addEventListener("input",()=>{se=j.value,ae="",He=!1}),j.addEventListener("keydown",C=>{C.key==="Enter"&&(C.preventDefault(),A.click())}),(W=$.querySelector(".ref-kind"))==null||W.addEventListener("change",C=>{var oe;te=C.target.value,ae="",Ce(),(oe=$.querySelector(".ref-value"))==null||oe.focus()}),(ne=$.querySelector('[data-act="ref-skip"]'))==null||ne.addEventListener("click",()=>{eo=!0,_=!1,te=null,se="",ae="",He=!1,Ce(),ee("")}),((!a&&se?$.querySelector("[data-ref-kind], .ref-kind"):null)||j).focus()}function Tr(a){if(X=a.conflicts.length?a.conflicts:a.loose.slice(0,4),Xt=a.conflicts.length?"confirm":a.loose.length?"suggest":"ask",_=!0,X.length)if(X.length===1)io(X[0]);else{se="";const[c]=X;te=X.every(d=>d.kinds.length===1&&d.kinds[0].key===c.kinds[0].key)?c.kinds[0].key:null}else te=te||K.fields[0].key;Ce()}function Er(){if(K.policy==="off"||!K.fields.length||Zt().length)return!1;const a=Jt();return to(a)||eo&&K.policy!=="required"?!1:a}A.addEventListener("click",async()=>{const a=R.value;if(!a.trim()){St("Add a few words about what went wrong — a short sentence is plenty."),R.focus();return}if(_&&se.trim()&&!te){ae="Pick what this ID is.",Ce();return}const c=Er();if(c){_?Ce():Tr(c),ee("");return}if(te&&se.trim()){const d=K.fields.find(w=>w.key===te);if(!He&&d&&!Ln(d,se)){ae=`That does not look like a ${d.label.toLowerCase()}. Press Send again to use it anyway.`,He=!0,Ce();return}}h=!0,ee(""),me();const p=A.innerHTML;A.innerHTML='<span class="spinner" aria-hidden="true"></span>Sending…';try{const d=await o.report({title:a,description:z.value,priority:m,references:Zt(),attachments:f.filter(w=>w.status==="ready").map(w=>({type:w.kind,storageKey:w.storageKey,mime:w.mime}))});if(d!=null&&d.cancelled){h=!1,A.innerHTML=p,me();return}xt=!0,clearTimeout(ge),await G,r.drafts!==!1&&await pt(Oe,null).catch(()=>{}),ho(d)}catch(d){h=!1,A.innerHTML=p,ee(d.message.replace("[BugCatch] ","")),me(),ce.mode!=="off"&&nn().catch(()=>{})}}),(ko=u.querySelector('[data-act="history"]'))==null||ko.addEventListener("click",go);let qe=[],$t="",Gt=null,ot=null;function so(){r.knownIssues!==!1&&o.knownIssues().then(a=>{qe=a,at()}).catch(()=>{})}let co=null;function Ir(a){if(r.knownIssues===!1)return;clearTimeout(co),ot==null||ot.abort();const c=(a||"").trim();if(c.length<3){so();return}co=setTimeout(()=>{ot=new AbortController,o.matchKnownIssues(c,{signal:ot.signal}).then(p=>{p.length&&(qe=p,at())}).catch(()=>{})},250)}function at(){if(!qe.length){Y.hidden=!0,Y.innerHTML="";return}Y.hidden=!1,Y.innerHTML=`
|
|
1209
1230
|
<p class="known-h">Already reported</p>
|
|
1210
|
-
${
|
|
1211
|
-
<div class="issue ${
|
|
1231
|
+
${qe.map(a=>`
|
|
1232
|
+
<div class="issue ${a.joined?"is-joined":""}">
|
|
1212
1233
|
<span class="who">
|
|
1213
|
-
<span class="t">${v(
|
|
1214
|
-
<span class="meta">${v(
|
|
1234
|
+
<span class="t">${v(a.title)}</span>
|
|
1235
|
+
<span class="meta">${v(Mr(a))}</span>
|
|
1215
1236
|
</span>
|
|
1216
|
-
<button class="join" type="button" data-join="${v(
|
|
1217
|
-
${
|
|
1237
|
+
<button class="join" type="button" data-join="${v(a.id)}"
|
|
1238
|
+
${a.joined?"disabled":""}>${a.joined?"Following":"Me too"}</button>
|
|
1218
1239
|
</div>
|
|
1219
|
-
${
|
|
1240
|
+
${Gt===a.id?`
|
|
1220
1241
|
<div class="ask">
|
|
1221
1242
|
<input type="email" class="join-email" placeholder="you@example.com"
|
|
1222
1243
|
aria-label="Your email, so we can tell you when this is fixed" />
|
|
1223
|
-
<button class="ghost" type="button" data-join-confirm="${v(
|
|
1244
|
+
<button class="ghost" type="button" data-join-confirm="${v(a.id)}">Follow</button>
|
|
1224
1245
|
</div>`:""}
|
|
1225
1246
|
`).join("")}
|
|
1226
|
-
${
|
|
1247
|
+
${$t?`<p class="err">${v($t)}</p>`:""}`}function Mr(a){const c=a.status==="IN_PROGRESS"?"Being worked on now":"Not fixed yet",p=a.affectedCount===0?"":` · ${a.affectedCount} ${a.affectedCount===1?"person has":"people have"} said this is happening to them`;return`${c} · reported ${mt(a.since)}${p}`}Y.addEventListener("click",async a=>{var x,D,j,V,W;const c=a.target.closest("[data-join]"),p=a.target.closest("[data-join-confirm]");if(!c&&!p)return;const d=(p||c).getAttribute(p?"data-join-confirm":"data-join");$t="";const w=((D=(x=Y.querySelector(".join-email"))==null?void 0:x.value)==null?void 0:D.trim())||((j=o.signedInAs())==null?void 0:j.email)||((V=o.config.user)==null?void 0:V.email);if(!w){Gt=d,at(),(W=Y.querySelector(".join-email"))==null||W.focus();return}try{const ne=await o.meToo(d,{email:w});Gt=null,qe=qe.map(C=>C.id===d?{...C,joined:!0,affectedCount:ne.affectedCount??C.affectedCount}:C),at()}catch(ne){$t=ne.message.replace("[BugCatch] ",""),at()}}),so(),R.addEventListener("input",()=>Ir(R.value));let lo=!1;function uo(){o.callKind().then(a=>{a&&(lo=!0,H.hidden=en())}).catch(()=>{})}uo();let ce={mode:o.lastLoginMode||"off",signedIn:null},le="idle",De=((So=o.config.user)==null?void 0:So.email)||"",Ne="",de=!1,we="";const en=()=>ce.mode==="required"&&!ce.signedIn;function Lr(){const a=en();T.hidden=a,A.hidden=a,ze&&(ze.hidden=a),a?H.hidden=!0:lo&&(H.hidden=!1)}function Ar(){var c;if(ce.mode==="off"){Q.hidden=!0,Q.innerHTML="";return}Q.hidden=!1,Q.classList.toggle("asking",le!=="idle");const a=we?`<div class="after err">${v(we)}</div>`:"";if(le==="idle"){if(ce.signedIn){Q.innerHTML=`<span class="who">Signed in as <strong>${v(ce.signedIn.email)}</strong></span><button type="button" class="link" data-act="signout">Sign out</button>`;return}const p=(c=o.config.user)==null?void 0:c.email;Q.innerHTML=`<span class="who">${ce.mode==="required"?"Sign in to report a bug here.":p?`Reporting as <strong>${v(p)}</strong>.`:"Reporting anonymously — sign in and we can tell you what happens next."}</span><button type="button" class="link" data-act="signin">Sign in</button>`;return}if(le==="email"){Q.innerHTML=`
|
|
1227
1248
|
<p class="why">Sign in with any email address — we'll send you a code.
|
|
1228
|
-
It's how you hear back about this report${
|
|
1249
|
+
It's how you hear back about this report${ce.mode==="required"?", and this project asks for it":""}.</p>
|
|
1229
1250
|
<div class="row">
|
|
1230
|
-
<input type="email" data-fld="email" value="${v(
|
|
1251
|
+
<input type="email" data-fld="email" value="${v(De)}"
|
|
1231
1252
|
placeholder="you@example.com" autocomplete="email" spellcheck="false"
|
|
1232
|
-
aria-label="Your email address" ${
|
|
1233
|
-
<button type="button" class="primary" data-act="code" ${
|
|
1234
|
-
${
|
|
1253
|
+
aria-label="Your email address" ${de?"disabled":""} />
|
|
1254
|
+
<button type="button" class="primary" data-act="code" ${de?"disabled":""}>
|
|
1255
|
+
${de?"Sending…":"Send code"}
|
|
1235
1256
|
</button>
|
|
1236
1257
|
</div>
|
|
1237
|
-
${
|
|
1238
|
-
${
|
|
1239
|
-
<p class="why">We sent a code to <strong>${v(
|
|
1258
|
+
${a}
|
|
1259
|
+
${ce.mode==="optional"?'<div class="after"><button type="button" class="link" data-act="skip">Not now</button></div>':""}`;return}Q.innerHTML=`
|
|
1260
|
+
<p class="why">We sent a code to <strong>${v(De)}</strong>. It expires in ten minutes.</p>
|
|
1240
1261
|
<div class="row">
|
|
1241
|
-
<input type="text" class="code" data-fld="code" value="${v(
|
|
1262
|
+
<input type="text" class="code" data-fld="code" value="${v(Ne)}"
|
|
1242
1263
|
placeholder="123456" inputmode="numeric" autocomplete="one-time-code"
|
|
1243
|
-
maxlength="8" aria-label="The code we emailed you" ${
|
|
1244
|
-
<button type="button" class="primary" data-act="confirm" ${
|
|
1245
|
-
${
|
|
1264
|
+
maxlength="8" aria-label="The code we emailed you" ${de?"disabled":""} />
|
|
1265
|
+
<button type="button" class="primary" data-act="confirm" ${de?"disabled":""}>
|
|
1266
|
+
${de?"Checking…":"Sign in"}
|
|
1246
1267
|
</button>
|
|
1247
1268
|
</div>
|
|
1248
|
-
${
|
|
1269
|
+
${a}
|
|
1249
1270
|
<div class="after">
|
|
1250
|
-
<button type="button" class="link" data-act="resend" ${
|
|
1251
|
-
<button type="button" class="link" data-act="signin-back" ${
|
|
1252
|
-
</div>`}function
|
|
1271
|
+
<button type="button" class="link" data-act="resend" ${de?"disabled":""}>Send it again</button>
|
|
1272
|
+
<button type="button" class="link" data-act="signin-back" ${de?"disabled":""}>Use another address</button>
|
|
1273
|
+
</div>`}function ye({focus:a=!1}={}){var p;if(Ar(),Lr(),!a||de)return;const c=Q.querySelector("[data-fld]");c&&(c.focus(),(p=c.setSelectionRange)==null||p.call(c,c.value.length,c.value.length))}Q.addEventListener("input",a=>{const c=a.target.closest("[data-fld]");c&&(c.dataset.fld==="email"?De=c.value:Ne=c.value)}),Q.addEventListener("keydown",a=>{a.key!=="Enter"||!a.target.closest("[data-fld]")||(a.preventDefault(),le==="email"?tn():po())});async function tn({resent:a=!1}={}){const c=De.trim();if(!c){we="Enter the address to send the code to.",ye({focus:!0});return}de=!0,we="",ye();try{await o.signIn(c),De=c,a||(Ne=""),le="code"}catch(p){we=p.message}finally{de=!1,ye({focus:!0})}}async function po(){const a=Ne.trim();if(!a){we="Enter the code we emailed you.",ye({focus:!0});return}de=!0,we="",ye();try{const c=await o.confirmSignIn(De.trim(),a);ce.signedIn=c,le="idle",Ne="",ee(""),uo()}catch(c){we=c.message}finally{de=!1,ye({focus:le!=="idle"})}}Q.addEventListener("click",async a=>{const c=a.target.closest("button[data-act]");if(!c)return;const p=c.dataset.act;if(p==="signin"){le="email",we="",ye({focus:!0});return}if(p==="skip"){le="idle",we="",ye();return}if(p==="signin-back"){le="email",we="",Ne="",ye({focus:!0});return}if(p==="code"){tn();return}if(p==="resend"){tn({resent:!0});return}if(p==="confirm"){po();return}if(p==="signout"){de=!0,ye();try{await o.signOut()}finally{ce.signedIn=null,de=!1,le=ce.mode==="required"?"email":"idle",ye({focus:le!=="idle"})}}});async function nn({announce:a=!1}={}){const c=await o.loginState();ce={mode:c.mode,signedIn:c.signedIn},o.lastLoginMode=c.mode,en()&&le==="idle"&&(le="email"),ce.signedIn&&(le="idle"),a&&c.signedOutReason&&ee(c.signedOutReason,"info"),ye()}nn({announce:!0}).catch(()=>{}),H.addEventListener("click",async()=>{h=!0,ee(""),me(),H.disabled=!0,H.innerHTML='<span class="spinner"></span>Ringing…';try{const a=await o.startCall();Br(a)}catch(a){h=!1,H.disabled=!1,H.innerHTML=`${B.phone}Talk to the team`,me(),a.filed?ho(a.filed,{callFailed:a.reason||"The call could not be started."}):(ee(a.message.replace("[BugCatch] ","")),ce.mode!=="off"&&nn().catch(()=>{}))}});function Br(a){const c=u.querySelector(".panel"),p=a!=null&&a.bugId?String(a.bugId).slice(0,8):null;c.innerHTML=`
|
|
1253
1274
|
<div class="call">
|
|
1254
1275
|
<div class="call-head">
|
|
1255
1276
|
<span class="call-dot" aria-hidden="true"></span>
|
|
1256
1277
|
<strong class="call-state">Ringing…</strong>
|
|
1257
1278
|
</div>
|
|
1258
1279
|
<p class="call-note">
|
|
1259
|
-
We're ringing the team now. Someone will pick up if they're free — your report${
|
|
1280
|
+
We're ringing the team now. Someone will pick up if they're free — your report${p?` <code>${v(p)}</code>`:""} is already filed either way, so nothing is lost if nobody answers.
|
|
1260
1281
|
</p>
|
|
1261
1282
|
<div class="foot">
|
|
1262
1283
|
<span class="spacer"></span>
|
|
1263
1284
|
<button class="primary" type="button" data-act="hangup">Cancel</button>
|
|
1264
1285
|
</div>
|
|
1265
|
-
</div>`;const d=c.querySelector(".call-state"),
|
|
1286
|
+
</div>`;const d=c.querySelector(".call-state"),w=c.querySelector(".call-dot"),x={ringing:"Ringing the team…",connecting:"Someone answered — connecting…",connected:"Connected",missed:"Nobody was free",ended:"Call ended",failed:"The call dropped"},D=["ended","failed","missed"],j=o.on("call",({state:V})=>{if(d.textContent=x[V]||V,w.classList.toggle("off",D.includes(V)),D.includes(V)&&(c.querySelector('[data-act="hangup"]').textContent="Close",V==="missed")){const W=c.querySelector(".call-note");W&&(W.textContent="Nobody was free to pick up just now. Your report is filed and the team will reply in the chat.")}});c.querySelector('[data-act="hangup"]').addEventListener("click",()=>{j(),o.endCall(),be()})}function ho(a,{callFailed:c=null}={}){if(a!=null&&a.id&&!c){on(a.id,{fresh:!0}).then(p=>{p||fo(a,{callFailed:c})});return}fo(a,{callFailed:c})}function fo(a,{callFailed:c=null}={}){var x;const p=a!=null&&a.id?String(a.id).slice(0,8):null,d=(x=a==null?void 0:a.estimate)!=null&&x.label?String(a.estimate.label):null,w=c?`<p class="eta">${v(c)} Your report is filed, and the team will reply in the chat.</p>`:"";u.querySelector(".panel").innerHTML=`
|
|
1266
1287
|
<div class="done">
|
|
1267
|
-
<div class="tick">${
|
|
1288
|
+
<div class="tick">${B.check}</div>
|
|
1268
1289
|
<h3>Thanks — that's on its way.</h3>
|
|
1269
|
-
<p>${
|
|
1270
|
-
${
|
|
1290
|
+
<p>${p?`Filed as <code>${v(p)}</code>.`:"The team has what they need to reproduce it."}</p>
|
|
1291
|
+
${w}
|
|
1271
1292
|
${d?`<p class="eta">Reports like this usually take <strong>${v(d)}</strong>. We'll let you know when it moves.</p>`:""}
|
|
1272
|
-
</div>`,setTimeout(
|
|
1273
|
-
${
|
|
1274
|
-
<div class="history" aria-busy="true">${
|
|
1275
|
-
<button class="row" type="button" data-report="${v(d.id)}" style="animation-delay:${Math.min(
|
|
1276
|
-
<span class="row-ico" aria-hidden="true">${
|
|
1293
|
+
</div>`,setTimeout(be,w?6e3:d?4e3:2e3)}async function go(){const a=u.querySelector(".panel");clearTimeout(rt),Te=null,a.classList.remove("is-chat"),a.innerHTML=`
|
|
1294
|
+
${qt({title:"Your reports",sub:"Everything you've reported, and where each one got to."})}
|
|
1295
|
+
<div class="history" aria-busy="true">${Xa(3)}</div>`,a.querySelector('[data-act="close"]').addEventListener("click",be);let c=[];try{({reports:c}=await o.myReports())}catch{const d=a.querySelector(".history");d&&(d.innerHTML=Dt("Couldn't load your reports just now.",B.alert));return}const p=a.querySelector(".history");if(p){p.removeAttribute("aria-busy"),p.innerHTML=c.length?c.map((d,w)=>`
|
|
1296
|
+
<button class="row" type="button" data-report="${v(d.id)}" style="animation-delay:${Math.min(w,8)*30}ms">
|
|
1297
|
+
<span class="row-ico" aria-hidden="true">${B.chat}</span>
|
|
1277
1298
|
<span class="who">
|
|
1278
1299
|
<span class="ttl">${v(d.title)}</span>
|
|
1279
|
-
<span class="sub">${v(d.reference)} · ${v(
|
|
1300
|
+
<span class="sub">${v(d.reference)} · ${v(mt(d.createdAt))}</span>
|
|
1280
1301
|
</span>
|
|
1281
|
-
<span class="pill ${v(String(d.status).toLowerCase())}">${v(
|
|
1282
|
-
<span class="chev" aria-hidden="true">${
|
|
1283
|
-
</button>`).join(""):
|
|
1284
|
-
${
|
|
1285
|
-
<div class="history chatting" aria-busy="true"><div class="thread">${
|
|
1302
|
+
<span class="pill ${v(String(d.status).toLowerCase())}">${v(Ut(d.status))}</span>
|
|
1303
|
+
<span class="chev" aria-hidden="true">${B.chevronRight}</span>
|
|
1304
|
+
</button>`).join(""):Dt("You haven't reported anything yet.",B.inbox);for(const d of p.querySelectorAll("[data-report]"))d.addEventListener("click",()=>on(d.dataset.report))}}async function on(a,{fresh:c=!1}={}){var j;const p=u.querySelector(".panel");clearTimeout(rt),p.classList.add("is-chat"),p.innerHTML=`
|
|
1305
|
+
${qt({back:!0,title:c?"Looking into it":"Your report",sub:c?"Our assistant is on it — it may ask you a question here.":"Everything that has happened, and a way to answer."})}
|
|
1306
|
+
<div class="history chatting" aria-busy="true"><div class="thread">${Ja()}</div></div>`,p.querySelector('[data-act="close"]').addEventListener("click",be),p.querySelector('[data-act="back"]').addEventListener("click",go);let d=null;try{d=await o.myReport(a)}catch{d=null}const w=p.querySelector(".history");if(!w||!p.querySelector('[data-act="back"]'))return!1;if(!d)return c?(p.classList.remove("is-chat"),!1):(w.removeAttribute("aria-busy"),w.innerHTML=Dt("Couldn't load that report just now.",B.alert),!1);Te=a,o.markReportRead(a);const x=On(d.timeline);w.classList.add("chatting"),w.removeAttribute("aria-busy"),w.innerHTML=`
|
|
1286
1307
|
<div class="report-head">
|
|
1287
1308
|
<span class="ttl">${v(d.title)}</span>
|
|
1288
1309
|
<span class="sub">${v(d.reference)} · ${v(d.project||"")}</span>
|
|
1289
|
-
<span class="pill ${v(String(d.status).toLowerCase())}">${v(
|
|
1290
|
-
${(
|
|
1310
|
+
<span class="pill ${v(String(d.status).toLowerCase())}">${v(Ut(d.status))}</span>
|
|
1311
|
+
${(j=d.estimate)!=null&&j.label?`<span class="eta-line">Usually takes ${v(String(d.estimate.label))}</span>`:""}
|
|
1291
1312
|
</div>
|
|
1292
|
-
<div class="thread" role="log" aria-live="polite" aria-label="Conversation">${
|
|
1293
|
-
<div class="as-body${
|
|
1313
|
+
<div class="thread" role="log" aria-live="polite" aria-label="Conversation">${x}</div>`;const D=w.querySelector(".thread");return Nt.set(D,x),Ve(D),mo(w,d),d.canReply&&jr(w,D,a),bo(w,d,a),Ve(D),!0}let rt=null;function bo(a,c,p){var F,re,ke;clearTimeout(rt);const d=c.assistant,w=a.querySelector(".thread");let x=a.querySelector(".assistant");if(!d){x==null||x.remove(),(F=w==null?void 0:w.querySelector(".typing-row"))==null||F.remove();return}const D=(x==null?void 0:x.dataset.phase)||null;x||(x=document.createElement("div"),x.setAttribute("role","status"),x.setAttribute("aria-live","polite"),(re=a.querySelector(".report-head"))==null||re.after(x)),x.className=`assistant ${v(d.phase)}`,x.dataset.phase=d.phase;const j=d.steps||[],V=j.filter(ie=>ie.state==="done").length,W=j.some(ie=>ie.state==="active")?.5:0,ne=j.length?Math.round((V+W)/j.length*100):0,C=`
|
|
1314
|
+
<div class="as-body${D&&D!==d.phase?" entering":""}">
|
|
1294
1315
|
<div class="as-top">
|
|
1295
|
-
<span class="as-orb" aria-hidden="true">${d.phase==="analyzing"?'<span class="as-spin"></span>':d.phase==="resolved"?
|
|
1316
|
+
<span class="as-orb" aria-hidden="true">${d.phase==="analyzing"?'<span class="as-spin"></span>':d.phase==="calling"?B.phone:d.phase==="resolved"?B.check:B.sparkle}</span>
|
|
1296
1317
|
<div class="as-text">
|
|
1297
1318
|
<div class="as-title">${v(d.title)}</div>
|
|
1298
1319
|
<div class="as-detail">${v(d.detail)}</div>
|
|
1299
1320
|
</div>
|
|
1300
1321
|
</div>
|
|
1301
1322
|
</div>
|
|
1302
|
-
${
|
|
1303
|
-
<div class="as-progress" role="progressbar" aria-label="Progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${
|
|
1304
|
-
<ol class="as-steps">${
|
|
1323
|
+
${j.length?`
|
|
1324
|
+
<div class="as-progress" role="progressbar" aria-label="Progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${ne}"><i style="width:${ne}%"></i></div>
|
|
1325
|
+
<ol class="as-steps">${j.map(ie=>`<li class="${v(ie.state)}"${ie.state==="active"?' aria-current="step"':""}><span class="dot"></span><span class="lbl">${v(ie.label)}</span></li>`).join("")}</ol>`:""}`,oe=JSON.stringify([d.phase,d.title,d.detail,j]);if(x.dataset.key!==oe){const ie=x.querySelector(".as-progress i"),ue=ie==null?void 0:ie.style.width;x.innerHTML=C,x.dataset.key=oe;const Ue=x.querySelector(".as-progress i");Ue&&ue&&(Ue.style.width=ue,requestAnimationFrame(()=>{Ue.style.width=`${ne}%`}))}if(w){const ie=qn(w),ue=w.querySelector(".typing-row");d.phase!=="analyzing"?ue==null||ue.remove():(!ue||ue!==w.lastElementChild)&&(ue==null||ue.remove(),w.insertAdjacentHTML("beforeend",Ya()),ie&&Ve(w))}d.phase==="analyzing"?rt=setTimeout(()=>it(p),3e3):d.phase==="calling"?rt=setTimeout(()=>it(p),1e4):d.phase==="needs_info"&&D!=="needs_info"&&((ke=a.querySelector(".composer textarea"))==null||ke.focus())}function mo(a,c){var d,w;if((d=a.querySelector(".fix-verification"))==null||d.remove(),!c.resolvedAt||!["RESOLVED","CLOSED"].includes(c.status))return;const p=document.createElement("div");p.className="fix-verification",c.verification?p.textContent=c.verification==="CONFIRMED"?"You confirmed that this fix works.":"Your feedback was recorded.":(p.innerHTML='<p>Does the fix work for you?</p><textarea maxlength="4000" aria-label="Fix feedback" placeholder="What happens when you try again? (optional)"></textarea><button type="button" data-result="CONFIRMED">It works now</button> <button type="button" data-result="STILL_HAPPENING">Still happening</button><p class="feedback-status" role="status"></p>',p.querySelectorAll("[data-result]").forEach(x=>{x.onclick=async()=>{p.querySelectorAll("button").forEach(D=>{D.disabled=!0});try{await o.verifyFix(c.id,{result:x.dataset.result,resolvedAt:c.resolvedAt,note:p.querySelector("textarea").value}),await on(c.id)}catch(D){p.querySelector(".feedback-status").textContent=D.message,p.querySelectorAll("button").forEach(j=>{j.disabled=!1})}}})),(w=a.querySelector(".report-head"))==null||w.after(p)}async function it(a){const c=u.querySelector(".history.chatting"),p=c==null?void 0:c.querySelector(".thread");if(!p||Te!==a)return;let d=null;try{d=await o.myReport(a)}catch{}if(!d||Te!==a)return;mo(c,d);const w=qn(p),x=On(d.timeline);Nt.get(p)!==x&&(p.innerHTML=x,Nt.set(p,x)),bo(c,d,a),w&&Ve(p);const D=c.querySelector(".report-head .pill");D&&(D.className=`pill ${String(d.status).toLowerCase()}`,D.textContent=Ut(d.status))}function jr(a,c,p){var Ue;const d=document.createElement("div");d.className="composer",d.innerHTML=`
|
|
1305
1326
|
<div class="staged" hidden></div>
|
|
1306
1327
|
<div class="row">
|
|
1307
1328
|
<div class="tools">
|
|
1308
|
-
|
|
1309
|
-
<button class="tool" type="button" data-act="
|
|
1310
|
-
<button class="tool" type="button" data-act="
|
|
1329
|
+
${r.attachments===!1?"":`
|
|
1330
|
+
<button class="tool" type="button" data-act="attach" title="Attach a file" aria-label="Attach a file">${B.paperclip}</button>
|
|
1331
|
+
<button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${B.mic}</button>`}
|
|
1332
|
+
<button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${B.phone}</button>
|
|
1311
1333
|
</div>
|
|
1312
1334
|
<textarea rows="1" placeholder="Write a reply…" aria-label="Write a reply"></textarea>
|
|
1313
|
-
<button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${
|
|
1335
|
+
<button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${B.send}</button>
|
|
1314
1336
|
</div>
|
|
1315
1337
|
<div class="note" hidden></div>
|
|
1316
|
-
<input type="file" hidden multiple accept="${
|
|
1317
|
-
<span class="chip ${
|
|
1318
|
-
<span class="nm">${v(
|
|
1319
|
-
<span class="sz">${
|
|
1320
|
-
<button type="button" data-drop="${
|
|
1321
|
-
</span>`).join("");for(const
|
|
1338
|
+
<input type="file" hidden multiple accept="${bn.join(",")}">`,a.appendChild(d);const w=d.querySelector(".staged"),x=d.querySelector("textarea"),D=d.querySelector('[data-act="send"]'),j=d.querySelector('[data-act="voice"]'),V=d.querySelector('[data-act="livecall"]'),W=d.querySelector("input[type=file]"),ne=d.querySelector(".note"),C=[];let oe=null,F=!1;function re(O,P=""){ne.hidden=!O,ne.className=`note ${P}`,ne.textContent=O||""}function ke(){const O=C.filter(P=>P.storageKey);D.disabled=F||!x.value.trim()&&!O.length,w.hidden=!C.length,w.innerHTML=C.map((P,ve)=>`
|
|
1339
|
+
<span class="chip ${P.storageKey?"":"uploading"}">
|
|
1340
|
+
<span class="nm">${v(P.name)}</span>
|
|
1341
|
+
<span class="sz">${P.storageKey?Re(P.size):"sending…"}</span>
|
|
1342
|
+
<button type="button" data-drop="${ve}" aria-label="Remove ${v(P.name)}">${B.close}</button>
|
|
1343
|
+
</span>`).join("");for(const P of w.querySelectorAll("[data-drop]"))P.addEventListener("click",()=>{C.splice(Number(P.dataset.drop),1),ke()})}async function ie(O,P,ve){const J={name:ve,size:O.size,storageKey:null};C.push(J),ke();try{const{storageKey:an,mime:zr}=await o.uploadAttachment(O,P);J.storageKey=an,J.mime=zr}catch(an){C.splice(C.indexOf(J),1),re(an.message||"That file could not be sent.","err")}ke()}x.addEventListener("input",()=>{x.style.height="auto",x.style.height=`${Math.min(x.scrollHeight,120)}px`,ke()}),x.addEventListener("keydown",O=>{O.key==="Enter"&&!O.shiftKey&&!O.isComposing&&(O.preventDefault(),ue())}),(Ue=d.querySelector('[data-act="attach"]'))==null||Ue.addEventListener("click",()=>W.click()),W.addEventListener("change",()=>{re("");for(const O of W.files){if(O.size>o.config.maxAttachmentBytes){re(`${O.name} is larger than ${Re(o.config.maxAttachmentBytes)}.`,"err");continue}ie(O,O.type,O.name)}W.value=""}),j&&!_o()&&(j.disabled=!0,j.title="This browser cannot record audio"),j==null||j.addEventListener("click",async()=>{if(oe){const O=oe;oe=null,j.classList.remove("recording"),j.innerHTML=B.mic,re("");const{blob:P,mime:ve}=await O.stop();P.size&&ie(P,ve,"Voice note");return}try{re(""),oe=await Xo({maxMs:o.config.maxRecordingMs,onTick:O=>re(`Recording — ${dt(O)}. Tap the mic to stop.`),onAutoStop:()=>j.click()}),j.classList.add("recording"),j.innerHTML=B.stopSquare}catch{oe=null,re("The microphone is not available — check the browser permission.","err")}}),o.canCallTeam(p).then(O=>{O&&(V.hidden=!1)}).catch(()=>{}),V.addEventListener("click",async()=>{V.disabled=!0,re("");try{const O=await o.startLiveCall(p);Rr(a,c,O)}catch(O){re(O.message.replace("[BugCatch] ",""),"err")}finally{V.disabled=!1}}),D.addEventListener("click",ue),c.addEventListener("click",O=>{var ve,J;const P=(J=(ve=O.target).closest)==null?void 0:J.call(ve,"[data-quick]");!P||F||(x.value=P.dataset.quick,ue())});async function ue(){var ve;const O=x.value.trim(),P=C.filter(J=>J.storageKey);if(!(F||!O&&!P.length)){F=!0,ke(),re(""),c.insertAdjacentHTML("beforeend",Qn({from:"reporter",body:O,at:new Date().toISOString(),attachments:P.map(J=>({type:"FILE",name:J.name,size:J.size}))},"pending")),Ve(c,{smooth:!0});try{await vn({apiBase:o.config.apiBase,bugId:p,body:O,attachments:P.map(J=>({storageKey:J.storageKey,mime:J.mime,name:J.name,size:J.size}))}),x.value="",x.style.height="auto",C.length=0,await it(p)}catch(J){(ve=c.querySelector(".msg-row.pending"))==null||ve.classList.replace("pending","failed"),re(J.message||"That could not be sent — try again.","err")}finally{F=!1,ke()}}}ke()}function Rr(a,c,p){const d=document.createElement("div");d.className="livecall",d.innerHTML=`
|
|
1322
1344
|
<span class="call-dot" aria-hidden="true"></span>
|
|
1323
1345
|
<span class="who" role="status" aria-live="polite">Calling the team…</span>
|
|
1324
1346
|
<span class="secs" hidden></span>
|
|
1347
|
+
${p!=null&&p.recorded?'<span class="call-kept">This call is recorded.</span>':""}
|
|
1325
1348
|
<button class="act" type="button" data-act="mute" hidden>Mute</button>
|
|
1326
|
-
<button class="act danger" type="button" data-act="hangup">Cancel</button>`,
|
|
1349
|
+
<button class="act danger" type="button" data-act="hangup">Cancel</button>`,a.insertBefore(d,c);const w=d.querySelector(".who"),x=d.querySelector(".secs"),D=d.querySelector(".call-dot"),j=d.querySelector('[data-act="mute"]'),V=d.querySelector('[data-act="hangup"]');let W=null;const ne=()=>{W&&(clearInterval(W),W=null)},C=F=>{ne(),D.classList.add("off"),d.classList.add("over"),w.textContent=F,x.hidden=!0,j.hidden=!0,V.textContent="Dismiss",V.classList.remove("danger")},oe=o.on("call",({state:F})=>{if(F==="ringing"&&(w.textContent="Calling the team…"),F==="connecting"&&(w.textContent="Someone answered — connecting…"),F==="connected"){w.textContent="You're on a call with the team",j.hidden=!1,x.hidden=!1;const re=Date.now();ne(),W=setInterval(()=>{x.textContent=dt(Math.floor((Date.now()-re)/1e3))},1e3),x.textContent="0s"}F==="missed"&&C("Nobody was free. Send a message instead and the team will pick it up."),F==="ended"&&C("Call ended."),F==="failed"&&C("The call dropped.")});j.addEventListener("click",()=>{const F=p.setMuted(!p.isMuted());j.textContent=F?"Unmute":"Mute",w.textContent=F?"You're muted":"You're on a call with the team"}),V.addEventListener("click",()=>{oe(),ne(),o.endCall(),d.remove(),it(Te)})}let Te=null;return je=o.on("update",a=>{!Te||(a==null?void 0:a.bugId)!==Te||(o.markReportRead(Te),it(Te))}),t.appendChild(u),me(),R.focus(),{destroy:Ge,close:be}}function On(t){const e=t||[];if(!e.length)return"";let n=null,o=null;return e.map(i=>{var m,b,h,u;const r=_e(i.at),s=r&&r!==n?`<div class="day-sep" role="separator">${v(Ga(i.at))}</div>`:"";if(s&&(n=r,o=null),!i.from)return o=null,s+Fa(i);const l={from:i.from,author:(m=i.reply)==null?void 0:m.author,automated:(b=i.reply)==null?void 0:b.automated,body:(h=i.reply)==null?void 0:h.body,at:i.at,attachments:(u=i.reply)==null?void 0:u.attachments},g=Wa(l),f=o&&o.who===g&&Math.abs(new Date(i.at).getTime()-new Date(o.at).getTime())<5*6e4;return o={who:g,at:i.at},s+Qn(l,f?"cont":"")}).join("")}function Wa(t){return t.from==="reporter"?"me":t.automated?"assistant":`team:${t.author||""}`}function Fa(t){const e=Hn(t.at);return`
|
|
1327
1350
|
<div class="sys k-${v(t.kind)}">
|
|
1328
1351
|
<span class="dot" aria-hidden="true"></span>${v(t.summary||"")}${e?`
|
|
1329
1352
|
<span class="t">· ${v(e)}</span>`:""}
|
|
1330
|
-
</div>`}function
|
|
1331
|
-
<button type="button" data-quick="Yes, this is the problem">${
|
|
1332
|
-
<button type="button" data-quick="No, that is not the problem">
|
|
1353
|
+
</div>`}function Qn(t,e=""){const n=t.from==="reporter",o=t.body||"",i=t.attachments||[],r=!n&&!!t.automated,s=o?`<span class="msg-text">${v(o)}</span>`:"",l=i.length?`<div class="att">${i.map(er).join("")}</div>`:"";let g="",f="";if(r)g='<span class="msg-who auto">Assistant <span class="tag">AI</span></span>',f=`<span class="av bot" aria-hidden="true">${B.sparkle}</span>`;else if(!n){const b=t.author||"Support team";g=`<span class="msg-who">${v(b)}</span>`,f=`<span class="av" aria-hidden="true">${v(Za(b))}</span>`}e.includes("cont")&&(g="");const m=r&&/it goes to the same person/i.test(o)?`<div class="quick" role="group" aria-label="Answer">
|
|
1354
|
+
<button type="button" data-quick="Yes, this is the problem">${B.check}That's right</button>
|
|
1355
|
+
<button type="button" data-quick="No, that is not the problem">That's not it</button>
|
|
1333
1356
|
</div>`:"";return`
|
|
1334
|
-
<div class="msg-row ${n?"mine":"theirs"} ${
|
|
1335
|
-
${
|
|
1336
|
-
${
|
|
1357
|
+
<div class="msg-row ${n?"mine":"theirs"} ${r?"auto":""} ${e}">
|
|
1358
|
+
${f}
|
|
1359
|
+
${g}
|
|
1337
1360
|
<div class="bubble ${o?"":"silent"}">${s}${l}</div>
|
|
1338
|
-
${
|
|
1339
|
-
<span class="msg-when">${v(
|
|
1340
|
-
</div>`}function
|
|
1361
|
+
${m}
|
|
1362
|
+
<span class="msg-when">${v(Hn(t.at)||mt(t.at))}</span>
|
|
1363
|
+
</div>`}function Ya(){return`
|
|
1341
1364
|
<div class="typing-row">
|
|
1342
|
-
<span class="av bot" aria-hidden="true">${
|
|
1365
|
+
<span class="av bot" aria-hidden="true">${B.sparkle}</span>
|
|
1343
1366
|
<span class="msg-who auto">Assistant <span class="tag">AI</span></span>
|
|
1344
1367
|
<div class="bubble typing" role="img" aria-label="The assistant is working on it"><i></i><i></i><i></i></div>
|
|
1345
|
-
</div>`}function
|
|
1368
|
+
</div>`}function qt({title:t,sub:e,id:n="",back:o=!1}){return`
|
|
1346
1369
|
<div class="head">
|
|
1347
|
-
${o?`<button class="icon-btn back" type="button" data-act="back" aria-label="Back to your reports">${
|
|
1348
|
-
<div class="mark" aria-hidden="true">${
|
|
1370
|
+
${o?`<button class="icon-btn back" type="button" data-act="back" aria-label="Back to your reports">${B.back}</button>`:""}
|
|
1371
|
+
<div class="mark" aria-hidden="true">${B.sparkle}</div>
|
|
1349
1372
|
<div class="titles">
|
|
1350
1373
|
<h2${n?` id="${n}"`:""}>${v(t)}</h2>
|
|
1351
1374
|
<p>${v(e)}</p>
|
|
1352
1375
|
</div>
|
|
1353
|
-
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${
|
|
1354
|
-
</div>`}function
|
|
1376
|
+
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${B.close}</button>
|
|
1377
|
+
</div>`}function Dt(t,e){return`<div class="empty"><span class="empty-ico" aria-hidden="true">${e}</span>${v(t)}</div>`}function Xa(t){return Array.from({length:t},()=>`
|
|
1355
1378
|
<div class="row" aria-hidden="true">
|
|
1356
1379
|
<span class="row-ico"></span>
|
|
1357
1380
|
<span class="who"><span class="skel" style="width:70%"></span><span class="skel" style="width:40%;height:9px"></span></span>
|
|
1358
|
-
</div>`).join("")+'<span class="sr-only">Loading…</span>'}function
|
|
1381
|
+
</div>`).join("")+'<span class="sr-only">Loading…</span>'}function Ja(){return`
|
|
1359
1382
|
<div aria-hidden="true" style="display:flex;flex-direction:column;gap:10px;padding-top:6px">
|
|
1360
1383
|
<span class="skel" style="width:42%;height:34px;border-radius:16px;align-self:center"></span>
|
|
1361
1384
|
<span class="skel" style="width:66%;height:52px;border-radius:18px"></span>
|
|
1362
1385
|
<span class="skel" style="width:48%;height:38px;border-radius:18px;align-self:flex-end"></span>
|
|
1363
1386
|
</div>
|
|
1364
|
-
<span class="sr-only">Loading…</span>`}const
|
|
1387
|
+
<span class="sr-only">Loading…</span>`}const Nt=new WeakMap;function Za(t){const e=String(t).trim().split(/\s+/).filter(Boolean);return e.length?(e[0][0]+(e.length>1?e[e.length-1][0]:"")).toUpperCase():"?"}function _e(t){const e=new Date(t);return Number.isFinite(e.getTime())?`${e.getFullYear()}-${e.getMonth()}-${e.getDate()}`:null}function Ga(t){const e=new Date(t),n=new Date,o=new Date(n.getFullYear(),n.getMonth(),n.getDate()-1);if(_e(e)===_e(n))return"Today";if(_e(e)===_e(o))return"Yesterday";try{return e.toLocaleDateString(void 0,{weekday:"short",day:"numeric",month:"short",...e.getFullYear()!==n.getFullYear()?{year:"numeric"}:{}})}catch{return mt(t)}}function Hn(t){const e=new Date(t);if(!Number.isFinite(e.getTime()))return"";try{return e.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit"})}catch{return""}}function er(t){const e=v(t.name||"attachment");if(!t.url)return`<span class="file"><span class="nm">${e}</span></span>`;const n=v(t.url);return t.type==="SCREENSHOT"?`<a href="${n}" target="_blank" rel="noopener noreferrer"><img src="${n}" alt="${e}" loading="lazy"></a>`:t.type==="AUDIO"?`<audio controls preload="metadata" src="${n}"></audio>`:t.type==="VIDEO"?`<video controls preload="metadata" src="${n}"></video>`:`
|
|
1365
1388
|
<a class="file" href="${n}" target="_blank" rel="noopener noreferrer" download>
|
|
1366
1389
|
<span class="nm">${e}</span>
|
|
1367
|
-
${t.size?`<span class="sz">${v(
|
|
1368
|
-
</a>`}function Cn(t){return t.scrollHeight-t.scrollTop-t.clientHeight<40}function Ne(t,{smooth:e=!1}={}){const n=typeof matchMedia=="function"&&matchMedia("(prefers-reduced-motion: reduce)").matches;e&&!n&&t.scrollTo?t.scrollTo({top:t.scrollHeight,behavior:"smooth"}):t.scrollTop=t.scrollHeight}function zt(t){return{OPEN:"Open",IN_PROGRESS:"In progress",RESOLVED:"Fixed",CLOSED:"Closed"}[t]||String(t||"").toLowerCase()}function lt(t){const e=new Date(t).getTime();if(!Number.isFinite(e))return"";const n=Math.floor((Date.now()-e)/864e5);if(n<=0)return"today";if(n===1)return"yesterday";if(n<30)return`${n} days ago`;const o=Math.floor(n/30);return o===1?"a month ago":`${o} months ago`}function v(t){return String(t).replace(/[&<>"']/g,e=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[e])}const Tn=8e3;function Ra(t=Tn){const e=window.AudioContext||window.webkitAudioContext;try{return new e({sampleRate:t})}catch{return new e}}async function ja(t){if(t.state==="suspended")try{await t.resume()}catch{}}function za(t,e,n){const o=e/n,i=new Float32Array(Math.floor(t.length/o));for(let a=0;a<i.length;a++){const s=Math.floor(a*o),l=Math.min(Math.floor((a+1)*o),t.length);let p=0;for(let h=s;h<l;h++)p+=t[h];i[a]=l>s?p/(l-s):0}return i}const Qa=132,En=32635;function Oa(t){const e=new Uint8Array(t.length);for(let n=0;n<t.length;n++){const o=Math.max(-1,Math.min(1,t[n]));let i=Math.round(o*32767);const a=i<0?128:0;a&&(i=-i),i>En&&(i=En),i+=Qa;let s=7;for(let p=16384;!(i&p)&&s>0;s--,p>>=1);const l=i>>s+3&15;e[n]=~(a|s<<4|l)&255}return e}const Ha=512;function qa(t,e,n,o=Tn){const i=t.createMediaStreamSource(e),a=t.createScriptProcessor(Ha,1,1);a.onaudioprocess=l=>{const p=l.inputBuffer.getChannelData(0),h=t.sampleRate===o?p:za(p,t.sampleRate,o);n(Oa(h))},i.connect(a);const s=t.createGain();return s.gain.value=0,a.connect(s),s.connect(t.destination),{stop(){a.onaudioprocess=null;try{i.disconnect()}catch{}try{a.disconnect()}catch{}try{s.disconnect()}catch{}}}}const Da="voiceai.realtime.v1",Na=[{urls:"stun:stun.l.google.com:19302"}];function Qt(){return navigator.mediaDevices.getUserMedia({audio:{echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,channelCount:1}})}function Ot(){var t;return typeof window<"u"&&typeof window.RTCPeerConnection=="function"&&!!((t=navigator.mediaDevices)!=null&&t.getUserMedia)}async function In({realtimeUrl:t,stream:e,ringsUntil:n,onState:o,onAudioBlocked:i,onMicrophone:a}){const s=(y,k)=>{try{o==null||o(y,k)}catch{}},l=y=>{try{i==null||i(y)}catch{}},p=y=>{try{a==null||a(y)}catch{}};if(!Ot()){const y=new Error("[BugCatch] this browser cannot make live calls.");throw s("failed",{reason:"unsupported"}),y}let h=e;if(!h)try{h=await Qt()}catch(y){throw s("failed",{reason:"microphone",error:String((y==null?void 0:y.name)||y)}),y}let b;try{b=await Ua(t)}catch(y){throw An(h),s("failed",{reason:"connect"}),y}let f=null,m=null,g=!1,T=null,Q=null,V=null,$=!1,L=null,B=null,j=!1;const N=[];let S=!1,U=!1,q=!1,I=null,Z=null,Re=0;const le=2e3,je=5e3,ze=3e4,ft=4,X=(y,k)=>{if(!g){g=!0,T&&(clearTimeout(T),T=null),Fe(),B==null||B(),B=null,Ke(),L==null||L(),L=null;try{f==null||f.close()}catch{}An(h),m&&(m.srcObject=null,m.remove(),m=null);try{b.readyState===WebSocket.OPEN&&b.close(1e3,"call over")}catch{}s(y,k)}},de=y=>{b.readyState===WebSocket.OPEN&&b.send(JSON.stringify(y))},me=async()=>{if(j||V||g||!Q||!Q.audio&&!Q.transcript)return;j=!0;const y=Q.encoding||"mulaw";if(y!=="mulaw"){Mn(`this call is kept as ${y}, which this SDK cannot produce.`);return}const k=Number(Q.sample_rate)||8e3;try{const z=Ra(k);if(await ja(z),g){try{z.close()}catch{}return}const O=qa(z,h,D=>{b.readyState===WebSocket.OPEN&&b.send(D)},k);V={context:z,tap:O}}catch(z){Mn(`could not send the copy this call is keeping: ${String((z==null?void 0:z.message)||z)}`)}};function Ke(){if(j=!1,!V)return;const{context:y,tap:k}=V;V=null;try{k.stop()}catch{}try{y.close()}catch{}}function Pe(){var k;if(!m||g)return;let y;try{y=(k=m.play)==null?void 0:k.call(m)}catch{Ce();return}if(!y||typeof y.then!="function"){_e();return}y.then(_e,Ce)}function _e(){L==null||L(),L=null,$&&($=!1,l(!1))}function Ce(){g||($||($=!0,l(!0)),Ve())}function Ve(){if(L||typeof window>"u"||typeof window.addEventListener!="function")return;const y=()=>Pe(),k=["pointerdown","keydown","touchstart"];for(const z of k)window.addEventListener(z,y,{capture:!0,passive:!0});L=()=>{for(const z of k)try{window.removeEventListener(z,y,{capture:!0})}catch{}}}const Nt=y=>{f=new RTCPeerConnection({iceServers:y!=null&&y.length?y:Na});for(const k of h.getAudioTracks())f.addTrack(k,h);B=J(),f.onicecandidate=k=>{k.candidate&&de({type:"signal",signal:{kind:"candidate",payload:k.candidate.toJSON()}})},f.ontrack=k=>{var O;const[z]=k.streams;z&&(m||(m=document.createElement("audio"),m.autoplay=!0,m.playsInline=!0,(O=m.setAttribute)==null||O.call(m,"playsinline",""),m.style.cssText="position:fixed;width:0;height:0;opacity:0;pointer-events:none",document.body.appendChild(m)),m.srcObject=z,Pe())},f.onconnectionstatechange=Me,f.oniceconnectionstatechange=Me};function Me(){if(!f||g)return;const y=f.connectionState||f.iceConnectionState;if(y==="connected"||y==="completed"){U=!0,Re=0,Fe(),q=!1,s("connected");return}if(y==="disconnected"){if(!U)return;Ae(le);return}if(y==="failed"){if(!U){X("failed",{reason:"ice"});return}Ae(0)}}function Ae(y){g||(q||(q=!0,s("reconnecting"),Z=setTimeout(()=>X("failed",{reason:"network"}),ze)),!I&&(I=setTimeout(ue,y)))}function Fe(){I&&(clearTimeout(I),I=null),Z&&(clearTimeout(Z),Z=null)}async function ue(){if(I=null,g||!f)return;const y=f.connectionState||f.iceConnectionState;if(!(y==="connected"||y==="completed")){if(!S){de({type:"signal",signal:{kind:"restart",payload:{}}}),I=setTimeout(ue,je);return}Re>=ft||(Re+=1,await We(),I=setTimeout(ue,je))}}async function We(){if(!(g||!f))try{const y=await f.createOffer({iceRestart:!0});await f.setLocalDescription(y),de({type:"signal",signal:{kind:"offer",payload:f.localDescription.toJSON()}})}catch{}}function J(){let k=null,z=!1;const O=D=>{if(k&&(clearTimeout(k),k=null),D){if(!z)return;z=!1,p(!0);return}z||(k=setTimeout(()=>{k=null,!g&&(z=!0,p(!1))},600))};for(const D of h.getAudioTracks())D.onmute=()=>O(!1),D.onunmute=()=>O(!0),D.onended=()=>{k&&(clearTimeout(k),k=null),!z&&(z=!0,p(!1))};return()=>{k&&(clearTimeout(k),k=null);for(const D of h.getAudioTracks())D.onmute=null,D.onunmute=null,D.onended=null}}const gt=async()=>{try{const y=await f.createOffer();await f.setLocalDescription(y),de({type:"signal",signal:{kind:"offer",payload:f.localDescription.toJSON()}})}catch{X("failed",{reason:"negotiation"})}},bt=async y=>{try{await f.setRemoteDescription(new RTCSessionDescription(y));const k=await f.createAnswer();await f.setLocalDescription(k),de({type:"signal",signal:{kind:"answer",payload:f.localDescription.toJSON()}}),await pe()}catch{X("failed",{reason:"negotiation"})}},pe=async()=>{for(;N.length;){const y=N.shift();try{await f.addIceCandidate(new RTCIceCandidate(y))}catch{}}};let Ye=Promise.resolve();b.onmessage=y=>{Ye=Ye.then(()=>Ut(y)).catch(()=>{})};const Ut=async y=>{var z,O,D,ye,he;if(typeof y.data!="string")return;let k;try{k=JSON.parse(y.data)}catch{return}switch(k.type){case"session.created":{if(Nt((z=k.data)==null?void 0:z.ice_servers),Q=((O=k.data)==null?void 0:O.capture)||null,(D=k.data)!=null&&D.peer_present){s("connecting"),me();break}s("ringing"),Xe();break}case"peer.joined":{T&&(clearTimeout(T),T=null),s("connecting"),S=!!((ye=k.data)!=null&&ye.should_offer),S&&await gt(),me();break}case"signal":{if(!f)break;const{kind:Le,payload:we}=k.data||{};if(Le==="offer")await bt(we);else if(Le==="answer")try{await f.setRemoteDescription(new RTCSessionDescription(we)),await pe()}catch{X("failed",{reason:"negotiation"})}else if(Le==="candidate")if(f.remoteDescription)try{await f.addIceCandidate(new RTCIceCandidate(we))}catch{}else N.push(we);else Le==="restart"&&S&&await We();break}case"peer.left":X("ended",{reason:"peer_left"});break;case"error":X("failed",{reason:"server",detail:(he=k.error)==null?void 0:he.detail});break;case"session.ended":X("ended",{reason:"server"});break}};b.onclose=()=>X("ended",{reason:"disconnected"}),b.onerror=()=>X("failed",{reason:"socket"});function Xe(){if(!n)return;const y=new Date(n).getTime()-Date.now();Number.isFinite(y)&&(T=setTimeout(()=>X("missed"),Math.max(0,y)))}return{hangUp(){de({type:"session.end"}),X("ended",{reason:"hung_up"})},setMuted(y){for(const k of h.getAudioTracks())k.enabled=!y;return y},isMuted(){return h.getAudioTracks().every(y=>!y.enabled)}}}function Ua(t){return new Promise((e,n)=>{let o;try{o=new WebSocket(t,Da)}catch(i){n(i);return}o.onopen=()=>{o.onopen=null,o.onerror=null,e(o)},o.onerror=()=>{o.onopen=null,o.onerror=null,n(new Error("[BugCatch] could not connect the call."))}})}function Mn(t){try{console.warn(`[BugCatch] ${t}`)}catch{}}function An(t){var e;for(const n of((e=t==null?void 0:t.getTracks)==null?void 0:e.call(t))??[])try{n.stop()}catch{}}const dt={cycleMs:3e3,peak:.045,bursts:[{at:0,seconds:.4,hz:[440,660]},{at:.55,seconds:.4,hz:[440,660]}]};let Ln=!1;if(typeof window<"u"&&window.addEventListener)for(const t of["pointerdown","keydown","touchstart"])window.addEventListener(t,()=>{Ln=!0},{once:!0,capture:!0,passive:!0});function Ka(){var t;try{return!!((t=navigator.userActivation)!=null&&t.hasBeenActive)}catch{return!1}}function Pa(){if(!Ln&&!Ka())return()=>{};const t=typeof window<"u"&&(window.AudioContext||window.webkitAudioContext);if(!t)return()=>{};let e;try{e=new t}catch{return()=>{}}let n=!1,o=null;const i=[],a=({at:p,seconds:h,hz:b})=>{const f=e.currentTime+p,m=e.createGain();m.connect(e.destination),m.gain.setValueAtTime(0,f),m.gain.linearRampToValueAtTime(dt.peak,f+.02),m.gain.setValueAtTime(dt.peak,f+h-.06),m.gain.linearRampToValueAtTime(0,f+h);for(const g of b){const T=e.createOscillator();T.type="sine",T.frequency.value=g,T.connect(m),T.start(f),T.stop(f+h+.02),i.push(T)}},s=()=>{if(!n)try{dt.bursts.forEach(a)}catch{}},l=()=>{n||(s(),o=setInterval(s,dt.cycleMs))};return e.state==="running"?l():e.resume().then(l).catch(()=>{}),()=>{n=!0,o&&clearInterval(o);for(const p of i)try{p.stop()}catch{}try{e.close()}catch{}}}function _a(t){const e=Date.parse(t||"");return Number.isNaN(e)?0:Math.max(0,Math.round((e-Date.now())/1e3))}const Bn=["flex:1","padding:9px 12px","border:0","border-radius:8px","font:600 13px/1.4 inherit","cursor:pointer"].join(";");function Va({call:t,accent:e="#5b6ef5",position:n="bottom-right",onAnswer:o,onDecline:i,onExpire:a}){if(typeof document>"u"||!document.body)return()=>{};const[s,l]=String(n).split("-"),p=document.createElement("div");p.setAttribute("role","alertdialog"),p.setAttribute("aria-live","assertive"),p.setAttribute("aria-label",`${t.from||"Support"} is calling about ${t.reference}`),p.style.cssText=["position:fixed",`${s==="top"?"top":"bottom"}:20px`,`${l==="left"?"left":"right"}:20px`,"z-index:2147483647","width:300px","max-width:calc(100vw - 40px)","padding:14px","border-radius:12px","background:#1b1e26","color:#eceef2",'font:13px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',"box-shadow:0 18px 44px rgba(0,0,0,0.5)",`border:1px solid ${e}`,"opacity:0","transform:translateY(8px)","transition:opacity .2s ease,transform .2s ease"].join(";");const h=document.createElement("div");h.style.cssText="font-weight:600;font-size:14px;margin-bottom:2px",h.textContent=`${t.from||"Support"} is calling`;const b=document.createElement("div");b.style.cssText="color:#a4abba;margin-bottom:10px",b.textContent=t.project?`About your report ${t.reference} · ${t.project}`:`About your report ${t.reference}`;const f=document.createElement("div");f.style.cssText="color:#7d8598;font-size:12px;margin-bottom:10px";const m=document.createElement("button");m.type="button",m.textContent="Answer",m.style.cssText=`${Bn};background:${e};color:#fff`;const g=document.createElement("button");g.type="button",g.textContent="Not now",g.style.cssText=`${Bn};background:#2b2f3a;color:#c8cedb`;const T=document.createElement("div");if(T.style.cssText="display:flex;gap:8px",T.append(m,g),p.append(h,b,f),t.recorded){const j=document.createElement("div");j.style.cssText="color:#7d8598;font-size:12px;margin-bottom:10px",j.textContent="This call will be recorded.",p.append(j)}p.append(T),document.body.appendChild(p);const Q=Pa();let V=!1,$=null;const L=()=>{V||(V=!0,$&&clearInterval($),Q(),p.style.opacity="0",p.style.transform="translateY(8px)",setTimeout(()=>p.remove(),250))},B=()=>{const j=_a(t.ringsUntil);if(f.textContent=j?`Ringing — ${j}s`:"The call has stopped ringing.",!j){L();try{a==null||a()}catch{}}};return B(),$=setInterval(B,1e3),m.addEventListener("click",()=>{L();try{o==null||o()}catch{}}),g.addEventListener("click",()=>{L();try{i==null||i()}catch{}}),requestAnimationFrame(()=>{p.style.opacity="1",p.style.transform="translateY(0)"}),L}const ut=120,Fa=500,pt=30,Wa=1e3,Ht={loanId:["loanId","loanNumber"],applicationId:["applicationId"],customerNumber:["customerNumber","customerId"]},Ya=/[\u0000-\u001f\u007f]/;function Xa(t){if(typeof t=="number")return Number.isFinite(t)?String(t):null;if(typeof t!="string")return null;const e=t.trim();return!e||e.length>ut||Ya.test(e)?null:e}function Se(t){return t===null?"null":Array.isArray(t)?"an array":typeof t=="object"?"an object":`a ${typeof t}`}function qt(t,e,n,o,i){for(const a of n){if(!(a in t)||t[a]===void 0||t[a]===null||t[a]==="")continue;const s=Xa(t[a]);if(s)return s;const l=t[a];i(typeof l=="string"&&l.trim().length>ut?`${o}.${a} is longer than ${ut} characters and was dropped — pass the identifier itself, not a sentence or a URL.`:`${o}.${a} should be a string or number, got ${Se(l)} — it was dropped.`)}return null}function Rn(t){if(t===null||typeof t=="boolean")return{ok:!0,value:t};if(typeof t=="number")return Number.isFinite(t)?{ok:!0,value:t}:{ok:!1};if(typeof t=="string")return{ok:!0,value:t.slice(0,Fa)};if(typeof t=="object")try{const e=JSON.stringify(t);if(e&&e.length<=Wa)return{ok:!0,value:JSON.parse(e)}}catch{}return{ok:!1}}const jn=["email","name","phone"],Ja=new Set(["id","userId",...jn,...Object.values(Ht).flat()]);function zn(t,e=()=>{}){if(t==null)return null;if(typeof t!="object"||Array.isArray(t))return e(`identify() takes an object like { id, email, name } or null, got ${Se(t)} — ignored.`),null;const n={};try{const o=qt(t,"id",["id","userId"],"identify()",e);o&&(n.id=o);for(const a of jn){const s=t[a];if(s==null||s==="")continue;if(a==="phone"&&typeof s=="number"&&Number.isFinite(s)){n.phone=String(s);continue}if(typeof s!="string"){e(`identify().${a} should be a string, got ${Se(s)} — it was dropped.`);continue}const l=s.trim().slice(0,a==="name"?200:ut);l&&(a==="email"&&!l.includes("@")&&e(`identify().email "${l}" does not look like an email address — reports cannot be threaded or followed up without one.`),n[a]=l)}for(const[a,s]of Object.entries(Ht)){const l=qt(t,a,s,"identify()",e);l&&(n[a]=l)}let i=0;for(const[a,s]of Object.entries(t)){if(Ja.has(a)||s===void 0||typeof s=="function")continue;if(i>=pt){e(`identify() was given more than ${pt} extra fields; the rest were dropped.`);break}const l=Rn(s);if(!l.ok){e(`identify().${a} could not be sent (${Se(s)} too large or not serialisable) — dropped.`);continue}n[a]=l.value,i+=1}}catch{}return!n.id&&!n.email&&e("identify() was called without an id or email — reports will not be attributed to anyone, and nothing can be looked up by user."),n}function Qn(t,e,n=()=>{}){if(e===null)return{};const o={...t||{}};if(e===void 0)return o;if(typeof e!="object"||Array.isArray(e))return n(`setContext() takes an object like { loanId, screen } or null, got ${Se(e)} — ignored.`),o;try{const i=new Map;for(const[a,s]of Object.entries(Ht))for(const l of s)i.set(l,a);for(const[a,s]of Object.entries(e)){const l=i.get(a);if(s==null){delete o[l||a];continue}if(l){const h=qt({[a]:s},l,[a],"setContext()",n);h?o[l]=h:delete o[l];continue}if(typeof s=="function")continue;if(!(a in o)&&Object.keys(o).length>=pt){n(`setContext() holds at most ${pt} keys; "${a}" was dropped.`);continue}const p=Rn(s);if(!p.ok){n(`setContext().${a} could not be sent (${Se(s)} too large or not serialisable) — dropped.`);continue}o[a]=p.value}}catch{}return o}const On=["apiBase","apiKey","projectId","consoleLimit","networkLimit","captureConsole","captureNetwork","captureErrors","widget","widgetPosition","theme","accent","attachments","maxAttachments","maxAttachmentBytes","maxRecordingMs","beforeSend","user","context","updates","updateToast","onUpdate","voice","onCallState","onIncomingCall","onReportSubmitted","onAssistantPhase","onError","debug","drafts","knownIssues","release","environment","buildId"],Za=["beforeSend","onUpdate","onCallState","onIncomingCall","onReportSubmitted","onAssistantPhase","onError"];function Ga(t){const e=t.toLowerCase().replace(/[-_]/g,"");return On.find(n=>n.toLowerCase()===e)||null}const Hn=/^(your[_-]|<|xxx|todo|changeme)/i,er=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function tr(t,{pageHost:e=""}={}){const n=[],o=[];if(!t||typeof t!="object")return n.push("init() takes an options object: BugCatch.init({ apiBase, apiKey, projectId })."),{errors:n,warnings:o};const{apiKey:i,projectId:a,apiBase:s}=t;i?typeof i!="string"?n.push(`apiKey must be a string, got ${Se(i)}.`):Hn.test(i)?n.push(`apiKey is still the placeholder "${i}" — paste the key you saved when you created it.`):er.test(i)?o.push("apiKey looks like a project id — did you swap apiKey and projectId?"):i.startsWith("bc_")||o.push('apiKey does not look like a BugCatch key (they start with "bc_live_") — reports will be refused with HTTP 401.'):n.push("apiKey is required — create one under Workspace Settings → API Keys."),a?typeof a!="string"?n.push(`projectId must be a string, got ${Se(a)}.`):Hn.test(a)?n.push(`projectId is still the placeholder "${a}".`):a.startsWith("bc_")?o.push("projectId looks like an API key — did you swap apiKey and projectId?"):/\s/.test(a)&&o.push("projectId contains whitespace — check it was copied cleanly."):n.push("projectId is required — copy it from Project Settings → Web SDK."),s==null?!e||/^(localhost|127\.|0\.0\.0\.0|\[::1\])/.test(e)||o.push("apiBase is not set, so reports go to http://localhost:3000 — set apiBase to your BugCatch API URL."):(typeof s!="string"||!/^https?:\/\//.test(s))&&o.push(`apiBase should be an absolute http(s) URL, got ${JSON.stringify(s)}.`);for(const l of Object.keys(t)){if(On.includes(l))continue;const p=Ga(l);o.push(p?`unknown option "${l}" — did you mean "${p}"?`:`unknown option "${l}" is ignored.`)}for(const l of Za){const p=t[l];p!=null&&typeof p!="function"&&o.push(`${l} should be a function, got ${Se(p)} — it will not be called.`)}return{errors:n,warnings:o}}function nr(t){return typeof t=="string"?t.replace(/\/+$/,""):t}const ht={name:"@sphoro/bugcatch-web-sdk",version:"0.15.0"},Ue={apiBase:"http://localhost:3000",apiKey:null,projectId:null,consoleLimit:100,networkLimit:50,captureConsole:!0,captureNetwork:!0,captureErrors:!0,widget:!0,widgetPosition:"bottom-right",theme:"auto",accent:"#4F46E5",attachments:!0,maxAttachments:5,maxAttachmentBytes:25*1024*1024,maxRecordingMs:12e4,beforeSend:null,user:null,updates:!0,updateToast:!0,onUpdate:null,voice:!0,onCallState:null,onIncomingCall:null,onReportSubmitted:null,onAssistantPhase:null,onError:null,context:null,debug:!1};class qn{constructor(){ao(this,E);this.config={...Ue},this.started=!1,this.teardown=[],this.consoleBuffer=et(Ue.consoleLimit),this.networkBuffer=et(Ue.networkLimit),this.stopWatching=null,this.notifier=null,this.call=null,this.callStarting=!1,this.ringing=null,this.listeners=new Map,this.context={},this.warned=new Set,this.phases=new Map}warn(e){this.warned.has(e)||(this.warned.add(e),console.warn(`[BugCatch] ${e}`))}debugLog(...e){this.config.debug&&console.info("[BugCatch]",...e)}init(e={}){if(this.started)return console.warn("[BugCatch] init() called twice — ignoring the second call."),this;const{errors:n,warnings:o}=tr(e,{pageHost:typeof location<"u"?location.hostname:""});if(n.length)throw new Error(`[BugCatch] ${n[0]}`);for(const a of o)this.warn(a);const i=this.config.user;return this.config={...Ue,...e,apiBase:nr(e.apiBase??Ue.apiBase)},this.config.user=e.user!==void 0?zn(e.user,a=>this.warn(a.replace("identify()","init({ user })"))):i||null,e.context&&this.setContext(e.context),this.consoleBuffer=et(this.config.consoleLimit),this.networkBuffer=et(this.config.networkLimit),this.config.captureConsole&&this.teardown.push(yo(this.consoleBuffer)),this.config.captureNetwork&&this.teardown.push(wo(this.networkBuffer)),this.config.captureErrors&&this.teardown.push(vo(this.consoleBuffer)),this.config.widget&&this.teardown.push(ka(this)),this.config.updates&&ce()&&(this.startWatching(),queueMicrotask(()=>H(this,E,Te).call(this))),this.started=!0,this.debugLog("initialised",{version:ht.version,apiBase:this.config.apiBase,projectId:this.config.projectId,user:this.config.user,context:this.context}),this}startWatching(){if(this.stopWatching)return this;this.stopWatching=ta({apiBase:this.config.apiBase,onUpdate:n=>{if(n!=null&&n.incomingCall){H(this,E,co).call(this,n);return}if(n!=null&&n.callWithdrawn){H(this,E,St).call(this,n.callWithdrawn.callId);return}const o=Po(n);typeof this.config.onUpdate=="function"&&this.config.onUpdate(o),this.emit("update",o),H(this,E,Te).call(this)}}),this.teardown.push(()=>{var n;return(n=this.stopWatching)==null?void 0:n.call(this)}),this.teardown.push(()=>H(this,E,St).call(this));const e=n=>{(n.key===st||n.key===null)&&H(this,E,Te).call(this)};return window.addEventListener("storage",e),this.teardown.push(()=>window.removeEventListener("storage",e)),this}on(e,n){if(typeof n!="function")return()=>{};const o=this.listeners.get(e)||new Set;return o.add(n),this.listeners.set(e,o),()=>this.off(e,n)}off(e,n){var o;return(o=this.listeners.get(e))==null||o.delete(n),this}emit(e,n){for(const o of this.listeners.get(e)||[])try{o(n)}catch(i){console.error(`[BugCatch] a '${e}' listener threw:`,i)}}unreadUpdates(){return qe()}markUpdateRead(e){return _o(e),H(this,E,Te).call(this),this}markReportRead(e){return Vo(e),H(this,E,Te).call(this),this}markUpdatesRead(){return cn(),H(this,E,Te).call(this),this}async verifyFix(e,{result:n,resolvedAt:o,note:i}){const a=n==="STILL_HAPPENING"?await H(this,E,kt).call(this,{}):{};return pa({apiBase:this.config.apiBase,bugId:e,result:n,resolvedAt:o,note:i,metadata:a.metadata,logs:a.logs})}async myReport(e){const n=await Yo({apiBase:this.config.apiBase,bugId:e});return H(this,E,ro).call(this,e,n==null?void 0:n.assistant),n}replyToReport(e,{body:n,attachments:o}={}){return ln({apiBase:this.config.apiBase,bugId:e,body:n,attachments:o})}async canCallNow(){return!!await this.callKind()}async callKind(){return(await this.callKinds()).live?"live":null}async callKinds(){var n;const e={agent:!1,live:!1};return!this.config.voice||!((n=this.config.user)!=null&&n.email)?e:this.kinds!==void 0?this.kinds:(this.kinds=await Xo({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId}),this.kinds)}canCall(e){return this.config.voice?dn({apiBase:this.config.apiBase,bugId:e}):Promise.resolve(!1)}async startCall(e){var n;if(!this.config.voice)throw new Error("[BugCatch] calling is switched off.");if(this.call||this.callStarting)throw new Error("[BugCatch] a call is already running.");this.callStarting=!0;try{if(!await this.callKind())throw new Error((n=this.config.user)!=null&&n.email?"[BugCatch] calling is not available on this project.":"[BugCatch] a call needs to know who is calling — call identify() with an email first.");return await H(this,E,so).call(this,e)}finally{this.callStarting=!1}}startLiveCall(e){return this.startCall(e)}canCallTeam(e){return this.config.voice?dn({apiBase:this.config.apiBase,bugId:e}):Promise.resolve(!1)}endCall(){var e;return(e=this.call)==null||e.hangUp(),this.call=null,this}myReports(){return Wo({apiBase:this.config.apiBase})}hasReports(){return!!ce()}forgetReports(){var e;return(e=this.stopWatching)==null||e.call(this),this.stopWatching=null,this.endCall(),Ie(),H(this,E,Te).call(this),this}identify(e){const n=zn(e,o=>this.warn(o));return e!=null&&!n?this:(this.config.user=n,this.debugLog("identify",n),this)}setContext(e){return this.context=Qn(this.context,e,n=>this.warn(n)),this.debugLog("context",this.context),this}getContext(){return{...this.context}}open(){return this.started?this.widgetControls?(this.widgetControls.open(),this):(this.warn("open() needs the built-in widget; it was turned off with widget: false."),this):(this.warn("open() was called before init() — nothing to open yet."),this)}close(){var e;return(e=this.widgetControls)==null||e.close(),this}isOpen(){var e;return!!((e=this.widgetControls)!=null&&e.isOpen())}async uploadAttachment(e,n,o){if(!this.started)throw new Error("[BugCatch] call init() first.");return Ao({apiBase:this.config.apiBase,apiKey:this.config.apiKey,blob:e,mime:n||(e==null?void 0:e.type),onProgress:o})}async report({title:e,description:n="",priority:o="MEDIUM",metadata:i={},attachments:a=[],references:s=[],context:l=null}={}){var T,Q,V,$,L,B,j,N;if(!this.started)throw new Error("[BugCatch] call init() first.");if(typeof e!="string"||!e.trim())throw new Error("[BugCatch] a title is required.");["LOW","MEDIUM","HIGH","CRITICAL"].includes(String(o).toUpperCase())||(this.warn(`priority "${o}" is not one of LOW, MEDIUM, HIGH, CRITICAL — sent as MEDIUM.`),o="MEDIUM");const p=(a||[]).filter(S=>(S==null?void 0:S.storageKey)&&nt(S.mime,tt)).map(S=>({type:S.type==="VIDEO"?"VIDEO":"SCREENSHOT",storageKey:S.storageKey,mime:nt(S.mime,tt)})),h=(Array.isArray(s)?s:[]).filter(S=>S&&typeof S.key=="string"&&S.key&&(typeof S.value=="string"||typeof S.value=="number")).map(S=>({key:S.key.slice(0,64),value:String(S.value).trim().slice(0,120)})).filter(S=>S.value);Array.isArray(s)&&h.length<s.length&&this.warn("report({ references }) takes [{ key, value }] with string values; malformed entries were dropped.");let b=await H(this,E,kt).call(this,{title:e.trim(),description:typeof n=="string"?n:String(n??""),priority:String(o).toUpperCase(),metadata:i,media:p,references:h,context:l});if(typeof this.config.beforeSend=="function"){const S=this.config.beforeSend(b);if(S===!1)return{cancelled:!0};S&&typeof S=="object"&&(b=S)}this.debugLog("sending report",{title:b.title,user:(T=b.metadata)==null?void 0:T.user,context:(Q=b.metadata)==null?void 0:Q.context,references:b.references,console:(L=($=(V=b.logs)==null?void 0:V.console)==null?void 0:$.entries)==null?void 0:L.length,network:(N=(j=(B=b.logs)==null?void 0:B.network)==null?void 0:j.entries)==null?void 0:N.length});const f=ke(this.config.projectId);let m;try{m=await fetch(`${this.config.apiBase}/ingest/bugs`,{method:"POST",headers:{"Content-Type":"application/json","X-BugCatch-Key":this.config.apiKey,...f!=null&&f.token?{"X-BugCatch-Session":f.token}:{}},body:JSON.stringify(b)})}catch(S){const U=new Error(`[BugCatch] could not reach ${this.config.apiBase} — check apiBase, and that this site's origin is allowed by the API.`);throw U.cause=S,H(this,E,xt).call(this,"report",U),U}if(m.status===401&&f&&It(this.config.projectId),!m.ok){let S="";try{const q=await m.json();S=Array.isArray(q.message)?q.message.join(", "):q.message||""}catch{}m.status===401&&!f&&(S||(S="the apiKey was not accepted")),m.status===403&&(S||(S="the apiKey is not allowed to report to this projectId"));const U=new Error(`[BugCatch] report failed (HTTP ${m.status})${S?": "+S:""}`);throw U.status=m.status,H(this,E,xt).call(this,"report",U),U}const g=await m.json();return H(this,E,Yt).call(this,g,{title:b.title??e.trim(),via:"form"}),g.watchToken&&(At(g.watchToken),this.config.updates&&this.startWatching()),g}loginState(){var e;return Ho({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,token:(e=ke(this.config.projectId))==null?void 0:e.token})}referenceFields(){return this.refFields?this.refFields:(this.refFields=ma({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId}),this.refFields)}signedInAs(){const e=ke(this.config.projectId);return e?{email:e.email,name:e.name}:null}signIn(e,{name:n}={}){var o;return qo({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,email:e,name:n??((o=this.config.user)==null?void 0:o.name)??null})}async confirmSignIn(e,n){var i;const o=await Do({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,email:e,code:n});return(i=this.config.user)!=null&&i.email||(this.config.user={email:o.email,name:o.name||void 0}),this.emit("signin",{email:o.email,name:o.name}),{email:o.email,name:o.name}}async signOut(){var o;const e=ke(this.config.projectId),n=await No({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,token:e==null?void 0:e.token});return e!=null&&e.email&&((o=this.config.user)==null?void 0:o.email)===e.email&&(this.config.user=null),this.emit("signout",{email:(e==null?void 0:e.email)||null}),n}knownIssues(){var e;return ca({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,sessionToken:(e=ke(this.config.projectId))==null?void 0:e.token})}matchKnownIssues(e,{signal:n}={}){var o;return la({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,q:e||"",sessionToken:(o=ke(this.config.projectId))==null?void 0:o.token,signal:n})}async meToo(e,{email:n,name:o}={}){var s,l;const i=ke(this.config.projectId),a=await tn();return da({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,bugId:e,reporterEmail:n||((s=this.config.user)==null?void 0:s.email),reporterName:o||((l=this.config.user)==null?void 0:l.name),metadata:{...a,user:this.config.user||void 0,...Object.keys(this.context).length?{context:this.context}:{},sdk:ht},logs:{console:{entries:this.consoleBuffer.all()},network:{entries:this.networkBuffer.all()}},sessionToken:i==null?void 0:i.token})}snapshot(){return{user:this.config.user||null,context:{...this.context},console:this.consoleBuffer.all(),network:this.networkBuffer.all(),environment:nn()}}clear(){this.consoleBuffer.clear(),this.networkBuffer.clear()}destroy(){this.endCall(),this.teardown.forEach(e=>{try{e()}catch{}}),this.teardown=[],this.notifier=null,this.started=!1}}E=new WeakSet,vt=function(e,n){const o=this.config[e];if(typeof o=="function")try{o(n)}catch(i){console.error(`[BugCatch] your ${e} callback threw:`,i)}},Te=function(){const e=qe();if(this.emit("unread",{count:e.length,updates:e}),!!this.config.updateToast){if(!this.notifier){if(!e.length)return;this.notifier=sa({accent:this.config.accent,position:this.config.widgetPosition,onRead:n=>this.markUpdateRead(n),onReadAll:()=>this.markUpdatesRead(),onCall:this.config.voice?n=>{this.markUpdateRead(n.id),this.startCall(n.bugId)}:null}),this.teardown.push(()=>{var n;return(n=this.notifier)==null?void 0:n.destroy()})}this.notifier.render(e)}},ro=function(e,n){const o=n==null?void 0:n.phase;if(!e||typeof o!="string"||this.phases.get(e)===o)return;this.phases.set(e,o);const i={bugId:e,phase:o,title:n.title??null,detail:n.detail??null};this.debugLog("assistant",i),H(this,E,vt).call(this,"onAssistantPhase",i),this.emit("assistant",i)},Yt=function(e,{title:n,via:o}){if(!(e!=null&&e.id))return;const i={bugId:e.id,title:n??null,via:o,result:e};this.debugLog("report accepted",i),H(this,E,vt).call(this,"onReportSubmitted",i),this.emit("report",i)},xt=function(e,n){H(this,E,vt).call(this,"onError",{action:e,error:n}),this.emit("error",{action:e,error:n})},kt=async function({title:e,description:n="",priority:o="MEDIUM",metadata:i={},media:a=[],references:s=[],context:l=null}){var h,b;const p=l?Qn(this.context,l,f=>this.warn(f.replace("setContext()","report({ context })"))):this.context;return{projectId:this.config.projectId,...e?{title:e}:{},description:n,priority:o,url:window.location.href,reporterEmail:(h=this.config.user)==null?void 0:h.email,reporterName:(b=this.config.user)==null?void 0:b.name,metadata:{...await tn(),release:this.config.release,environment:this.config.environment,buildId:this.config.buildId,...i,user:this.config.user||void 0,...Object.keys(p).length?{context:p}:{},sdk:ht},logs:{console:{entries:this.consoleBuffer.all()},network:{entries:this.networkBuffer.all()}},...a.length?{attachments:a}:{},...s.length?{references:s}:{}}},io=async function(){const e=ke(this.config.projectId);let n;try{n=await Jo({apiBase:this.config.apiBase,apiKey:this.config.apiKey,token:e==null?void 0:e.token,payload:await H(this,E,kt).call(this,{})})}catch(o){throw o.status===401&&e&&It(this.config.projectId),H(this,E,xt).call(this,"call",o),o}return H(this,E,Yt).call(this,n,{title:null,via:"call"}),n.watchToken&&(At(n.watchToken),this.config.updates&&this.startWatching()),n},so=async function(e){if(!Ot())throw new Error("[BugCatch] this browser cannot make live calls.");const n=await Qt();let o,i=null;try{if(e)o=await Zo({apiBase:this.config.apiBase,bugId:e});else if(i=await H(this,E,io).call(this),e=i.id,o=i.live_call,!(o!=null&&o.realtime_url)){const s=new Error(`[BugCatch] the report was filed, but the team could not be rung${i.call_error?`: ${i.call_error}`:"."}`);throw s.filed=i,s.reason=i.call_error||null,s}}catch(s){for(const l of n.getTracks())l.stop();throw s}const a=await In({realtimeUrl:o.realtime_url,stream:n,ringsUntil:o.rings_until,onState:(s,l)=>{(s==="ended"||s==="failed"||s==="missed")&&(this.call=null),s==="missed"&&Go({apiBase:this.config.apiBase,bugId:e,callId:o.call_id}),typeof this.config.onCallState=="function"&&this.config.onCallState(s,{bugId:e,live:!0,...l}),this.emit("call",{bugId:e,live:!0,state:s,...l})}});return this.call=a,Object.assign(a,{bugId:e,callId:o.call_id,live:!0,filed:i})},co=function(e){var i;const n=e.incomingCall;if(!this.config.voice||!Ot()||((i=this.ringing)==null?void 0:i.callId)===n.callId||this.call||this.callStarting)return;H(this,E,St).call(this);const o=Va({call:n,accent:this.config.accent,position:this.config.widgetPosition,onAnswer:()=>{H(this,E,lo).call(this,e.bugId,n)},onDecline:()=>{this.ringing=null,un({apiBase:this.config.apiBase,bugId:e.bugId,callId:n.callId}),this.emit("incoming-call",{bugId:e.bugId,callId:n.callId,state:"declined"})},onExpire:()=>{this.ringing=null,this.emit("incoming-call",{bugId:e.bugId,callId:n.callId,state:"missed"})}});if(this.ringing={callId:n.callId,dismiss:o},typeof this.config.onIncomingCall=="function")try{this.config.onIncomingCall({bugId:e.bugId,...n})}catch{}this.emit("incoming-call",{bugId:e.bugId,callId:n.callId,state:"ringing"})},St=function(e){if(this.ringing&&!(e&&this.ringing.callId!==e)){try{this.ringing.dismiss()}catch{}this.ringing=null}},lo=async function(e,n){if(this.ringing=null,this.call||this.callStarting)return;this.callStarting=!0;let o;try{o=await Qt()}catch(a){this.callStarting=!1,un({apiBase:this.config.apiBase,bugId:e,callId:n.callId}),this.emit("incoming-call",{bugId:e,callId:n.callId,state:"failed",error:a});return}let i;try{i=await ea({apiBase:this.config.apiBase,bugId:e,callId:n.callId})}catch(a){for(const s of o.getTracks())s.stop();this.callStarting=!1,this.emit("incoming-call",{bugId:e,callId:n.callId,state:"missed",error:a});return}try{const a=await In({realtimeUrl:i.realtime_url,stream:o,onState:(s,l)=>{(s==="ended"||s==="failed"||s==="missed")&&(this.call=null),typeof this.config.onCallState=="function"&&this.config.onCallState(s,{bugId:e,live:!0,incoming:!0,...l}),this.emit("call",{bugId:e,live:!0,incoming:!0,state:s,...l})}});this.call=a,this.emit("incoming-call",{bugId:e,callId:n.callId,state:"answered"})}catch(a){for(const s of o.getTracks())s.stop();this.emit("incoming-call",{bugId:e,callId:n.callId,state:"failed",error:a})}finally{this.callStarting=!1}};const Dt=new qn;return Dt.Client=qn,Dt.version=ht.version,Dt});
|
|
1390
|
+
${t.size?`<span class="sz">${v(Re(t.size))}</span>`:""}
|
|
1391
|
+
</a>`}function qn(t){return t.scrollHeight-t.scrollTop-t.clientHeight<40}function Ve(t,{smooth:e=!1}={}){const n=typeof matchMedia=="function"&&matchMedia("(prefers-reduced-motion: reduce)").matches;e&&!n&&t.scrollTo?t.scrollTo({top:t.scrollHeight,behavior:"smooth"}):t.scrollTop=t.scrollHeight}function Ut(t){return{OPEN:"Open",IN_PROGRESS:"In progress",RESOLVED:"Fixed",CLOSED:"Closed"}[t]||String(t||"").toLowerCase()}function mt(t){const e=new Date(t).getTime();if(!Number.isFinite(e))return"";const n=Math.floor((Date.now()-e)/864e5);if(n<=0)return"today";if(n===1)return"yesterday";if(n<30)return`${n} days ago`;const o=Math.floor(n/30);return o===1?"a month ago":`${o} months ago`}function v(t){return String(t).replace(/[&<>"']/g,e=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[e])}const Dn=8e3;function tr(t=Dn){const e=window.AudioContext||window.webkitAudioContext;try{return new e({sampleRate:t})}catch{return new e}}async function nr(t){if(t.state==="suspended")try{await t.resume()}catch{}}function or(t,e,n){const o=e/n,i=new Float32Array(Math.floor(t.length/o));for(let r=0;r<i.length;r++){const s=Math.floor(r*o),l=Math.min(Math.floor((r+1)*o),t.length);let g=0;for(let f=s;f<l;f++)g+=t[f];i[r]=l>s?g/(l-s):0}return i}const ar=132,Nn=32635;function rr(t){const e=new Uint8Array(t.length);for(let n=0;n<t.length;n++){const o=Math.max(-1,Math.min(1,t[n]));let i=Math.round(o*32767);const r=i<0?128:0;r&&(i=-i),i>Nn&&(i=Nn),i+=ar;let s=7;for(let g=16384;!(i&g)&&s>0;s--,g>>=1);const l=i>>s+3&15;e[n]=~(r|s<<4|l)&255}return e}const ir=512;function sr(t,e,n,o=Dn){const i=t.createMediaStreamSource(e),r=t.createScriptProcessor(ir,1,1);r.onaudioprocess=l=>{const g=l.inputBuffer.getChannelData(0),f=t.sampleRate===o?g:or(g,t.sampleRate,o);n(rr(f))},i.connect(r);const s=t.createGain();return s.gain.value=0,r.connect(s),s.connect(t.destination),{stop(){r.onaudioprocess=null;try{i.disconnect()}catch{}try{r.disconnect()}catch{}try{s.disconnect()}catch{}}}}const cr="voiceai.realtime.v1",lr=[{urls:"stun:stun.l.google.com:19302"}];function Kt(){return navigator.mediaDevices.getUserMedia({audio:{echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,channelCount:1}})}function Pt(){var t;return typeof window<"u"&&typeof window.RTCPeerConnection=="function"&&!!((t=navigator.mediaDevices)!=null&&t.getUserMedia)}async function Un({realtimeUrl:t,stream:e,ringsUntil:n,onState:o,onAudioBlocked:i,onMicrophone:r}){const s=(y,E)=>{try{o==null||o(y,E)}catch{}},l=y=>{try{i==null||i(y)}catch{}},g=y=>{try{r==null||r(y)}catch{}};if(!Pt()){const y=new Error("[BugCatch] this browser cannot make live calls.");throw s("failed",{reason:"unsupported"}),y}let f=e;if(!f)try{f=await Kt()}catch(y){throw s("failed",{reason:"microphone",error:String((y==null?void 0:y.name)||y)}),y}let m;try{m=await dr(t)}catch(y){throw Pn(f),s("failed",{reason:"connect"}),y}let b=null,h=null,u=!1,k=null,R=null,z=null,S=!1,M=null,I=null,A=!1;const H=[];let U=!1,T=!1,Q=!1,$=null,Y=null,ze=0;const fe=2e3,Oe=5e3,Qe=3e4,xt=4,G=(y,E)=>{if(!u){u=!0,k&&(clearTimeout(k),k=null),Ge(),I==null||I(),I=null,Ye(),M==null||M(),M=null;try{b==null||b.close()}catch{}Pn(f),h&&(h.srcObject=null,h.remove(),h=null);try{m.readyState===WebSocket.OPEN&&m.close(1e3,"call over")}catch{}s(y,E)}},ge=y=>{m.readyState===WebSocket.OPEN&&m.send(JSON.stringify(y))},xe=async()=>{if(A||z||u||!R||!R.audio&&!R.transcript)return;A=!0;const y=R.encoding||"mulaw";if(y!=="mulaw"){Kn(`this call is kept as ${y}, which this SDK cannot produce.`);return}const E=Number(R.sample_rate)||8e3;try{const q=tr(E);if(await nr(q),u){try{q.close()}catch{}return}const K=sr(q,f,_=>{m.readyState===WebSocket.OPEN&&m.send(_)},E);z={context:q,tap:K}}catch(q){Kn(`could not send the copy this call is keeping: ${String((q==null?void 0:q.message)||q)}`)}};function Ye(){if(A=!1,!z)return;const{context:y,tap:E}=z;z=null;try{E.stop()}catch{}try{y.close()}catch{}}function Xe(){var E;if(!h||u)return;let y;try{y=(E=h.play)==null?void 0:E.call(h)}catch{Ee();return}if(!y||typeof y.then!="function"){Je();return}y.then(Je,Ee)}function Je(){M==null||M(),M=null,S&&(S=!1,l(!1))}function Ee(){u||(S||(S=!0,l(!0)),Ze())}function Ze(){if(M||typeof window>"u"||typeof window.addEventListener!="function")return;const y=()=>Xe(),E=["pointerdown","keydown","touchstart"];for(const q of E)window.addEventListener(q,y,{capture:!0,passive:!0});M=()=>{for(const q of E)try{window.removeEventListener(q,y,{capture:!0})}catch{}}}const Ft=y=>{b=new RTCPeerConnection({iceServers:y!=null&&y.length?y:lr});for(const E of f.getAudioTracks())b.addTrack(E,f);I=ee(),b.onicecandidate=E=>{E.candidate&&ge({type:"signal",signal:{kind:"candidate",payload:E.candidate.toJSON()}})},b.ontrack=E=>{var K;const[q]=E.streams;q&&(h||(h=document.createElement("audio"),h.autoplay=!0,h.playsInline=!0,(K=h.setAttribute)==null||K.call(h,"playsinline",""),h.style.cssText="position:fixed;width:0;height:0;opacity:0;pointer-events:none",document.body.appendChild(h)),h.srcObject=q,Xe())},b.onconnectionstatechange=Be,b.oniceconnectionstatechange=Be};function Be(){if(!b||u)return;const y=b.connectionState||b.iceConnectionState;if(y==="connected"||y==="completed"){T=!0,ze=0,Ge(),Q=!1,s("connected");return}if(y==="disconnected"){if(!T)return;je(fe);return}if(y==="failed"){if(!T){G("failed",{reason:"ice"});return}je(0)}}function je(y){u||(Q||(Q=!0,s("reconnecting"),Y=setTimeout(()=>G("failed",{reason:"network"}),Qe)),!$&&($=setTimeout(be,y)))}function Ge(){$&&(clearTimeout($),$=null),Y&&(clearTimeout(Y),Y=null)}async function be(){if($=null,u||!b)return;const y=b.connectionState||b.iceConnectionState;if(!(y==="connected"||y==="completed")){if(!U){ge({type:"signal",signal:{kind:"restart",payload:{}}}),$=setTimeout(be,Oe);return}ze>=xt||(ze+=1,await et(),$=setTimeout(be,Oe))}}async function et(){if(!(u||!b))try{const y=await b.createOffer({iceRestart:!0});await b.setLocalDescription(y),ge({type:"signal",signal:{kind:"offer",payload:b.localDescription.toJSON()}})}catch{}}function ee(){let E=null,q=!1;const K=_=>{if(E&&(clearTimeout(E),E=null),_){if(!q)return;q=!1,g(!0);return}q||(E=setTimeout(()=>{E=null,!u&&(q=!0,g(!1))},600))};for(const _ of f.getAudioTracks())_.onmute=()=>K(!1),_.onunmute=()=>K(!0),_.onended=()=>{E&&(clearTimeout(E),E=null),!q&&(q=!0,g(!1))};return()=>{E&&(clearTimeout(E),E=null);for(const _ of f.getAudioTracks())_.onmute=null,_.onunmute=null,_.onended=null}}const kt=async()=>{try{const y=await b.createOffer();await b.setLocalDescription(y),ge({type:"signal",signal:{kind:"offer",payload:b.localDescription.toJSON()}})}catch{G("failed",{reason:"negotiation"})}},St=async y=>{try{await b.setRemoteDescription(new RTCSessionDescription(y));const E=await b.createAnswer();await b.setLocalDescription(E),ge({type:"signal",signal:{kind:"answer",payload:b.localDescription.toJSON()}}),await me()}catch{G("failed",{reason:"negotiation"})}},me=async()=>{for(;H.length;){const y=H.shift();try{await b.addIceCandidate(new RTCIceCandidate(y))}catch{}}};let tt=Promise.resolve();m.onmessage=y=>{tt=tt.then(()=>Yt(y)).catch(()=>{})};const Yt=async y=>{var q,K,_,te,se;if(typeof y.data!="string")return;let E;try{E=JSON.parse(y.data)}catch{return}switch(E.type){case"session.created":{if(Ft((q=E.data)==null?void 0:q.ice_servers),R=((K=E.data)==null?void 0:K.capture)||null,(_=E.data)!=null&&_.peer_present){s("connecting"),xe();break}s("ringing"),nt();break}case"peer.joined":{k&&(clearTimeout(k),k=null),s("connecting"),U=!!((te=E.data)!=null&&te.should_offer),U&&await kt(),xe();break}case"signal":{if(!b)break;const{kind:ae,payload:X}=E.data||{};if(ae==="offer")await St(X);else if(ae==="answer")try{await b.setRemoteDescription(new RTCSessionDescription(X)),await me()}catch{G("failed",{reason:"negotiation"})}else if(ae==="candidate")if(b.remoteDescription)try{await b.addIceCandidate(new RTCIceCandidate(X))}catch{}else H.push(X);else ae==="restart"&&U&&await et();break}case"peer.left":G("ended",{reason:"peer_left"});break;case"error":G("failed",{reason:"server",detail:(se=E.error)==null?void 0:se.detail});break;case"session.ended":G("ended",{reason:"server"});break}};m.onclose=()=>G("ended",{reason:"disconnected"}),m.onerror=()=>G("failed",{reason:"socket"});function nt(){if(!n)return;const y=new Date(n).getTime()-Date.now();Number.isFinite(y)&&(k=setTimeout(()=>G("missed"),Math.max(0,y)))}return{hangUp(){ge({type:"session.end"}),G("ended",{reason:"hung_up"})},setMuted(y){for(const E of f.getAudioTracks())E.enabled=!y;return y},isMuted(){return f.getAudioTracks().every(y=>!y.enabled)}}}function dr(t){return new Promise((e,n)=>{let o;try{o=new WebSocket(t,cr)}catch(i){n(i);return}o.onopen=()=>{o.onopen=null,o.onerror=null,e(o)},o.onerror=()=>{o.onopen=null,o.onerror=null,n(new Error("[BugCatch] could not connect the call."))}})}function Kn(t){try{console.warn(`[BugCatch] ${t}`)}catch{}}function Pn(t){var e;for(const n of((e=t==null?void 0:t.getTracks)==null?void 0:e.call(t))??[])try{n.stop()}catch{}}const yt={cycleMs:3e3,peak:.045,bursts:[{at:0,seconds:.4,hz:[440,660]},{at:.55,seconds:.4,hz:[440,660]}]};let _n=!1;if(typeof window<"u"&&window.addEventListener)for(const t of["pointerdown","keydown","touchstart"])window.addEventListener(t,()=>{_n=!0},{once:!0,capture:!0,passive:!0});function ur(){var t;try{return!!((t=navigator.userActivation)!=null&&t.hasBeenActive)}catch{return!1}}function pr(){if(!_n&&!ur())return()=>{};const t=typeof window<"u"&&(window.AudioContext||window.webkitAudioContext);if(!t)return()=>{};let e;try{e=new t}catch{return()=>{}}let n=!1,o=null;const i=[],r=({at:g,seconds:f,hz:m})=>{const b=e.currentTime+g,h=e.createGain();h.connect(e.destination),h.gain.setValueAtTime(0,b),h.gain.linearRampToValueAtTime(yt.peak,b+.02),h.gain.setValueAtTime(yt.peak,b+f-.06),h.gain.linearRampToValueAtTime(0,b+f);for(const u of m){const k=e.createOscillator();k.type="sine",k.frequency.value=u,k.connect(h),k.start(b),k.stop(b+f+.02),i.push(k)}},s=()=>{if(!n)try{yt.bursts.forEach(r)}catch{}},l=()=>{n||(s(),o=setInterval(s,yt.cycleMs))};return e.state==="running"?l():e.resume().then(l).catch(()=>{}),()=>{n=!0,o&&clearInterval(o);for(const g of i)try{g.stop()}catch{}try{e.close()}catch{}}}function hr(t){const e=Date.parse(t||"");return Number.isNaN(e)?0:Math.max(0,Math.round((e-Date.now())/1e3))}const Vn=["flex:1","padding:9px 12px","border:0","border-radius:8px","font:600 13px/1.4 inherit","cursor:pointer"].join(";");function fr({call:t,accent:e="#5b6ef5",position:n="bottom-right",onAnswer:o,onDecline:i,onExpire:r}){if(typeof document>"u"||!document.body)return()=>{};const[s,l]=String(n).split("-"),g=document.createElement("div");g.setAttribute("role","alertdialog"),g.setAttribute("aria-live","assertive"),g.setAttribute("aria-label",`${t.from||"Support"} is calling about ${t.reference}`),g.style.cssText=["position:fixed",`${s==="top"?"top":"bottom"}:20px`,`${l==="left"?"left":"right"}:20px`,"z-index:2147483647","width:300px","max-width:calc(100vw - 40px)","padding:14px","border-radius:12px","background:#1b1e26","color:#eceef2",'font:13px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',"box-shadow:0 18px 44px rgba(0,0,0,0.5)",`border:1px solid ${e}`,"opacity:0","transform:translateY(8px)","transition:opacity .2s ease,transform .2s ease"].join(";");const f=document.createElement("div");f.style.cssText="font-weight:600;font-size:14px;margin-bottom:2px",f.textContent=`${t.from||"Support"} is calling`;const m=document.createElement("div");m.style.cssText="color:#a4abba;margin-bottom:10px",m.textContent=t.project?`About your report ${t.reference} · ${t.project}`:`About your report ${t.reference}`;const b=document.createElement("div");b.style.cssText="color:#7d8598;font-size:12px;margin-bottom:10px";const h=document.createElement("button");h.type="button",h.textContent="Answer",h.style.cssText=`${Vn};background:${e};color:#fff`;const u=document.createElement("button");u.type="button",u.textContent="Not now",u.style.cssText=`${Vn};background:#2b2f3a;color:#c8cedb`;const k=document.createElement("div");if(k.style.cssText="display:flex;gap:8px",k.append(h,u),g.append(f,m,b),t.recorded){const A=document.createElement("div");A.style.cssText="color:#7d8598;font-size:12px;margin-bottom:10px",A.textContent="This call will be recorded.",g.append(A)}g.append(k),document.body.appendChild(g);const R=pr();let z=!1,S=null;const M=()=>{z||(z=!0,S&&clearInterval(S),R(),g.style.opacity="0",g.style.transform="translateY(8px)",setTimeout(()=>g.remove(),250))},I=()=>{const A=hr(t.ringsUntil);if(b.textContent=A?`Ringing — ${A}s`:"The call has stopped ringing.",!A){M();try{r==null||r()}catch{}}};return I(),S=setInterval(I,1e3),h.addEventListener("click",()=>{M();try{o==null||o()}catch{}}),u.addEventListener("click",()=>{M();try{i==null||i()}catch{}}),requestAnimationFrame(()=>{g.style.opacity="1",g.style.transform="translateY(0)"}),M}const wt=120,gr=500,vt=30,br=1e3,_t={loanId:["loanId","loanNumber"],applicationId:["applicationId"],customerNumber:["customerNumber","customerId"]},mr=/[\u0000-\u001f\u007f]/;function yr(t){if(typeof t=="number")return Number.isFinite(t)?String(t):null;if(typeof t!="string")return null;const e=t.trim();return!e||e.length>wt||mr.test(e)?null:e}function $e(t){return t===null?"null":Array.isArray(t)?"an array":typeof t=="object"?"an object":`a ${typeof t}`}function Vt(t,e,n,o,i){for(const r of n){if(!(r in t)||t[r]===void 0||t[r]===null||t[r]==="")continue;const s=yr(t[r]);if(s)return s;const l=t[r];i(typeof l=="string"&&l.trim().length>wt?`${o}.${r} is longer than ${wt} characters and was dropped — pass the identifier itself, not a sentence or a URL.`:`${o}.${r} should be a string or number, got ${$e(l)} — it was dropped.`)}return null}function Wn(t){if(t===null||typeof t=="boolean")return{ok:!0,value:t};if(typeof t=="number")return Number.isFinite(t)?{ok:!0,value:t}:{ok:!1};if(typeof t=="string")return{ok:!0,value:t.slice(0,gr)};if(typeof t=="object")try{const e=JSON.stringify(t);if(e&&e.length<=br)return{ok:!0,value:JSON.parse(e)}}catch{}return{ok:!1}}const Fn=["email","name","phone"],wr=new Set(["id","userId",...Fn,...Object.values(_t).flat()]);function Yn(t,e=()=>{}){if(t==null)return null;if(typeof t!="object"||Array.isArray(t))return e(`identify() takes an object like { id, email, name } or null, got ${$e(t)} — ignored.`),null;const n={};try{const o=Vt(t,"id",["id","userId"],"identify()",e);o&&(n.id=o);for(const r of Fn){const s=t[r];if(s==null||s==="")continue;if(r==="phone"&&typeof s=="number"&&Number.isFinite(s)){n.phone=String(s);continue}if(typeof s!="string"){e(`identify().${r} should be a string, got ${$e(s)} — it was dropped.`);continue}const l=s.trim().slice(0,r==="name"?200:wt);l&&(r==="email"&&!l.includes("@")&&e(`identify().email "${l}" does not look like an email address — reports cannot be threaded or followed up without one.`),n[r]=l)}for(const[r,s]of Object.entries(_t)){const l=Vt(t,r,s,"identify()",e);l&&(n[r]=l)}let i=0;for(const[r,s]of Object.entries(t)){if(wr.has(r)||s===void 0||typeof s=="function")continue;if(i>=vt){e(`identify() was given more than ${vt} extra fields; the rest were dropped.`);break}const l=Wn(s);if(!l.ok){e(`identify().${r} could not be sent (${$e(s)} too large or not serialisable) — dropped.`);continue}n[r]=l.value,i+=1}}catch{}return!n.id&&!n.email&&e("identify() was called without an id or email — reports will not be attributed to anyone, and nothing can be looked up by user."),n}function Xn(t,e,n=()=>{}){if(e===null)return{};const o={...t||{}};if(e===void 0)return o;if(typeof e!="object"||Array.isArray(e))return n(`setContext() takes an object like { loanId, screen } or null, got ${$e(e)} — ignored.`),o;try{const i=new Map;for(const[r,s]of Object.entries(_t))for(const l of s)i.set(l,r);for(const[r,s]of Object.entries(e)){const l=i.get(r);if(s==null){delete o[l||r];continue}if(l){const f=Vt({[r]:s},l,[r],"setContext()",n);f?o[l]=f:delete o[l];continue}if(typeof s=="function")continue;if(!(r in o)&&Object.keys(o).length>=vt){n(`setContext() holds at most ${vt} keys; "${r}" was dropped.`);continue}const g=Wn(s);if(!g.ok){n(`setContext().${r} could not be sent (${$e(s)} too large or not serialisable) — dropped.`);continue}o[r]=g.value}}catch{}return o}const Jn=["apiBase","apiKey","projectId","consoleLimit","networkLimit","captureConsole","captureNetwork","captureErrors","widget","widgetPosition","theme","accent","attachments","maxAttachments","maxAttachmentBytes","maxRecordingMs","beforeSend","user","context","updates","updateToast","onUpdate","voice","onCallState","onIncomingCall","onReportSubmitted","onAssistantPhase","onError","debug","drafts","knownIssues","release","environment","buildId"],vr=["beforeSend","onUpdate","onCallState","onIncomingCall","onReportSubmitted","onAssistantPhase","onError"];function xr(t){const e=t.toLowerCase().replace(/[-_]/g,"");return Jn.find(n=>n.toLowerCase()===e)||null}const Zn=/^(your[_-]|<|xxx|todo|changeme)/i,kr=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Sr(t,{pageHost:e=""}={}){const n=[],o=[];if(!t||typeof t!="object")return n.push("init() takes an options object: BugCatch.init({ apiBase, apiKey, projectId })."),{errors:n,warnings:o};const{apiKey:i,projectId:r,apiBase:s}=t;i?typeof i!="string"?n.push(`apiKey must be a string, got ${$e(i)}.`):Zn.test(i)?n.push(`apiKey is still the placeholder "${i}" — paste the key you saved when you created it.`):kr.test(i)?o.push("apiKey looks like a project id — did you swap apiKey and projectId?"):i.startsWith("bc_")||o.push('apiKey does not look like a BugCatch key (they start with "bc_live_") — reports will be refused with HTTP 401.'):n.push("apiKey is required — create one under Workspace Settings → API Keys."),r?typeof r!="string"?n.push(`projectId must be a string, got ${$e(r)}.`):Zn.test(r)?n.push(`projectId is still the placeholder "${r}".`):r.startsWith("bc_")?o.push("projectId looks like an API key — did you swap apiKey and projectId?"):/\s/.test(r)&&o.push("projectId contains whitespace — check it was copied cleanly."):n.push("projectId is required — copy it from Project Settings → Web SDK."),s==null?!e||/^(localhost|127\.|0\.0\.0\.0|\[::1\])/.test(e)||o.push("apiBase is not set, so reports go to http://localhost:3000 — set apiBase to your BugCatch API URL."):(typeof s!="string"||!/^https?:\/\//.test(s))&&o.push(`apiBase should be an absolute http(s) URL, got ${JSON.stringify(s)}.`);for(const l of Object.keys(t)){if(Jn.includes(l))continue;const g=xr(l);o.push(g?`unknown option "${l}" — did you mean "${g}"?`:`unknown option "${l}" is ignored.`)}for(const l of vr){const g=t[l];g!=null&&typeof g!="function"&&o.push(`${l} should be a function, got ${$e(g)} — it will not be called.`)}return{errors:n,warnings:o}}function $r(t){return typeof t=="string"?t.replace(/\/+$/,""):t}const We={name:"@sphoro/bugcatch-web-sdk",version:"0.16.0"},Fe={apiBase:"http://localhost:3000",apiKey:null,projectId:null,consoleLimit:100,networkLimit:50,captureConsole:!0,captureNetwork:!0,captureErrors:!0,widget:!0,widgetPosition:"bottom-right",theme:"auto",accent:"#4F46E5",attachments:!0,maxAttachments:5,maxAttachmentBytes:25*1024*1024,maxRecordingMs:12e4,beforeSend:null,user:null,updates:!0,updateToast:!0,onUpdate:null,voice:!0,onCallState:null,onIncomingCall:null,onReportSubmitted:null,onAssistantPhase:null,onError:null,context:null,debug:!1};class Gn{constructor(){Co(this,L);this.config={...Fe},this.started=!1,this.teardown=[],this.consoleBuffer=st(Fe.consoleLimit),this.networkBuffer=st(Fe.networkLimit),this.stopWatching=null,this.notifier=null,this.call=null,this.callStarting=!1,this.ringing=null,this.listeners=new Map,this.context={},this.warned=new Set,this.phases=new Map}warn(e){this.warned.has(e)||(this.warned.add(e),console.warn(`[BugCatch] ${e}`))}debugLog(...e){this.config.debug&&console.info("[BugCatch]",...e)}init(e={}){if(this.started)return console.warn("[BugCatch] init() called twice — ignoring the second call."),this;const{errors:n,warnings:o}=Sr(e,{pageHost:typeof location<"u"?location.hostname:""});if(n.length)throw new Error(`[BugCatch] ${n[0]}`);for(const r of o)this.warn(r);const i=this.config.user;return this.config={...Fe,...e,apiBase:$r(e.apiBase??Fe.apiBase)},this.config.user=e.user!==void 0?Yn(e.user,r=>this.warn(r.replace("identify()","init({ user })"))):i||null,e.context&&this.setContext(e.context),this.consoleBuffer=st(this.config.consoleLimit),this.networkBuffer=st(this.config.networkLimit),this.config.captureConsole&&this.teardown.push(qo(this.consoleBuffer)),this.config.captureNetwork&&this.teardown.push(Do(this.networkBuffer)),this.config.captureErrors&&this.teardown.push(No(this.consoleBuffer)),da(this.config.projectId),this.config.widget&&this.teardown.push(Pa(this)),this.config.updates&&he()&&(this.startWatching(),queueMicrotask(()=>N(this,L,Me).call(this))),this.started=!0,N(this,L,To).call(this),this.debugLog("initialised",{version:We.version,apiBase:this.config.apiBase,projectId:this.config.projectId,user:this.config.user,context:this.context}),this}startWatching(){if(this.stopWatching)return this;this.stopWatching=Sa({apiBase:this.config.apiBase,onUpdate:n=>{if(n!=null&&n.incomingCall){N(this,L,Lo).call(this,n);return}if(n!=null&&n.callWithdrawn){N(this,L,It).call(this,n.callWithdrawn.callId);return}const o=pa(n);typeof this.config.onUpdate=="function"&&this.config.onUpdate(o),this.emit("update",o),N(this,L,Me).call(this)}}),this.teardown.push(()=>{var n;return(n=this.stopWatching)==null?void 0:n.call(this)}),this.teardown.push(()=>N(this,L,It).call(this));const e=n=>{(n.key===gt||n.key===null)&&N(this,L,Me).call(this)};return window.addEventListener("storage",e),this.teardown.push(()=>window.removeEventListener("storage",e)),this}on(e,n){if(typeof n!="function")return()=>{};const o=this.listeners.get(e)||new Set;return o.add(n),this.listeners.set(e,o),()=>this.off(e,n)}off(e,n){var o;return(o=this.listeners.get(e))==null||o.delete(n),this}emit(e,n){for(const o of this.listeners.get(e)||[])try{o(n)}catch(i){console.error(`[BugCatch] a '${e}' listener threw:`,i)}}unreadUpdates(){return Pe()}markUpdateRead(e){return ha(e),N(this,L,Me).call(this),this}markReportRead(e){return fa(e),N(this,L,Me).call(this),this}markUpdatesRead(){return wn(),N(this,L,Me).call(this),this}async verifyFix(e,{result:n,resolvedAt:o,note:i}){const r=n==="STILL_HAPPENING"?await N(this,L,Et).call(this,{}):{};return Ra({apiBase:this.config.apiBase,bugId:e,result:n,resolvedAt:o,note:i,metadata:r.metadata,logs:r.logs})}async myReport(e){const n=await ma({apiBase:this.config.apiBase,bugId:e});return N(this,L,Eo).call(this,e,n==null?void 0:n.assistant),n}replyToReport(e,{body:n,attachments:o}={}){return vn({apiBase:this.config.apiBase,bugId:e,body:n,attachments:o})}async canCallNow(){return!!await this.callKind()}async callKind(){return(await this.callKinds()).live?"live":null}async callKinds(){var n;const e={agent:!1,live:!1};return!this.config.voice||!((n=this.config.user)!=null&&n.email)?e:this.kinds!==void 0?this.kinds:(this.kinds=await ya({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId}),this.kinds)}canCall(e){return this.config.voice?xn({apiBase:this.config.apiBase,bugId:e}):Promise.resolve(!1)}async startCall(e){var n;if(!this.config.voice)throw new Error("[BugCatch] calling is switched off.");if(this.call||this.callStarting)throw new Error("[BugCatch] a call is already running.");this.callStarting=!0;try{if(!await this.callKind())throw new Error((n=this.config.user)!=null&&n.email?"[BugCatch] calling is not available on this project.":"[BugCatch] a call needs to know who is calling — call identify() with an email first.");return await N(this,L,Mo).call(this,e)}finally{this.callStarting=!1}}startLiveCall(e){return this.startCall(e)}canCallTeam(e){return this.config.voice?xn({apiBase:this.config.apiBase,bugId:e}):Promise.resolve(!1)}endCall(){var e;return(e=this.call)==null||e.hangUp(),this.call=null,this}myReports(){return ba({apiBase:this.config.apiBase})}hasReports(){return!!he()}forgetReports(){var e;return(e=this.stopWatching)==null||e.call(this),this.stopWatching=null,this.endCall(),Ae(),N(this,L,Me).call(this),this}identify(e){const n=Yn(e,o=>this.warn(o));return e!=null&&!n?this:(this.config.user=n,this.debugLog("identify",n),this)}setContext(e){return this.context=Xn(this.context,e,n=>this.warn(n)),this.debugLog("context",this.context),this}getContext(){return{...this.context}}open(){return this.started?this.widgetControls?(this.widgetControls.open(),this):(this.warn("open() needs the built-in widget; it was turned off with widget: false."),this):(this.warn("open() was called before init() — nothing to open yet."),this)}close(){var e;return(e=this.widgetControls)==null||e.close(),this}isOpen(){var e;return!!((e=this.widgetControls)!=null&&e.isOpen())}async uploadAttachment(e,n,o){if(!this.started)throw new Error("[BugCatch] call init() first.");return Jo({apiBase:this.config.apiBase,apiKey:this.config.apiKey,blob:e,mime:n||(e==null?void 0:e.type),onProgress:o})}async report({title:e,description:n="",priority:o="MEDIUM",metadata:i={},attachments:r=[],references:s=[],context:l=null}={}){var R,z,S,M,I,A,H,U;if(!this.started)throw new Error("[BugCatch] call init() first.");if(typeof e!="string"||!e.trim())throw new Error("[BugCatch] a title is required.");["LOW","MEDIUM","HIGH","CRITICAL"].includes(String(o).toUpperCase())||(this.warn(`priority "${o}" is not one of LOW, MEDIUM, HIGH, CRITICAL — sent as MEDIUM.`),o="MEDIUM");const g=(r||[]).filter(T=>(T==null?void 0:T.storageKey)&<(T.mime,ct)).map(T=>({type:T.type==="VIDEO"?"VIDEO":"SCREENSHOT",storageKey:T.storageKey,mime:lt(T.mime,ct)})),f=(Array.isArray(s)?s:[]).filter(T=>T&&typeof T.key=="string"&&T.key&&(typeof T.value=="string"||typeof T.value=="number")).map(T=>({key:T.key.slice(0,64),value:String(T.value).trim().slice(0,120)})).filter(T=>T.value);Array.isArray(s)&&f.length<s.length&&this.warn("report({ references }) takes [{ key, value }] with string values; malformed entries were dropped.");let m=await N(this,L,Et).call(this,{title:e.trim(),description:typeof n=="string"?n:String(n??""),priority:String(o).toUpperCase(),metadata:i,media:g,references:f,context:l});const b=N(this,L,sn).call(this,m);if(b===!1)return{cancelled:!0};m=b,this.debugLog("sending report",{title:m.title,user:(R=m.metadata)==null?void 0:R.user,context:(z=m.metadata)==null?void 0:z.context,references:m.references,console:(I=(M=(S=m.logs)==null?void 0:S.console)==null?void 0:M.entries)==null?void 0:I.length,network:(U=(H=(A=m.logs)==null?void 0:A.network)==null?void 0:H.entries)==null?void 0:U.length});const h=Se(this.config.projectId);let u;try{u=await fetch(`${this.config.apiBase}/ingest/bugs`,{method:"POST",headers:{"Content-Type":"application/json","X-BugCatch-Key":this.config.apiKey,...h!=null&&h.token?{"X-BugCatch-Session":h.token}:{}},body:JSON.stringify(m)})}catch(T){const Q=new Error(`[BugCatch] could not reach ${this.config.apiBase} — check apiBase, and that this site's origin is allowed by the API.`);throw Q.cause=T,N(this,L,Tt).call(this,"report",Q),Q}if(u.status===401&&h&&jt(this.config.projectId),!u.ok){let T="";try{const $=await u.json();T=Array.isArray($.message)?$.message.join(", "):$.message||""}catch{}u.status===401&&!h&&(T||(T="the apiKey was not accepted")),u.status===403&&(T||(T="the apiKey is not allowed to report to this projectId"));const Q=new Error(`[BugCatch] report failed (HTTP ${u.status})${T?": "+T:""}`);throw Q.status=u.status,N(this,L,Tt).call(this,"report",Q),Q}const k=await u.json();return N(this,L,rn).call(this,k,{title:m.title??e.trim(),via:"form"}),k.watchToken&&(Ot(k.watchToken),this.config.updates&&this.startWatching()),k}loginState(){var e;return ra({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,token:(e=Se(this.config.projectId))==null?void 0:e.token})}referenceFields(){return this.refFields?this.refFields:(this.refFields=qa({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId}),this.refFields)}signedInAs(){const e=Se(this.config.projectId);return e?{email:e.email,name:e.name}:null}signIn(e,{name:n}={}){var o;return ia({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,email:e,name:n??((o=this.config.user)==null?void 0:o.name)??null})}async confirmSignIn(e,n){var i;const o=await sa({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,email:e,code:n});return(i=this.config.user)!=null&&i.email||(this.config.user={email:o.email,name:o.name||void 0}),this.emit("signin",{email:o.email,name:o.name}),{email:o.email,name:o.name}}async signOut(){var o;const e=Se(this.config.projectId),n=await ca({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,token:e==null?void 0:e.token});return e!=null&&e.email&&((o=this.config.user)==null?void 0:o.email)===e.email&&(this.config.user=null),this.emit("signout",{email:(e==null?void 0:e.email)||null}),n}knownIssues(){var e;return La({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,sessionToken:(e=Se(this.config.projectId))==null?void 0:e.token})}matchKnownIssues(e,{signal:n}={}){var o;return Aa({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,q:e||"",sessionToken:(o=Se(this.config.projectId))==null?void 0:o.token,signal:n})}async meToo(e,{email:n,name:o}={}){var s,l;const i=Se(this.config.projectId),r=await hn();return Ba({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,bugId:e,reporterEmail:n||((s=this.config.user)==null?void 0:s.email),reporterName:o||((l=this.config.user)==null?void 0:l.name),metadata:{...r,user:this.config.user||void 0,...Object.keys(this.context).length?{context:this.context}:{},sdk:We},logs:{console:{entries:this.consoleBuffer.all()},network:{entries:this.networkBuffer.all()}},sessionToken:i==null?void 0:i.token})}snapshot(){return{user:this.config.user||null,context:{...this.context},console:this.consoleBuffer.all(),network:this.networkBuffer.all(),environment:fn()}}clear(){this.consoleBuffer.clear(),this.networkBuffer.clear()}destroy(){this.endCall(),this.teardown.forEach(e=>{try{e()}catch{}}),this.teardown=[],this.notifier=null,this.started=!1}}L=new WeakSet,Ct=function(e,n){const o=this.config[e];if(typeof o=="function")try{o(n)}catch(i){console.error(`[BugCatch] your ${e} callback threw:`,i)}},To=function(){if(typeof window>"u"||typeof fetch!="function")return;const e=`bugcatch:hello:${this.config.projectId}`,n=new Date().toISOString().slice(0,10);try{if(window.localStorage.getItem(e)===n)return}catch{}const o=setTimeout(()=>{try{window.localStorage.setItem(e,n)}catch{}fetch(`${this.config.apiBase}/ingest/hello`,{method:"POST",keepalive:!0,headers:{"Content-Type":"application/json","X-BugCatch-Key":this.config.apiKey},body:JSON.stringify({projectId:this.config.projectId,version:We.version,identify:!!this.config.user,context:!!(this.context&&Object.keys(this.context).length),widget:!!this.config.widget,environment:this.config.environment||null,release:this.config.release||null})}).catch(()=>{})},5e3);this.teardown.push(()=>clearTimeout(o))},Me=function(){const e=Pe();if(this.emit("unread",{count:e.length,updates:e}),!!this.config.updateToast){if(!this.notifier){if(!e.length)return;this.notifier=Ma({accent:this.config.accent,position:this.config.widgetPosition,onRead:n=>this.markUpdateRead(n),onReadAll:()=>this.markUpdatesRead(),onCall:this.config.voice?n=>{this.markUpdateRead(n.id),this.startCall(n.bugId)}:null}),this.teardown.push(()=>{var n;return(n=this.notifier)==null?void 0:n.destroy()})}this.notifier.render(e)}},Eo=function(e,n){const o=n==null?void 0:n.phase;if(!e||typeof o!="string"||this.phases.get(e)===o)return;this.phases.set(e,o);const i={bugId:e,phase:o,title:n.title??null,detail:n.detail??null};this.debugLog("assistant",i),N(this,L,Ct).call(this,"onAssistantPhase",i),this.emit("assistant",i)},rn=function(e,{title:n,via:o}){if(!(e!=null&&e.id))return;const i={bugId:e.id,title:n??null,via:o,result:e};this.debugLog("report accepted",i),N(this,L,Ct).call(this,"onReportSubmitted",i),this.emit("report",i)},Tt=function(e,n){N(this,L,Ct).call(this,"onError",{action:e,error:n}),this.emit("error",{action:e,error:n})},Et=async function({title:e,description:n="",priority:o="MEDIUM",metadata:i={},media:r=[],references:s=[],context:l=null}){var f,m;const g=l?Xn(this.context,l,b=>this.warn(b.replace("setContext()","report({ context })"))):this.context;return{projectId:this.config.projectId,...e?{title:e}:{},description:n,priority:o,url:window.location.href,reporterEmail:(f=this.config.user)==null?void 0:f.email,reporterName:(m=this.config.user)==null?void 0:m.name,metadata:{...await hn(),release:this.config.release,environment:this.config.environment,buildId:this.config.buildId,...i,user:this.config.user||void 0,...Object.keys(g).length?{context:g}:{},sdk:We},logs:{console:{entries:this.consoleBuffer.all()},network:{entries:this.networkBuffer.all()}},...r.length?{attachments:r}:{},...s.length?{references:s}:{}}},sn=function(e){if(typeof this.config.beforeSend!="function")return e;let n;try{n=this.config.beforeSend(e)}catch(o){return this.warn(`beforeSend threw, so nothing was sent: ${(o==null?void 0:o.message)||o}`),!1}return n===!1?!1:n&&typeof n=="object"?n:e},Io=async function(){const e=Se(this.config.projectId),n=N(this,L,sn).call(this,await N(this,L,Et).call(this,{}));if(n===!1)return this.debugLog("call cancelled by beforeSend"),{cancelled:!0};let o;try{o=await wa({apiBase:this.config.apiBase,apiKey:this.config.apiKey,token:e==null?void 0:e.token,payload:n})}catch(i){throw i.status===401&&e&&jt(this.config.projectId),N(this,L,Tt).call(this,"call",i),i}return N(this,L,rn).call(this,o,{title:null,via:"call"}),o.watchToken&&(Ot(o.watchToken),this.config.updates&&this.startWatching()),o},Mo=async function(e){if(!Pt())throw new Error("[BugCatch] this browser cannot make live calls.");const n=await Kt();let o,i=null;try{if(e)o=await va({apiBase:this.config.apiBase,bugId:e});else if(i=await N(this,L,Io).call(this),e=i.id,o=i.live_call,!(o!=null&&o.realtime_url)){const s=new Error(`[BugCatch] the report was filed, but the team could not be rung${i.call_error?`: ${i.call_error}`:"."}`);throw s.filed=i,s.reason=i.call_error||null,s}}catch(s){for(const l of n.getTracks())l.stop();throw s}const r=await Un({realtimeUrl:o.realtime_url,stream:n,ringsUntil:o.rings_until,onState:(s,l)=>{(s==="ended"||s==="failed"||s==="missed")&&(this.call=null),s==="missed"&&xa({apiBase:this.config.apiBase,bugId:e,callId:o.call_id}),typeof this.config.onCallState=="function"&&this.config.onCallState(s,{bugId:e,live:!0,...l}),this.emit("call",{bugId:e,live:!0,state:s,...l})}});return this.call=r,Object.assign(r,{bugId:e,callId:o.call_id,live:!0,filed:i,recorded:!!o.recorded})},Lo=function(e){var i;const n=e.incomingCall;if(!this.config.voice||!Pt()||((i=this.ringing)==null?void 0:i.callId)===n.callId||this.call||this.callStarting)return;N(this,L,It).call(this);const o=fr({call:n,accent:this.config.accent,position:this.config.widgetPosition,onAnswer:()=>{N(this,L,Ao).call(this,e.bugId,n)},onDecline:()=>{this.ringing=null,kn({apiBase:this.config.apiBase,bugId:e.bugId,callId:n.callId}),this.emit("incoming-call",{bugId:e.bugId,callId:n.callId,state:"declined"})},onExpire:()=>{this.ringing=null,this.emit("incoming-call",{bugId:e.bugId,callId:n.callId,state:"missed"})}});if(this.ringing={callId:n.callId,dismiss:o},typeof this.config.onIncomingCall=="function")try{this.config.onIncomingCall({bugId:e.bugId,...n})}catch{}this.emit("incoming-call",{bugId:e.bugId,callId:n.callId,state:"ringing"})},It=function(e){if(this.ringing&&!(e&&this.ringing.callId!==e)){try{this.ringing.dismiss()}catch{}this.ringing=null}},Ao=async function(e,n){if(this.ringing=null,this.call||this.callStarting)return;this.callStarting=!0;let o;try{o=await Kt()}catch(r){this.callStarting=!1,kn({apiBase:this.config.apiBase,bugId:e,callId:n.callId}),this.emit("incoming-call",{bugId:e,callId:n.callId,state:"failed",error:r});return}let i;try{i=await ka({apiBase:this.config.apiBase,bugId:e,callId:n.callId})}catch(r){for(const s of o.getTracks())s.stop();this.callStarting=!1,this.emit("incoming-call",{bugId:e,callId:n.callId,state:"missed",error:r});return}try{const r=await Un({realtimeUrl:i.realtime_url,stream:o,onState:(s,l)=>{(s==="ended"||s==="failed"||s==="missed")&&(this.call=null),typeof this.config.onCallState=="function"&&this.config.onCallState(s,{bugId:e,live:!0,incoming:!0,...l}),this.emit("call",{bugId:e,live:!0,incoming:!0,state:s,...l})}});this.call=r,this.emit("incoming-call",{bugId:e,callId:n.callId,state:"answered"})}catch(r){for(const s of o.getTracks())s.stop();this.emit("incoming-call",{bugId:e,callId:n.callId,state:"failed",error:r})}finally{this.callStarting=!1}};const Wt=new Gn;return Wt.Client=Gn,Wt.version=We.version,Wt});
|
|
1369
1392
|
//# sourceMappingURL=bugcatch.umd.js.map
|