@crikket-io/capture 0.1.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.
Files changed (72) hide show
  1. package/README.md +203 -0
  2. package/dist/browser.d.ts +6 -0
  3. package/dist/browser.js +1 -0
  4. package/dist/capture-screenshot-b3snwyge.js +1 -0
  5. package/dist/capture.css +907 -0
  6. package/dist/capture.global.js +10 -0
  7. package/dist/constants.d.ts +7 -0
  8. package/dist/debugger/debugger-collector.d.ts +15 -0
  9. package/dist/debugger/lazy-debugger-collector.d.ts +12 -0
  10. package/dist/debugger-collector-f0etqtvj.js +2 -0
  11. package/dist/eager.d.ts +18 -0
  12. package/dist/global.d.ts +6 -0
  13. package/dist/index-0avnsp70.js +2 -0
  14. package/dist/index-331vjad4.js +2 -0
  15. package/dist/index-97c5xshv.js +2 -0
  16. package/dist/index-ehy0ec5e.js +2 -0
  17. package/dist/index-nd41xgv7.js +2 -0
  18. package/dist/index-shtqtrh3.js +2 -0
  19. package/dist/index.d.ts +18 -0
  20. package/dist/index.js +2 -0
  21. package/dist/launcher.css +42 -0
  22. package/dist/media/capture-screenshot.d.ts +1 -0
  23. package/dist/media/display-capture.d.ts +6 -0
  24. package/dist/media/lazy-capture-media.d.ts +3 -0
  25. package/dist/media/start-display-recording.d.ts +2 -0
  26. package/dist/plugin.d.ts +5 -0
  27. package/dist/plugin.js +1 -0
  28. package/dist/react.d.ts +2 -0
  29. package/dist/react.js +1 -0
  30. package/dist/review-form-section-frr1x0zk.js +1 -0
  31. package/dist/runtime/capture-runtime.d.ts +36 -0
  32. package/dist/runtime/lazy-capture-runtime.d.ts +33 -0
  33. package/dist/runtime/submit-captured-report.d.ts +8 -0
  34. package/dist/start-display-recording-cve3f1me.js +1 -0
  35. package/dist/submit-captured-report-behdzdha.js +1 -0
  36. package/dist/transport/default-submit-transport.d.ts +2 -0
  37. package/dist/transport/turnstile.d.ts +20 -0
  38. package/dist/types.d.ts +165 -0
  39. package/dist/ui/capture-widget/capture-widget-root.d.ts +6 -0
  40. package/dist/ui/capture-widget/capture-widget-shell.d.ts +8 -0
  41. package/dist/ui/capture-widget/capture-widget-view.d.ts +7 -0
  42. package/dist/ui/capture-widget/components/capture-launcher-button.d.ts +5 -0
  43. package/dist/ui/capture-widget/components/icons.d.ts +8 -0
  44. package/dist/ui/capture-widget/components/media-preview.d.ts +6 -0
  45. package/dist/ui/capture-widget/components/primitives/badge.d.ts +5 -0
  46. package/dist/ui/capture-widget/components/primitives/button.d.ts +7 -0
  47. package/dist/ui/capture-widget/components/primitives/card.d.ts +11 -0
  48. package/dist/ui/capture-widget/components/primitives/cn.d.ts +1 -0
  49. package/dist/ui/capture-widget/components/primitives/field.d.ts +4 -0
  50. package/dist/ui/capture-widget/components/primitives/input.d.ts +1 -0
  51. package/dist/ui/capture-widget/components/primitives/label.d.ts +1 -0
  52. package/dist/ui/capture-widget/components/primitives/textarea.d.ts +1 -0
  53. package/dist/ui/capture-widget/components/screenshot-annotation-editor.d.ts +7 -0
  54. package/dist/ui/capture-widget/components/summary-stat.d.ts +4 -0
  55. package/dist/ui/capture-widget/hooks/use-capture-ui-handlers.d.ts +12 -0
  56. package/dist/ui/capture-widget/hooks/use-recording-clock.d.ts +4 -0
  57. package/dist/ui/capture-widget/hooks/use-review-form.d.ts +14 -0
  58. package/dist/ui/capture-widget/sections/chooser-section.d.ts +5 -0
  59. package/dist/ui/capture-widget/sections/recording-dock.d.ts +6 -0
  60. package/dist/ui/capture-widget/sections/review-form-section.d.ts +11 -0
  61. package/dist/ui/capture-widget/sections/success-section.d.ts +5 -0
  62. package/dist/ui/capture-widget/utils/get-view-description.d.ts +2 -0
  63. package/dist/ui/capture-widget/utils/review-form-schema.d.ts +22 -0
  64. package/dist/ui/capture-widget/utils/screenshot-annotations.d.ts +45 -0
  65. package/dist/ui/mount-capture-launcher.d.ts +11 -0
  66. package/dist/ui/mount-capture-ui.d.ts +2 -0
  67. package/dist/ui/store/capture-ui-store.d.ts +2 -0
  68. package/dist/ui/types.d.ts +63 -0
  69. package/dist/utils.d.ts +16 -0
  70. package/package.json +85 -0
  71. package/react.d.ts +2 -0
  72. package/react.js +1 -0
@@ -0,0 +1,7 @@
1
+ export declare const DEFAULT_ENDPOINT = "https://api.crikket.io";
2
+ export declare const DEFAULT_SUBMIT_PATH = "/api/embed/bug-reports";
3
+ export declare const DEFAULT_Z_INDEX = 2147483640;
4
+ export declare const MAX_RECENT_EVENT_AGE_MS = 60000;
5
+ export declare const MAX_RECENT_EVENT_COUNT = 250;
6
+ export declare const SCREENSHOT_LOOKBACK_MS = 10000;
7
+ export declare const TRAILING_SLASHES_REGEX: RegExp;
@@ -0,0 +1,15 @@
1
+ import type { CaptureType, DebuggerSession, ReviewSnapshot } from "../types.js";
2
+ export declare class DebuggerCollector {
3
+ private installed;
4
+ private recentEvents;
5
+ private session;
6
+ private readonly handleWindowMessage;
7
+ install(): void;
8
+ dispose(): void;
9
+ startSession(captureType: CaptureType, lookbackMs?: number): DebuggerSession;
10
+ markRecordingStarted(recordingStartedAt: number): void;
11
+ clearSession(): void;
12
+ finalizeSession(): ReviewSnapshot;
13
+ private trimRecentEvents;
14
+ private appendEvent;
15
+ }
@@ -0,0 +1,12 @@
1
+ import type { ReviewSnapshot } from "../types.js";
2
+ export declare class LazyDebuggerCollector {
3
+ private collector;
4
+ private collectorPromise;
5
+ startScreenshotSession(): Promise<void>;
6
+ startRecordingSession(): Promise<void>;
7
+ markRecordingStarted(recordingStartedAt: number): void;
8
+ finalizeSession(): ReviewSnapshot;
9
+ clearSession(): void;
10
+ dispose(): void;
11
+ private ensureCollector;
12
+ }
@@ -0,0 +1,2 @@
1
+ import{H as _0,I as r,O as b0,P as A0}from"./index-ehy0ec5e.js";import"./index-331vjad4.js";var t=2000,I=2000,e=4096,v=4000,$0="CRIKKET_DEBUGGER_PAGE_BRIDGE";var m0=400,E0=800,T0=1200;function m($,J){$.push(J),y0($,J.kind);while($.length>t){let W=p0($,["console","action","network"]);$.splice(W,1)}}function W0($,J){if(h0($,J))return;m($,J)}function Z0($,J){if(g0($,J))return;m($,J)}function h0($,J){for(let Q=$.length-1;Q>=0;Q-=1){let Z=$[Q];if(!Z||Z.kind!=="network")continue;if(!(Z.method===J.method&&Z.url===J.url&&(Z.status??0)===(J.status??0)))continue;if(Math.abs(Z.timestamp-J.timestamp)>350)return!1;return!0}return!1}function g0($,J){if(J.actionType!=="navigation")return!1;let W=500,Q=J0(J);if(!Q)return!1;for(let Z=$.length-1;Z>=0;Z-=1){let Y=$[Z];if(!Y||Y.kind!=="action"||Y.actionType!=="navigation")continue;if(Math.abs(Y.timestamp-J.timestamp)>W)return!1;if(J0(Y)===Q)return!0}return!1}function J0($){let J=$.metadata;if(!(J&&typeof J==="object"))return null;let W=J.url;return typeof W==="string"&&W.length>0?W:null}function y0($,J){let W=c0(J),Q=0;for(let j of $)if(j.kind===J)Q+=1;let Z=Q-W;if(Z<=0)return;let Y=0;for(let j=0;j<$.length&&Y<Z;j+=1){if($[j]?.kind!==J)continue;$.splice(j,1),j-=1,Y+=1}}function c0($){if($==="action")return m0;if($==="console")return E0;return T0}function p0($,J){for(let W of J){let Q=$.findIndex((Z)=>Z.kind===W);if(Q>=0)return Q}return 0}var Q0="CRIKKET_DEBUGGER_PAGE_BRIDGE",o="__crikketDebuggerPageScriptInstalled",V=2000,O=4000,z=120,_=500,i=40,Y0=120,j0=4,E=30,K0=30;var S="[REDACTED]",d0=["authorization","cookie","set-cookie","token","secret","password","passwd","pwd","session","api-key","apikey","x-api-key","refresh-token","refresh_token","access-token","access_token","id-token","id_token","client-secret","client_secret"],s=/((?:access[_-]?token|refresh[_-]?token|id[_-]?token|api[_-]?key|client[_-]?secret|password|passwd|pwd|authorization|cookie|session[_-]?id)\s*[:=]\s*)([^&\s",;]+)/gi,F=($,J=V)=>{if($.length<=J)return $;return`${$.slice(0,J)}...`},T=($)=>{let J=$.trim().toLowerCase();if(!J)return!1;return d0.some((W)=>{return J.includes(W)})},b=($)=>{return $.includes("debugger")||T($)},k=($)=>{if(!($ instanceof Element))return;if($.id)return`#${$.id}`;let W=(typeof $.className==="string"?$.className:"").split(" ").map((Q)=>Q.trim()).find((Q)=>Q.length>0);if(W)return`${$.tagName.toLowerCase()}.${W}`;return $.tagName.toLowerCase()},h=($,J)=>{try{return new URL($,location.href).toString()}catch(W){return J.reportNonFatalError("Failed to normalize network URL in debugger instrumentation",{error:W,value:$}),null}},g=($)=>{try{let J=new URL($);for(let[W]of J.searchParams.entries()){if(!T(W))continue;J.searchParams.set(W,S)}return J.toString()}catch{return $}},l=($,J=0)=>{if(J>=6)return"[MaxDepth]";if(Array.isArray($))return $.map((W)=>l(W,J+1));if($&&typeof $==="object"){let W={};for(let[Q,Z]of Object.entries($)){if(T(Q)){W[Q]=S;continue}W[Q]=l(Z,J+1)}return W}if(typeof $==="string")return $.replace(s,`$1${S}`);return $},v0=($)=>{let J=new URLSearchParams($);for(let[W]of J.entries()){if(!T(W))continue;J.set(W,S)}return J.toString()},M=($,J)=>{if(typeof $!=="string"||$.length===0)return $;let W=J.toLowerCase();if(W.includes("application/json"))try{let Q=JSON.parse($);return F(JSON.stringify(l(Q)),V*2)}catch{return F($.replace(s,`$1${S}`),V*2)}if(W.includes("x-www-form-urlencoded"))return F(v0($),V*2);return F($.replace(s,`$1${S}`),V*2)};function w0(){let $=console.warn.bind(console),J=new Set;return{reportNonFatalError(W,Q){if(J.has(W))return;J.add(W),$(`[Non-fatal] ${W}`,Q)}}}function G0($){let{postAction:J}=$,W=(K)=>{J("navigation","window",{mode:K,url:location.href,path:location.pathname,search:location.search,hash:location.hash,title:document.title})},Q={click:(K)=>{J("click",k(K.target))},input:(K)=>{let P=k(K.target),G,X=K.target;if(X instanceof HTMLInputElement||X instanceof HTMLTextAreaElement)G=X.value.length;J("input",P,{valueLength:G})},change:(K)=>{J("change",k(K.target))}},Z=(K)=>{if(K.type!=="click"&&K.type!=="input"&&K.type!=="change")return;Q[K.type](K)};for(let K of["click","input","change"])document.addEventListener(K,Z,{capture:!0,passive:!0});let Y=history.pushState;history.pushState=function(...K){Y.apply(this,K),W("pushState")};let j=history.replaceState;history.replaceState=function(...K){j.apply(this,K),W("replaceState")},window.addEventListener("popstate",()=>{W("popstate")},{capture:!0,passive:!0}),window.addEventListener("hashchange",()=>{W("hashchange")},{capture:!0,passive:!0}),W("initial")}function X0($){let{reporter:J,postConsole:W}=$,Q=["log","info","warn","error","debug"];for(let Z of Q){let Y=console[Z].bind(console);console[Z]=(...j)=>{try{W(Z,j)}catch(K){J.reportNonFatalError("Failed to post console event in debugger instrumentation",K)}Y(...j)}}}var P0="__crikketDebuggerDiagnostics",o0=1,i0=25,s0=300,l0=()=>{return{version:o0,installedAt:Date.now(),url:location.href,hooks:{fetch:"pending",xhr:!1},counters:{actionEvents:0,consoleEvents:0,networkEvents:0,fetchCalls:0,fetchFailures:0,xhrCalls:0,queuedEvents:0,flushedBatches:0},last:{},errors:[]}},u0=($,J)=>{if(J instanceof Error)return`${$}: ${J.message}`;return`${$}: ${String(J)}`};function H0($){let J=$,W=J[P0]??l0();return J[P0]=W,W.installedAt=Date.now(),W.url=location.href,W.hooks.fetch="pending",W.hooks.xhr=!1,{state:W,createReporter(Q){let Z=Q.reportNonFatalError.bind(Q);return{reportNonFatalError(Y,j){if(W.errors.push(F(u0(Y,j),s0)),W.errors.length>i0)W.errors.shift();Z(Y,j)}}},recordActionEvent(){W.counters.actionEvents+=1},recordConsoleEvent(){W.counters.consoleEvents+=1},recordNetworkEvent(Q){W.counters.networkEvents+=1,W.last.networkUrl=Q},recordFetchCall(){W.counters.fetchCalls+=1},recordFetchFailure(Q){W.counters.fetchFailures+=1,W.last.fetchError=Q},setFetchHookState(Q){W.hooks.fetch=Q},recordXhrCall(){W.counters.xhrCalls+=1},setXhrHookInstalled(){W.hooks.xhr=!0},recordQueuedEvent(){W.counters.queuedEvents+=1},recordFlushedBatch(){W.counters.flushedBatches+=1}}}function F0($={}){let{recordFlushedBatch:J,recordQueuedEvent:W}=$,Q=[],Z=null,Y=()=>{if(Z=null,Q.length===0)return;let P=Q.splice(0,i);if(J?.(),window.postMessage({source:Q0,events:P},"*"),Q.length>0){Z=setTimeout(Y,0);return}},j=()=>{if(Z)return;Z=setTimeout(Y,Y0)};return{enqueueEvent:(P)=>{if(Q.push(P),W?.(),Q.length>=i){if(Z)clearTimeout(Z);Z=setTimeout(Y,0);return}j()},flushEventQueue:Y}}var n0=($)=>{if($===null||typeof $==="boolean"||typeof $==="number")return{handled:!0,value:$};if(typeof $==="string")return{handled:!0,value:F($)};if(typeof $>"u")return{handled:!0,value:"[undefined]"};if(typeof $==="bigint")return{handled:!0,value:`${$.toString()}n`};if(typeof $==="symbol")return{handled:!0,value:$.toString()};if(typeof $==="function")return{handled:!0,value:`[Function ${$.name||"anonymous"}]`};return{handled:!1}},r0=($)=>{return{name:$.name,message:F($.message),stack:typeof $.stack==="string"?F($.stack):void 0}},a0=($)=>{return typeof ArrayBuffer<"u"&&$ instanceof ArrayBuffer},t0=($)=>{return typeof ArrayBuffer<"u"&&ArrayBuffer.isView($)},e0=($,J,W,Q,Z)=>{let Y=[],j=Math.min($.length,K0);for(let K=0;K<j;K+=1)Y.push(Z($[K],J,W+1,`${Q}[${K}]`));if($.length>j)Y.push(`[+${$.length-j} more]`);return Y},$1=($,J,W,Q,Z)=>{let Y=[],j=0;for(let[K,P]of $.entries()){if(j>=E){Y.push(`[+${$.size-j} more]`);break}Y.push([Z(K,J,W+1,`${Q}.mapKey${j}`),Z(P,J,W+1,`${Q}.mapVal${j}`)]),j+=1}return{type:"Map",entries:Y}},J1=($,J,W,Q,Z)=>{let Y=[],j=0;for(let K of $.values()){if(j>=E){Y.push(`[+${$.size-j} more]`);break}Y.push(Z(K,J,W+1,`${Q}.setVal${j}`)),j+=1}return{type:"Set",values:Y}},W1=($,J,W,Q,Z)=>{let Y={},j=Object.entries($),K=Math.min(j.length,E);for(let P=0;P<K;P+=1){let[G,X]=j[P]??[];if(typeof G!=="string")continue;Y[G]=Z(X,J,W+1,`${Q}.${G}`)}if(j.length>K)Y.__truncatedKeys=j.length-K;return Y},Z1=[{canHandle:($)=>$ instanceof Error,serialize:($)=>r0($)},{canHandle:($)=>$ instanceof Date,serialize:($)=>$.toISOString()},{canHandle:($)=>$ instanceof RegExp,serialize:($)=>$.toString()},{canHandle:($)=>typeof URL<"u"&&$ instanceof URL,serialize:($)=>$.toString()},{canHandle:($)=>typeof Element<"u"&&$ instanceof Element,serialize:($)=>{let J=$;return k(J)??J.tagName.toLowerCase()}},{canHandle:($)=>typeof Event<"u"&&$ instanceof Event,serialize:($)=>{let J=$;return{type:J.type,target:k(J.target)}}},{canHandle:($)=>Array.isArray($),serialize:($,J,W,Q,Z)=>e0($,J,W,Q,Z)},{canHandle:($)=>$ instanceof Map,serialize:($,J,W,Q,Z)=>$1($,J,W,Q,Z)},{canHandle:($)=>$ instanceof Set,serialize:($,J,W,Q,Z)=>J1($,J,W,Q,Z)},{canHandle:($)=>a0($),serialize:($)=>`[ArrayBuffer ${$.byteLength}]`},{canHandle:($)=>t0($),serialize:($)=>{let J=$;return`[${J.constructor.name} ${J.byteLength}]`}}],Q1=($,J,W,Q,Z)=>{for(let Y of Z1){if(!Y.canHandle($))continue;return Y.serialize($,J,W,Q,Z)}return W1($,J,W,Q,Z)},U0=($,J,W,Q)=>{let Z=n0($);if(Z.handled)return Z.value;if(W>=j0)return"[MaxDepth]";if(typeof $!=="object"||$===null)return Object.prototype.toString.call($);let Y=J.seen.get($);if(Y)return`[Circular ~${Y}]`;return J.seen.set($,Q),Q1($,J,W,Q,U0)};function N($){return(J)=>{if(typeof J==="string")return F(J);if(typeof J==="number"||typeof J==="boolean"||J===null||typeof J>"u")return String(J);try{let W=U0(J,{seen:new WeakMap},0,"$");if(typeof W==="string")return F(W);return F(JSON.stringify(W))}catch(W){return $.reportNonFatalError("Failed to stringify console value in debugger instrumentation",W),F(Object.prototype.toString.call(J))}}}var y=($,J)=>{if(!$)return;if(typeof $==="string")return F($,O);if($ instanceof URLSearchParams)return F($.toString(),O);if(typeof FormData<"u"&&$ instanceof FormData){let W=[];for(let Q of $.keys())W.push(Q);return F(`[form-data] ${W.join(",")}`,O)}if(typeof Blob<"u"&&$ instanceof Blob)return`[blob:${$.type||"unknown"}:${$.size}]`;if(typeof ArrayBuffer<"u"){if($ instanceof ArrayBuffer)return`[arraybuffer:${$.byteLength}]`;if(ArrayBuffer.isView($))return`[${$.constructor.name.toLowerCase()}:${$.byteLength}]`}return F(J($),O)},R=($)=>{let J=$.toLowerCase();return J.includes("json")||J.includes("text")||J.includes("xml")||J.includes("x-www-form-urlencoded")};var A=($)=>{if(!$)return{};let J={};for(let[W,Q]of $.entries()){let Z=W.trim().toLowerCase();if(!Z||b(Z))continue;J[Z.slice(0,z)]=Q.slice(0,_)}return J},f0=($)=>{let J={},W=$.split(`
2
+ `);for(let Q of W){let Z=Q.replace("\r",""),Y=Z.indexOf(":");if(Y<=0)continue;let j=Z.slice(0,Y).trim().toLowerCase();if(!j||b(j))continue;let K=Z.slice(Y+1).trim();if(!K)continue;J[j.slice(0,z)]=K.slice(0,_)}return J};var q=($,J)=>{let W=()=>{Promise.resolve(J()).catch((Q)=>{$.reportNonFatalError("Background debugger instrumentation task failed",Q)})};if(typeof window.requestIdleCallback==="function"){window.requestIdleCallback(()=>{W()});return}window.setTimeout(W,0)},c=($,J,W,Q="")=>{return new Promise((Z)=>{q($,()=>{Z(M(y(J,W),Q))})})},p=($,J,W,Q)=>{return new Promise((Z)=>{q($,async()=>{if(!R(J)){Z(void 0);return}try{Z(M(F(await Q(),O),J))}catch(Y){$.reportNonFatalError(W,Y),Z(void 0)}})})};var Y1=($,J)=>{if(typeof J?.method==="string"&&J.method)return J.method.toUpperCase();if($ instanceof Request)return $.method.toUpperCase();return"GET"},j1=($)=>{if(typeof $==="string")return $;if($ instanceof URL)return $.toString();return $.url},O0=async($,J,W,Q,Z)=>{let Y=y(J?.body,Q);if(Y)return Y;if(!($ instanceof Request))return;let j=(J?.method??$.method??"GET").toUpperCase();if(j==="GET"||j==="HEAD"||$.bodyUsed)return;let K=W?.get("content-type")??$.headers.get("content-type")??"";if(!R(K))return;try{return M(F(await $.clone().text(),O),K)}catch(P){Z.reportNonFatalError("Failed to capture fetch request body in debugger instrumentation",P);return}},K1=($,J,W,Q,Z,Y)=>{if($ instanceof Request)return Y.get($)??O0($,J,W,Q,Z);return O0($,J,W,Q,Z)},M0=($,J,W,Q)=>{let[Z,Y]=$,j=Y1(Z,Y),K=j1(Z),P=h(K,J);if(!P)return null;let G=null;if(Y?.headers)try{G=new Headers(Y.headers)}catch(w){J.reportNonFatalError("Failed to normalize fetch headers in debugger instrumentation",w)}else if(Z instanceof Request)G=Z.headers;let X=G?A(G):Z instanceof Request?A(Z.headers):{},f=G?.get("content-type")??(Z instanceof Request?Z.headers.get("content-type")??"":""),H=K1(Z,Y,G,W,J,Q);return{method:j,normalizedUrl:g(P),requestHeaders:X,requestContentType:f,requestBodyPromise:H}},D0=($,J,W)=>{if(typeof window.Request!=="function")return;let Q=window.Request,Z=new Proxy(Q,{construct(Y,j,K){let[,P]=j,G=Reflect.construct(Y,j,K),X;if(P?.headers!==void 0)try{X=new Headers(P.headers)}catch(w){$.reportNonFatalError("Failed to normalize Request headers in debugger instrumentation",w),X=G.headers}else X=G.headers;let f=X.get("content-type")??"",H=P?.body!==void 0?c($,P.body,J,f):p($,f,"Failed to capture Request body text in debugger instrumentation",()=>{if(G.bodyUsed)return Promise.resolve("");return G.clone().text()});return W.set(G,H),G}});try{Object.assign(Z,Q)}catch(Y){$.reportNonFatalError("Failed to mirror Request constructor properties in debugger instrumentation",Y)}try{window.Request=Z}catch(Y){$.reportNonFatalError("Failed to patch Request constructor in debugger instrumentation",Y)}};var w1=($,J)=>{let W=$.headers.get("content-type")??"";if(!R(W)||$.bodyUsed)return{contentType:W,responseClone:null};try{return{contentType:W,responseClone:$.clone()}}catch(Q){return J.reportNonFatalError("Failed to clone fetch response body in debugger instrumentation",Q),{contentType:W,responseClone:null}}},C0=($,J,W,Q,Z)=>{let Y=A(Q.headers),{contentType:j,responseClone:K}=w1(Q,$);q($,async()=>{let P,G;try{P=await W.requestBodyPromise}catch(X){$.reportNonFatalError("Failed to resolve fetch request body in debugger instrumentation",X)}try{G=await p($,j,"Failed to capture fetch response body text in debugger instrumentation",()=>{if(!K)return Promise.resolve("");return K.text()})}catch(X){$.reportNonFatalError("Failed to capture fetch response body in debugger instrumentation",X)}J({method:W.method,url:W.normalizedUrl,status:Q.status,duration:Z,requestHeaders:W.requestHeaders,responseHeaders:Y,requestBody:M(P,W.requestContentType),responseBody:M(G,j)})})},B0=($,J,W,Q,Z,Y)=>{q($,async()=>{let j;try{j=await W.requestBodyPromise}catch(K){j=void 0}J({method:W.method,url:W.normalizedUrl,status:0,duration:Date.now()-Z,requestHeaders:W.requestHeaders,requestBody:M(j,W.requestContentType),responseBody:M(F(Y(Q),O),"")})})};var k0=($)=>{let{diagnostics:J,postNetwork:W,reporter:Q}=$,Z=N(Q),Y=new WeakMap,j=(w)=>{return w.bind(window)};if(D0(Q,Z,Y),typeof window.fetch!=="function"){J.setFetchHookState("failed");return}let K=j(window.fetch),P=K,G=!1,X=async(...w)=>{if(G)return K(...w);G=!0,J.recordFetchCall();let C=Date.now(),D=M0(w,Q,Z,Y);if(!D)try{return P(...w)}finally{G=!1}try{let U=await P(...w),B=Date.now()-C;return C0(Q,W,D,U,B),U}catch(U){throw J.recordFetchFailure(F(Z(U),300)),B0(Q,W,D,U,C,Z),U}finally{G=!1}};try{Object.assign(X,window.fetch)}catch(w){Q.reportNonFatalError("Failed to mirror fetch properties in debugger instrumentation",w)}let f=Object.getOwnPropertyDescriptor(window,"fetch");if(!f||f.configurable)try{Object.defineProperty(window,"fetch",{configurable:!0,enumerable:f?.enumerable??!0,get(){return X},set(w){if(typeof w!=="function")return;if(w===X)return;P=j(w)}}),J.setFetchHookState("accessor");return}catch(w){Q.reportNonFatalError("Failed to install fetch accessor in debugger instrumentation",w)}try{window.fetch=X,J.setFetchHookState("assignment")}catch(w){J.setFetchHookState("failed"),Q.reportNonFatalError("Failed to patch fetch in debugger instrumentation",w)}};var q0=($)=>{let{diagnostics:J,postNetwork:W,reporter:Q}=$,Z=N(Q),Y=new WeakMap,j=async(H)=>{let w=Y.get(H);if(!w)return null;let C=h(w.url,Q);if(!C)return null;let D=g(C),U,B,x=f0(H.getAllResponseHeaders()),x0=x["content-type"]??"";try{U=await w.requestBodyPromise}catch(a){U=void 0}try{if(H.responseType===""||H.responseType==="text")B=F(H.responseText||"",O);else if(H.responseType==="json")B=F(Z(H.response),O)}catch(a){Q.reportNonFatalError("Failed to capture XHR response body in debugger instrumentation",a)}return{method:w.method,url:D,status:H.status,duration:Date.now()-w.startedAt,requestHeaders:w.requestHeaders,responseHeaders:x,requestBody:M(U,w.requestHeaders["content-type"]??""),responseBody:M(B,x0)}},K=(H)=>{q(Q,async()=>{let w=await j(H);if(!w)return;W(w)})},G=XMLHttpRequest.prototype.open;XMLHttpRequest.prototype.open=function(H,w,C,D,U){let B=typeof H==="string"?H:"GET",x=typeof w==="string"?w:String(w??"");if(Y.set(this,{method:B,url:x,startedAt:Date.now(),requestBodyPromise:Promise.resolve(void 0),requestHeaders:{}}),typeof C==="boolean"||typeof D==="string"||D===null||typeof U==="string"||U===null)return G.call(this,H,w,C??!0,D,U);return G.call(this,H,w)};let X=XMLHttpRequest.prototype.setRequestHeader;XMLHttpRequest.prototype.setRequestHeader=function(...H){let[w,C]=H,D=Y.get(this);if(D){let U=w.trim().toLowerCase();if(!b(U))D.requestHeaders[U.slice(0,z)]=C.slice(0,_)}return X.apply(this,H)};let f=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.send=function(...H){J.recordXhrCall();let w=Y.get(this);if(w)w.startedAt=Date.now(),w.requestBodyPromise=c(Q,H[0],Z,w.requestHeaders["content-type"]??"");return this.addEventListener("loadend",()=>{K(this)},{once:!0}),f.apply(this,H)},J.setXhrHookInstalled()};function L0($){k0($),q0($)}function V0(){let $=window;if($[o])return;$[o]=!0;let J=H0(window),W=J.createReporter(w0()),{enqueueEvent:Q,flushEventQueue:Z}=F0({recordQueuedEvent:J.recordQueuedEvent,recordFlushedBatch:J.recordFlushedBatch}),Y=N(W),j=(X,f,H)=>{J.recordActionEvent(),Q({kind:"action",timestamp:Date.now(),actionType:X,target:f,metadata:H})},K=(X,f)=>{J.recordConsoleEvent();let H=[];for(let w of f)H.push(Y(w));Q({kind:"console",timestamp:Date.now(),level:X,message:F(H.join(" ")),metadata:{argumentCount:f.length}})},P=(X)=>{J.recordNetworkEvent(X.url),Q({kind:"network",timestamp:Date.now(),...X})};G0({postAction:j}),X0({reporter:W,postConsole:K});try{L0({diagnostics:J,reporter:W,postNetwork:P})}catch(X){W.reportNonFatalError("Failed to install network capture in debugger runtime",X)}let G=()=>{Z()};window.addEventListener("pagehide",G,{capture:!0}),document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="hidden")Z()},{capture:!0,passive:!0})}function R0($){if(!d($))return null;let J=$.kind;if(J!=="action"&&J!=="console"&&J!=="network")return null;let W=u($.timestamp);if(W===void 0)return null;if(J==="action"){let Y=L($.actionType);if(!Y)return null;return{kind:J,timestamp:W,actionType:Y,target:L($.target,I),metadata:N0($.metadata)}}if(J==="console"){let Y=$.level;if(Y!=="log"&&Y!=="info"&&Y!=="warn"&&Y!=="error"&&Y!=="debug")return null;let j=L($.message,I);if(!j)return null;return{kind:J,timestamp:W,level:Y,message:j,metadata:N0($.metadata)}}let Q=L($.method,20),Z=L($.url,e);if(!(Q&&Z))return null;return{kind:J,timestamp:W,method:Q,url:Z,status:u($.status),duration:u($.duration),requestHeaders:S0($.requestHeaders),responseHeaders:S0($.responseHeaders),requestBody:L($.requestBody,v),responseBody:L($.responseBody,v)}}function S0($){if(!d($))return;let J={};for(let[W,Q]of Object.entries($)){if(typeof Q!=="string")continue;let Z=W.trim().toLowerCase();if(!Z||G1(Z))continue;J[Z.slice(0,120)]=Q.slice(0,500)}return Object.keys(J).length>0?J:void 0}function G1($){return $.includes("debugger")}function N0($){if(!d($))return;let J={};for(let[W,Q]of Object.entries($)){let Z=n(Q);if(Z===void 0)continue;J[W.slice(0,120)]=Z}return Object.keys(J).length>0?J:void 0}function n($,J=0){if(J>3)return;if($===null||typeof $==="boolean"||typeof $==="number")return $;if(typeof $==="string")return $.slice(0,I);if(Array.isArray($))return $.slice(0,30).map((W)=>n(W,J+1)).filter(X1);if(d($)){let W={};for(let[Q,Z]of Object.entries($).slice(0,30)){let Y=n(Z,J+1);if(Y===void 0)continue;W[Q.slice(0,120)]=Y}return W}return}function L($,J=I){if(typeof $!=="string")return;let W=$.trim();if(!W)return;return W.slice(0,J)}function u($){if(typeof $!=="number"||!Number.isFinite($))return;return Math.floor($)}function d($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function X1($){return $!==null&&$!==void 0}function I0($){return $.actions.length>0||$.logs.length>0||$.networkRequests.length>0}function z0($){let J=$.recordingStartedAt??$.startedAt,W=[...$.events].sort((Z,Y)=>Z.timestamp-Y.timestamp),Q={actions:[],logs:[],networkRequests:[]};for(let Z of W){let Y=new Date(Z.timestamp).toISOString(),j=P1(Z.timestamp,J);if(Z.kind==="action"){Q.actions.push({type:Z.actionType,target:Z.target,timestamp:Y,offset:j,metadata:Z.metadata});continue}if(Z.kind==="console"){Q.logs.push({level:Z.level,message:Z.message,timestamp:Y,offset:j,metadata:Z.metadata});continue}Q.networkRequests.push({method:Z.method,url:Z.url,status:Z.status,duration:Z.duration,requestHeaders:Z.requestHeaders,responseHeaders:Z.responseHeaders,requestBody:Z.requestBody,responseBody:Z.responseBody,timestamp:Y,offset:j})}return Q}function P1($,J){let W=Math.floor($-J);return W>=0?W:null}class H1{installed=!1;recentEvents=[];session=null;handleWindowMessage=($)=>{if($.source!==window)return;let J=$.data;if(!b0(J)||J.source!==$0)return;let W=Array.isArray(J.events)?J.events:[J.event],Q=[];for(let Z of W){let Y=R0(Z);if(Y)Q.push(Y)}if(Q.length===0)return;for(let Z of Q)if(this.appendEvent(this.recentEvents,Z),this.session)this.appendEvent(this.session.events,Z);this.trimRecentEvents()};install(){if(this.installed||typeof window>"u")return;V0(),window.addEventListener("message",this.handleWindowMessage),this.installed=!0}dispose(){if(!this.installed||typeof window>"u")return;window.removeEventListener("message",this.handleWindowMessage),this.installed=!1}startSession($,J=0){let W=Date.now(),Q={sessionId:A0(),captureType:$,startedAt:W,recordingStartedAt:$==="screenshot"?W:null,events:[]};if(J>0){for(let Z of this.recentEvents)if(W-Z.timestamp<=J)this.appendEvent(Q.events,Z)}return this.session=Q,Q}markRecordingStarted($){if(!this.session)return;this.session.recordingStartedAt=Math.floor($)}clearSession(){this.session=null}finalizeSession(){if(!this.session)return{warnings:["Debugger session was not available. This report will not include debugger data."],debuggerSummary:{actions:0,logs:0,networkRequests:0}};let $=z0({sessionId:this.session.sessionId,captureTabId:0,captureType:this.session.captureType,startedAt:this.session.startedAt,recordingStartedAt:this.session.recordingStartedAt,events:this.session.events});this.clearSession();let J={actions:$.actions.length,logs:$.logs.length,networkRequests:$.networkRequests.length},W=[],Q=I0($);if(!Q)W.push("No debugger events were captured. Reproduce the issue before submitting if you need event or network traces.");else if(J.networkRequests===0)W.push("No network requests were captured. API-level debugging context may be incomplete.");return{warnings:W,debuggerSummary:J,debuggerPayload:Q?$:void 0}}trimRecentEvents(){let $=Date.now();if(this.recentEvents=this.recentEvents.filter((J)=>{return $-J.timestamp<=_0}),this.recentEvents.length>r)this.recentEvents=this.recentEvents.slice(-r)}appendEvent($,J){if(J.kind==="network"){W0($,J);return}if(J.kind==="action"){Z0($,J);return}m($,J)}}export{H1 as DebuggerCollector};
@@ -0,0 +1,18 @@
1
+ import type { CaptureInitOptions, CaptureRuntimeController, CaptureSubmissionDraft, CaptureSubmitResult } from "./types.js";
2
+ export { defaultSubmitTransport } from "./transport/default-submit-transport.js";
3
+ export type { CaptureDebuggerSummary, CaptureInitOptions, CapturePriority, CaptureReportVisibility, CaptureRuntimeConfig, CaptureRuntimeController, CaptureSubmissionDraft, CaptureSubmitRequest, CaptureSubmitResult, CaptureSubmitTransport, CaptureType, } from "./types.js";
4
+ export declare function init(options: CaptureInitOptions): CaptureRuntimeController;
5
+ export declare function mount(target?: HTMLElement): void;
6
+ export declare function unmount(): void;
7
+ export declare function open(): void;
8
+ export declare function close(): void;
9
+ export declare function destroy(): void;
10
+ export declare function startRecording(): Promise<{
11
+ startedAt: number;
12
+ }>;
13
+ export declare function stopRecording(): Promise<Blob | null>;
14
+ export declare function takeScreenshot(): Promise<Blob | null>;
15
+ export declare function submit(draft: CaptureSubmissionDraft): Promise<CaptureSubmitResult>;
16
+ export declare function reset(): void;
17
+ export declare function isInitialized(): boolean;
18
+ export declare function getConfig(): import("./types.js").CaptureRuntimeConfig | null;
@@ -0,0 +1,6 @@
1
+ import type { CaptureGlobalApi } from "./types.js";
2
+ declare global {
3
+ interface Window {
4
+ CrikketCapture?: CaptureGlobalApi;
5
+ }
6
+ }
@@ -0,0 +1,2 @@
1
+ async function $(n,i,w){let t;try{t=await fetch(n.url,{method:n.method,headers:{...n.headers,...w?.contentEncoding?{"content-encoding":w.contentEncoding}:void 0},body:i,mode:"cors"})}catch(c){throw Error("Direct upload to storage failed before the server responded. Check storage CORS and network access, then retry.",{cause:c})}if(!t.ok)throw Error(`Artifact upload failed with status ${t.status}.`)}async function W(n){if(!n)return null;let i=new Blob([JSON.stringify(n)],{type:"application/json"});if(typeof CompressionStream!=="function")return{blob:i,contentEncoding:void 0};let w=i.stream().pipeThrough(new CompressionStream("gzip"));return{blob:await new Response(w).blob(),contentEncoding:"gzip"}}var m=null;async function C(n){if(typeof window>"u"||typeof document>"u")throw Error("Anti-bot verification requires a browser environment.");let i=await V();return new Promise((w,t)=>{let c=document.createElement("div");c.style.position="fixed",c.style.right="16px",c.style.bottom="16px",c.style.zIndex="2147483647",document.body.append(c);let f=(x)=>{i.remove?.(x),c.remove()},r=i.render(c,{appearance:"interaction-only",callback:(x)=>{f(r),w(x)},execution:"execute","error-callback":()=>{f(r),t(Error("Anti-bot verification failed."))},"expired-callback":()=>{f(r),t(Error("Anti-bot verification expired. Please try again."))},sitekey:n});i.execute(r)})}function V(){if(window.turnstile)return Promise.resolve(window.turnstile);if(m)return m;let n=new Promise((i,w)=>{let t=document.querySelector('script[src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit"]');if(t){if(window.turnstile){i(window.turnstile);return}t.addEventListener("load",()=>{if(window.turnstile){i(window.turnstile);return}w(Error("Turnstile did not initialize."))}),t.addEventListener("error",()=>{w(Error("Failed to load anti-bot verification script."))});return}let c=document.createElement("script");c.async=!0,c.defer=!0,c.src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit",c.addEventListener("load",()=>{if(window.turnstile){i(window.turnstile);return}w(Error("Turnstile did not initialize."))}),c.addEventListener("error",()=>{w(Error("Failed to load anti-bot verification script."))}),document.head.append(c)}).finally(()=>{if(!window.turnstile)m=null});return m=n,n}var Y=/^https?:\/\//,g="/bug-reports",d="CAPTURE_CHALLENGE_REQUIRED",Q="This recording is too large to upload reliably. Retry with a shorter recording or a screenshot.";async function G(n){let i=Z(n),w=`${n.config.host}${O(n.config.submitPath)}`,t=`${n.config.host}${k(n.config.submitPath)}`,c=await j(n),f=await fetch(w,{method:"POST",headers:{...c?{"x-crikket-capture-token":c}:void 0,"content-type":"application/json","x-crikket-public-key":n.config.key},body:JSON.stringify(i),credentials:"omit",mode:"cors"}),r=await B(f);if(!f.ok)throw Error(J(r,f.status));let x=v(r);await $(x.captureUpload,n.report.media);let L=await W(n.report.debuggerPayload);if(x.debuggerUpload&&L)await $(x.debuggerUpload,L.blob,{contentEncoding:L.contentEncoding});let N=await fetch(t,{method:"POST",headers:{...x.finalizeToken?{"x-crikket-capture-finalize-token":x.finalizeToken}:void 0,"content-type":"application/json","x-crikket-public-key":n.config.key},body:JSON.stringify({id:x.bugReportId,captureContentType:n.report.media.type||(n.report.captureType==="screenshot"?"image/png":"video/webm"),captureSizeBytes:n.report.media.size,debuggerContentEncoding:L?.contentEncoding,debuggerSizeBytes:L?.blob.size}),credentials:"omit",mode:"cors"}),E=await B(N);if(!N.ok)throw Error(J(E,N.status));return{shareUrl:T(n.config.host,D(E,["shareUrl","url"])),reportId:D(E,["id","reportId"]),raw:E}}function Z(n){if(n.report.media.size>99614720)throw Error(Q);return{title:n.report.title,description:n.report.description,priority:n.report.priority,visibility:n.report.visibility,attachmentType:n.report.captureType,url:n.report.pageUrl,metadata:{durationMs:n.report.durationMs??void 0,pageTitle:n.report.pageTitle,submittedVia:"capture-sdk"},deviceInfo:n.report.deviceInfo,captureContentType:n.report.media.type||void 0,debuggerSummary:n.report.debuggerSummary,hasDebuggerPayload:Boolean(n.report.debuggerPayload)}}async function j(n){let i=`${n.config.host}${b(n.config.submitPath)}`,w;for(let t of[0,1]){let c=await fetch(i,{method:"POST",headers:{"content-type":"application/json","x-crikket-public-key":n.config.key},body:JSON.stringify(w?{turnstileToken:w}:{turnstileToken:void 0}),credentials:"omit",mode:"cors"});if(c.status===404||c.status===405||c.status===501)return;let f=await B(c);if(c.ok)return D(f,["token"]);let r=M(f);if(I(f)&&r?.provider==="turnstile"&&r.siteKey&&!w){w=await C(r.siteKey);continue}throw Error(J(f,c.status))}throw Error("Anti-bot verification could not be completed.")}async function B(n){if(!(n.headers.get("content-type")??"").includes("application/json"))return;try{return await n.json()}catch{return}}function J(n,i){if(!o(n))return`Capture submission failed with status ${i}.`;return D(n,["message","error"])??`Capture submission failed with status ${i}.`}function I(n){return o(n)&&n.code===d}function M(n){if(!o(n))return;let i=n.challenge;if(!o(i))return;return{provider:typeof i.provider==="string"?i.provider:void 0,siteKey:typeof i.siteKey==="string"?i.siteKey:void 0}}function D(n,i){if(!o(n))return;for(let t of i){let c=n[t];if(typeof c==="string"&&c.trim().length>0)return c}let w=n.report;if(!o(w))return;for(let t of i){let c=w[t];if(typeof c==="string"&&c.trim().length>0)return c}return}function T(n,i){if(!i)return;if(Y.test(i))return i;return`${n}${i.startsWith("/")?i:`/${i}`}`}function b(n){let i=n.endsWith("/")?n.slice(0,-1):n;if(i.endsWith(g))return`${i.slice(0,-g.length)}/capture-token`;return`${i}/token`}function O(n){let i=n.endsWith("/")?n.slice(0,-1):n;if(i.endsWith(g))return`${i.slice(0,-g.length)}/bug-report-upload-session`;return`${i}/upload-session`}function k(n){let i=n.endsWith("/")?n.slice(0,-1):n;if(i.endsWith(g))return`${i.slice(0,-g.length)}/bug-report-finalize`;return`${i}/finalize`}function o(n){return typeof n==="object"&&n!==null&&!Array.isArray(n)}function v(n){if(!o(n))throw Error("Capture upload session response was invalid.");let i=typeof n.bugReportId==="string"?n.bugReportId:void 0;if(!i)throw Error("Capture upload session response was missing bugReportId.");return{bugReportId:i,captureUpload:K(n.captureUpload),debuggerUpload:n.debuggerUpload?K(n.debuggerUpload):void 0,finalizeToken:typeof n.finalizeToken==="string"?n.finalizeToken:void 0}}function K(n){if(!o(n)||n.method!=="PUT"||typeof n.url!=="string")throw Error("Capture upload target response was invalid.");let i=o(n.headers)?Object.fromEntries(Object.entries(n.headers).filter((w)=>{return typeof w[1]==="string"})):{};return{url:n.url,method:"PUT",headers:i}}
2
+ export{G};
@@ -0,0 +1,2 @@
1
+ var g=Object.create;var{getPrototypeOf:h,defineProperty:f,getOwnPropertyNames:i}=Object;var j=Object.prototype.hasOwnProperty;var k=(a,c,b)=>{b=a!=null?g(h(a)):{};let d=c||!a||!a.__esModule?f(b,"default",{value:a,enumerable:!0}):b;for(let e of i(a))if(!j.call(d,e))f(d,e,{get:()=>a[e],enumerable:!0});return d};var l=((a)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(a,{get:(c,b)=>(typeof require<"u"?require:c)[b]}):a)(function(a){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+a+'" is not supported')});
2
+ export{k as W,l as X};
@@ -0,0 +1,2 @@
1
+ var e={public:"public",private:"private"};
2
+ export{e as V};
@@ -0,0 +1,2 @@
1
+ var e="https://api.crikket.io",n="/api/embed/bug-reports",o=2147483640,f=60000,u=250,c=1e4,i=/\/+$/;function g(t){let r=t.trim();if(!r)throw Error("@crikket-io/capture requires a non-empty key in capture.init({ key })");return r}function m(t){if(typeof t!=="string"||t.trim().length===0)return e;return t.trim().replace(i,"")}function l(t){if(typeof t!=="string"||t.trim().length===0)return n;let r=t.trim();return r.startsWith("/")?r:`/${r}`}function E(t){if(typeof t!=="number"||!Number.isFinite(t))return o;return Math.max(1,Math.floor(t))}function _(t){if(typeof t!=="object"||t===null||Array.isArray(t))return!1;return typeof t.source==="string"}function y(){if(typeof crypto<"u"&&typeof crypto.randomUUID==="function")return crypto.randomUUID();return`sdk_${Date.now()}_${Math.random().toString(36).slice(2,10)}`}function x(t){if(t instanceof Error&&t.message.trim().length>0){if(t.message.includes("Failed to fetch")||t.message.includes("Direct upload to storage failed"))return"Direct upload to storage failed. Check storage CORS or network access, then retry.";return t.message}return"Capture action failed. Please try again."}function S(){if(typeof location>"u")return"";return location.href}function T(){if(typeof document>"u")return"";return document.title.trim().slice(0,300)}function h(){if(typeof navigator>"u"||typeof window>"u")return{};return{browser:navigator.userAgent||void 0,os:navigator.platform||void 0,viewport:`${window.innerWidth}x${window.innerHeight}`}}function A(t){let r=Math.max(0,Math.floor(t/1000)),s=Math.floor(r/60),a=r%60;return`${s.toString().padStart(2,"0")}:${a.toString().padStart(2,"0")}`}
2
+ export{f as H,u as I,c as J,g as K,m as L,l as M,E as N,_ as O,y as P,x as Q,S as R,T as S,h as T,A as U};
@@ -0,0 +1,2 @@
1
+ function s(){return{frameRate:30,displaySurface:"browser"}}function i(e){return{video:s(),audio:e,monitorTypeSurfaces:"exclude",preferCurrentTab:!0,selfBrowserSurface:"include",surfaceSwitching:"exclude",systemAudio:e?"include":"exclude"}}async function p(e){if(!navigator.mediaDevices?.getDisplayMedia)throw Error("This browser does not support screen capture.");try{return await navigator.mediaDevices.getDisplayMedia(i(e))}catch(r){if(!e)throw r;return navigator.mediaDevices.getDisplayMedia(i(!1))}}function f(e){if(e.getVideoTracks()[0]?.getSettings().displaySurface==="browser")return;for(let o of e.getTracks())o.stop();throw Error("Please choose the current browser tab. Window and full-screen capture are not supported in the web SDK.")}async function w(e,r){e.srcObject=r,e.muted=!0,e.playsInline=!0,await c(r.getVideoTracks()[0]),await d(e),await e.play(),await u(e)}function T(e){e.pause(),e.srcObject=null}function E(){if(typeof MediaRecorder>"u")throw Error("This browser does not support video recording.");let e=["video/webm;codecs=vp9,opus","video/webm;codecs=vp8,opus","video/webm"];for(let r of e)if(MediaRecorder.isTypeSupported(r))return r;return""}function S(e,r){return new Promise((t,o)=>{e.toBlob((a)=>{if(!a){o(Error("Failed to generate captured image."));return}t(a)},r)})}function d(e){return new Promise((r,t)=>{let o=()=>{n(),r()},a=()=>{n(),t(Error("Failed to read captured video metadata."))},n=()=>{e.removeEventListener("loadedmetadata",o),e.removeEventListener("error",a)};e.addEventListener("loadedmetadata",o,{once:!0}),e.addEventListener("error",a,{once:!0})})}function c(e){if(!e)throw Error("No video track available for capture.");if(!e.muted)return Promise.resolve();return new Promise((r)=>{let t=window.setTimeout(()=>{a(),r()},1000),o=()=>{a(),r()},a=()=>{window.clearTimeout(t),e.removeEventListener("unmute",o)};e.addEventListener("unmute",o,{once:!0})})}async function u(e,r=2){for(let t=0;t<r;t+=1)await l(e);await m(120)}function l(e){if("requestVideoFrameCallback"in e)return new Promise((r)=>{e.requestVideoFrameCallback(()=>{r()})});return new Promise((r)=>{requestAnimationFrame(()=>{r()})})}function m(e){return new Promise((r)=>{window.setTimeout(r,e)})}
2
+ export{p as n,f as o,w as p,T as q,E as r,S as s};
@@ -0,0 +1,2 @@
1
+ function o(...t){return t.filter(Boolean).join(" ")}import{jsx as c}from"react/jsx-runtime";function S(t){let a=t.variant??"primary",i=t.size??"default";return c("button",{...t,className:o("inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/60 disabled:cursor-not-allowed disabled:opacity-50",i==="sm"&&"h-8 px-3 text-xs",i==="default"&&"h-9 px-4 text-sm",i==="icon"&&"h-9 w-9 px-0 text-sm",a==="primary"&&"bg-foreground text-background hover:opacity-90",a==="outline"&&"border border-input bg-transparent text-foreground hover:bg-muted/80",a==="secondary"&&"bg-muted text-foreground",t.className),type:t.type??"button",children:t.children})}import{jsx as l}from"react/jsx-runtime";function g(t){return l("input",{...t,className:o("h-9 w-full rounded-md border border-input bg-transparent px-3 text-sm shadow-xs outline-none transition-[border-color,box-shadow] focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/60 disabled:cursor-not-allowed disabled:opacity-50",t.className)})}import{jsx as u}from"react/jsx-runtime";function V(t){return u("label",{...t,className:o("font-medium text-sm leading-none",t.className),children:t.children})}import{jsx as e,jsxs as r}from"react/jsx-runtime";function n(t){return e("svg",{"aria-hidden":"true",fill:"none",height:"1em",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"1.75",viewBox:"0 0 24 24",width:"1em",...t})}function G(t){return r(n,{...t,children:[e("path",{d:"M4 20h4l10.5-10.5a2.1 2.1 0 0 0-3-3L5 17v3Z"}),e("path",{d:"m13.5 6.5 4 4"})]})}function E(t){return r(n,{...t,children:[e("path",{d:"M6 16.5 14.5 8a2.1 2.1 0 1 1 3 3L9 19.5H6v-3Z"}),e("path",{d:"M4 20h16"})]})}function y(t){return e(n,{...t,children:e("rect",{height:"12",rx:"2",width:"16",x:"4",y:"6"})})}function M(t){return r(n,{...t,children:[e("path",{d:"m10 8-5 4 5 4"}),e("path",{d:"M6 12h8a4 4 0 1 1 0 8h-1"})]})}function P(t){return r(n,{...t,children:[e("path",{d:"M12 5a7 7 0 1 1-6.2 3.8"}),e("path",{d:"M4 4v5h5"})]})}function L(t){return r(n,{...t,children:[e("rect",{height:"12",rx:"2",width:"10",x:"9",y:"9"}),e("path",{d:"M7 15H6a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v1"})]})}function w(t){return e(n,{...t,children:e("path",{d:"m5 12 4.2 4.2L19 6.5"})})}function J(t){return r(n,{...t,children:[e("path",{d:"M14 5h5v5"}),e("path",{d:"M10 14 19 5"}),e("path",{d:"M19 13v4a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h4"})]})}var H={none:"none",low:"low",medium:"medium",high:"high",critical:"critical"};
2
+ export{o as t,S as u,G as v,E as w,y as x,M as y,P as z,L as A,w as B,J as C,g as D,V as E,H as F};
@@ -0,0 +1,18 @@
1
+ import type { CaptureInitOptions, CaptureRuntimeController, CaptureSubmissionDraft, CaptureSubmitResult } from "./types.js";
2
+ export { defaultSubmitTransport } from "./transport/default-submit-transport.js";
3
+ export type { CaptureDebuggerSummary, CaptureInitOptions, CapturePriority, CaptureReportVisibility, CaptureRuntimeConfig, CaptureRuntimeController, CaptureSubmissionDraft, CaptureSubmitRequest, CaptureSubmitResult, CaptureSubmitTransport, CaptureType, } from "./types.js";
4
+ export declare function init(options: CaptureInitOptions): CaptureRuntimeController;
5
+ export declare function mount(target?: HTMLElement): void;
6
+ export declare function unmount(): void;
7
+ export declare function open(): void;
8
+ export declare function close(): void;
9
+ export declare function destroy(): void;
10
+ export declare function startRecording(): Promise<{
11
+ startedAt: number;
12
+ }>;
13
+ export declare function stopRecording(): Promise<Blob | null>;
14
+ export declare function takeScreenshot(): Promise<Blob | null>;
15
+ export declare function submit(draft: CaptureSubmissionDraft): Promise<CaptureSubmitResult>;
16
+ export declare function reset(): void;
17
+ export declare function isInitialized(): boolean;
18
+ export declare function getConfig(): import("./types.js").CaptureRuntimeConfig | null;
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import{A,B,C as J,D as X,E as K,F as ae,t as h,u as s}from"./index-shtqtrh3.js";import{G as He}from"./index-0avnsp70.js";import{J as H,K as w,L as k,M as p,N as L,Q as v,U as ne}from"./index-ehy0ec5e.js";import{V as T}from"./index-97c5xshv.js";import{W as C,X as b}from"./index-331vjad4.js";function z(e,t){let r=document.createElement("div"),o=r.attachShadow({mode:"open"}),a=document.createElement("style");a.textContent=":host {\n all: initial;\n}\n\n.capture-launcher {\n position: fixed;\n right: 24px;\n bottom: 24px;\n z-index: var(--capture-z-index);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 36px;\n padding: 0 16px;\n border: 0;\n border-radius: 9999px;\n background: #111827;\n color: #ffffff;\n font:\n 500 14px / 1.2 Inter Variable,\n Inter,\n ui-sans-serif,\n system-ui,\n sans-serif;\n box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);\n cursor: pointer;\n transition: opacity 150ms ease;\n}\n\n.capture-launcher:hover {\n opacity: 0.92;\n}\n\n.capture-launcher:focus-visible {\n outline: 2px solid rgb(17 24 39 / 0.45);\n outline-offset: 2px;\n}\n\n.capture-launcher:disabled {\n opacity: 0.7;\n cursor: progress;\n}\n";let n=document.createElement("button");return n.className="capture-launcher",n.style.setProperty("--capture-z-index",String(t.zIndex)),n.type="button",n.textContent="Report Issue",n.setAttribute("aria-label","Report an issue"),n.addEventListener("click",t.onOpen),n.addEventListener("pointerenter",t.onPrefetch,{once:!0,passive:!0}),n.addEventListener("focus",t.onPrefetch,{once:!0,passive:!0}),o.append(a,n),e.append(r),{setLoading:(l)=>{n.disabled=l,n.textContent=l?"Loading...":"Report Issue"},unmount:()=>{n.removeEventListener("click",t.onOpen),r.remove()}}}class P{collector=null;collectorPromise=null;async startScreenshotSession(){(await this.ensureCollector()).startSession("screenshot",H)}async startRecordingSession(){(await this.ensureCollector()).startSession("video")}markRecordingStarted(e){this.collector?.markRecordingStarted(e)}finalizeSession(){return this.collector?.finalizeSession()??ce()}clearSession(){this.collector?.clearSession()}dispose(){this.collectorPromise=null,this.collector?.dispose(),this.collector=null}ensureCollector(){if(this.collector)return Promise.resolve(this.collector);if(this.collectorPromise)return this.collectorPromise;let e=import("./debugger-collector-f0etqtvj.js").then(({DebuggerCollector:t})=>{let r=new t;return r.install(),this.collector=r,r}).finally(()=>{if(this.collectorPromise===e)this.collectorPromise=null});return this.collectorPromise=e,e}}function ce(){return{warnings:["Debugger session was not available. This report will not include debugger data."],debuggerSummary:{actions:0,logs:0,networkRequests:0}}}async function O(){return(await import("./capture-screenshot-b3snwyge.js")).captureScreenshot()}async function D(){return(await import("./start-display-recording-cve3f1me.js")).startDisplayRecording()}import{createRoot as Te}from"react-dom/client";import{useSyncExternalStore as Ee}from"react";import{lazy as me,Suspense as de}from"react";import{jsx as N,jsxs as I}from"react/jsx-runtime";function x(e){return I("section",{className:"grid gap-4 p-5",children:[N("p",{className:"m-0 text-muted-foreground text-sm",children:"Choose how to capture the issue."}),I("div",{className:"grid grid-cols-2 gap-2",children:[N(s,{className:"w-full",disabled:e.busy,onClick:e.onStartVideo,type:"button",children:"Record Video"}),N(s,{className:"w-full",disabled:e.busy,onClick:e.onTakeScreenshot,type:"button",variant:"outline",children:"Take Screenshot"})]})]})}import{jsx as c,jsxs as g}from"react/jsx-runtime";function V(e){let t=e.state.copyLabel==="Copied";return g("section",{className:"grid gap-5 p-5",children:[g("div",{className:"grid gap-1 text-center",children:[c("strong",{className:"text-green-700 text-xl",children:"Bug report submitted"}),c("p",{className:"m-0 text-muted-foreground text-sm",children:"Your bug report has been created successfully."})]}),g("div",{className:"grid gap-2",children:[c(K,{children:"Share URL"}),g("div",{className:"flex flex-col gap-2 sm:flex-row",children:[c(X,{className:"flex-1",readOnly:!0,type:"text",value:e.state.shareUrl}),c(s,{"aria-label":t?"Copied":"Copy link",className:"shrink-0",disabled:e.state.busy,onClick:e.handlers.onCopyLink,size:"icon",type:"button",variant:"outline",children:t?c(B,{className:"h-4 w-4"}):c(A,{className:"h-4 w-4"})})]})]}),g("div",{className:"grid gap-2 sm:grid-cols-2",children:[g(s,{className:"w-full gap-2",disabled:e.state.busy,onClick:e.handlers.onOpenLink,type:"button",variant:"outline",children:[c(J,{className:"h-4 w-4"}),"Open Link"]}),c(s,{className:"w-full gap-2",disabled:e.state.busy,onClick:e.handlers.onRetry,type:"button",children:"Capture Another"})]})]})}import{jsx as d,jsxs as fe}from"react/jsx-runtime";var he=me(async()=>{return{default:(await import("./review-form-section-frr1x0zk.js")).ReviewFormSection}});function _(e){if(e.state.view==="chooser")return d(x,{busy:e.isBusy,onStartVideo:e.handlers.onStartVideo,onTakeScreenshot:e.handlers.onTakeScreenshot});if(e.state.view==="review")return d(de,{fallback:d(ge,{}),children:d(he,{formKey:e.state.reviewFormKey,isSubmitting:e.isSubmitPending,onCancel:e.handlers.onCancel,onSubmit:e.handlers.onSubmit,state:e.state})});if(e.state.view==="success")return d(V,{handlers:e.handlers,state:e.state});return null}function ge(){return fe("section",{className:"grid gap-2 px-5 py-8 text-muted-foreground text-sm",children:[d("p",{children:"Preparing review form..."}),d("p",{className:"text-xs",children:"Your capture is ready. Loading report details."})]})}import{jsx as Ce}from"react/jsx-runtime";function q(e){return Ce("button",{"aria-label":"Report an issue",className:"capture-launcher",disabled:e.disabled,onClick:e.onClick,style:{["--capture-z-index"]:String(e.zIndex)},type:"button",children:"Report Issue"})}import{jsx as S}from"react/jsx-runtime";function F(e){return S("div",{...e,className:h("rounded-xl border border-border/80 bg-card text-card-foreground shadow-2xl",e.className),children:e.children})}function Q(e){return S("div",{...e,className:h("border-b px-5 py-4",e.className),children:e.children})}function W(e){return S("div",{...e,className:e.className,children:e.children})}function Z(e){return S("h2",{className:h("font-semibold text-lg",e.className),children:e.children})}function $(e){return S("p",{className:h("m-0 text-muted-foreground text-sm",e.className),children:e.children})}import{jsx as be}from"react/jsx-runtime";function G(e){return be("span",{className:h("inline-flex items-center rounded-full bg-muted px-2 py-0.5 font-medium text-[11px] text-foreground",e.className),children:e.children})}import{jsx as R,jsxs as Se}from"react/jsx-runtime";function Y(e){return Se("div",{className:"fixed right-6 bottom-[76px] z-[var(--capture-z-index)] flex items-center gap-2 rounded-full border bg-card px-3 py-2 text-card-foreground shadow-2xl",style:{["--capture-z-index"]:String(e.zIndex+2)},children:[R("span",{"aria-hidden":"true",className:"size-2 rounded-full bg-foreground"}),R(G,{variant:"secondary",children:"Recording"}),R("span",{className:"min-w-11 text-right font-mono text-muted-foreground text-xs",children:e.recordingTime}),R(s,{disabled:e.busy,onClick:e.onStopRecording,size:"sm",type:"button",children:"Stop"})]})}function j(e){if(e==="chooser")return"Choose how to capture";if(e==="review")return"Review and submit";if(e==="success")return"Submission complete";return"Capture issue details"}import{jsx as m,jsxs as y}from"react/jsx-runtime";function ee(e){let t=e.state.busy||e.isSubmitPending,r=e.state.view==="review";return y("div",{className:"crikket-capture-root",children:[m(q,{disabled:t,onClick:e.handlers.onLauncherClick,zIndex:e.zIndex}),e.state.overlayOpen?m("div",{className:"fixed inset-0 z-[var(--capture-overlay-z-index)] grid overflow-y-auto bg-black/60 p-4",style:{["--capture-overlay-z-index"]:String(e.zIndex+1)},children:y(F,{className:r?"m-auto flex h-[min(820px,calc(100dvh-2rem))] w-full max-w-[1120px] flex-col overflow-hidden border-border/80 bg-card text-card-foreground shadow-2xl":"m-auto flex max-h-[calc(100dvh-2rem)] w-full max-w-[560px] flex-col overflow-hidden border-border/80 bg-card text-card-foreground shadow-2xl",role:"dialog",children:[y(Q,{className:"flex flex-row items-start justify-between gap-3 border-b",children:[y("div",{className:"grid gap-1",children:[m(Z,{children:"Crikket Capture"}),m($,{children:j(e.state.view)})]}),m(s,{disabled:t,onClick:e.handlers.onClose,type:"button",variant:"outline",children:"Close"})]}),e.state.errorMessage?m("p",{className:"mx-5 mt-5 rounded-md border bg-muted px-3 py-2 text-sm",role:"alert",children:e.state.errorMessage}):null,m(W,{className:r?"min-h-0 flex-1 overflow-hidden px-0 pb-0":"min-h-0 overflow-y-auto px-0 pb-0",children:m(_,{handlers:e.handlers,isBusy:t,isSubmitPending:e.isSubmitPending,state:e.state})})]})}):null,e.state.recordingDockOpen?m(Y,{busy:t,onStopRecording:e.handlers.onStopRecording,recordingTime:e.recordingTime,zIndex:e.zIndex}):null]})}import{useEffect as Re,useRef as ye,useState as ve}from"react";var we=1500;function te(e){let t=ye(null),[r,o]=ve(!1);Re(()=>{return()=>{if(t.current!==null)window.clearTimeout(t.current)}},[]);let a=async(i)=>{e.store.patchState({busy:!0,errorMessage:null});try{await i()}finally{e.store.patchState({busy:!1})}},n=(i)=>{a(i).catch(()=>{return})},l=(i)=>{e.store.openChooser(),e.store.showError(v(i))};return{isSubmitPending:r,handlers:{onLauncherClick:()=>{e.callbacks.onReset(),e.store.openChooser()},onClose:()=>{e.callbacks.onClose()},onStartVideo:()=>{n(async()=>{try{let i=await e.callbacks.onStartVideo();e.store.showRecording(i.startedAt)}catch(i){l(i)}})},onTakeScreenshot:()=>{n(async()=>{try{await e.callbacks.onTakeScreenshot()}catch(i){l(i)}})},onStopRecording:()=>{n(async()=>{try{await e.callbacks.onStopRecording()}catch(i){l(i)}})},onSubmit:(i,f)=>{return o(!0),e.store.patchState({errorMessage:null,reviewDraft:i}),e.callbacks.onSubmit(i,f).catch((E)=>{e.store.showError(v(E))}).finally(()=>{o(!1)})},onCancel:()=>{e.callbacks.onReset(),e.store.openChooser()},onRetry:()=>{e.callbacks.onReset(),e.store.openChooser()},onCopyLink:()=>{if(!e.shareUrl.trim())return;navigator.clipboard.writeText(e.shareUrl).then(()=>{if(e.store.patchState({copyLabel:"Copied"}),t.current!==null)window.clearTimeout(t.current);t.current=window.setTimeout(()=>{e.store.patchState({copyLabel:"Copy Link"})},we)}).catch((i)=>{e.store.showError(v(i))})},onOpenLink:()=>{if(!e.shareUrl.trim())return;window.open(e.shareUrl,"_blank","noopener")}}}}import{useEffect as ke,useState as pe}from"react";var Le=250;function re(e){let[t,r]=pe(()=>Date.now());if(ke(()=>{if(!(e.recordingDockOpen&&e.recordingStartedAt))return;r(Date.now());let o=window.setInterval(()=>{r(Date.now())},Le);return()=>{window.clearInterval(o)}},[e.recordingDockOpen,e.recordingStartedAt]),e.recordingStartedAt===null)return"00:00";return ne(t-e.recordingStartedAt)}import{jsx as Pe}from"react/jsx-runtime";function oe(e){let t=Ee(e.store.subscribe,e.store.getSnapshot,e.store.getSnapshot),{handlers:r,isSubmitPending:o}=te({callbacks:e.callbacks,shareUrl:t.shareUrl,store:e.store}),a=re({recordingDockOpen:t.recordingDockOpen,recordingStartedAt:t.recordingStartedAt});return Pe(ee,{handlers:r,isSubmitPending:o,recordingTime:a,state:t,zIndex:e.zIndex})}var ue=ae.none,Ne={actions:0,logs:0,networkRequests:0};function se(){let e=ie(),t=new Set,r=()=>{for(let n of t)n()},o=(n)=>{e={...e,...n},r()};return{getSnapshot:()=>e,subscribe:(n)=>{return t.add(n),()=>{t.delete(n)}},patchState:o,openChooser:()=>{o({overlayOpen:!0,recordingDockOpen:!1,recordingStartedAt:null,view:"chooser",errorMessage:null,busy:!1})},close:()=>{o({overlayOpen:!1,recordingDockOpen:!1,recordingStartedAt:null,busy:!1,errorMessage:null})},showRecording:(n)=>{o({overlayOpen:!1,recordingDockOpen:!0,recordingStartedAt:n,view:"recording",errorMessage:null,busy:!1})},showReview:(n)=>{o({overlayOpen:!0,recordingDockOpen:!1,recordingStartedAt:null,view:"review",errorMessage:null,busy:!1,media:n.media,warnings:[...n.warnings],summary:n.summary,shareUrl:"",copyLabel:"Copy Link",reviewDraft:{title:"",description:"",priority:ue,visibility:T.private},reviewFormKey:n.media.objectUrl})},showSuccess:(n)=>{o({overlayOpen:!0,recordingDockOpen:!1,recordingStartedAt:null,view:"success",errorMessage:null,busy:!1,shareUrl:n??"",copyLabel:"Copy Link"})},showError:(n)=>{o({errorMessage:n})},setTitleIfEmpty:(n)=>{if(e.reviewDraft.title.trim().length>0)return;o({reviewDraft:{...e.reviewDraft,title:n.slice(0,200)}})},destroy:()=>{e=ie(),t.clear()}}}function ie(){return{view:"chooser",overlayOpen:!1,recordingDockOpen:!1,busy:!1,errorMessage:null,recordingStartedAt:null,warnings:[],summary:{...Ne},media:null,shareUrl:"",copyLabel:"Copy Link",reviewDraft:{title:"",description:"",priority:ue,visibility:T.private},reviewFormKey:""}}import{jsx as Me}from"react/jsx-runtime";var Ue="/*! tailwindcss v4.2.0 | MIT License | https://tailwindcss.com */\n@layer properties;\n@layer theme, base, components, utilities;\n@layer theme {\n :root, :host {\n --font-sans: \"Inter Variable\", sans-serif;\n --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\",\n \"Courier New\", monospace;\n --color-green-700: oklch(52.7% 0.154 150.069);\n --color-black: #000;\n --color-white: #fff;\n --spacing: 0.25rem;\n --text-xs: 0.75rem;\n --text-xs--line-height: calc(1 / 0.75);\n --text-sm: 0.875rem;\n --text-sm--line-height: calc(1.25 / 0.875);\n --text-lg: 1.125rem;\n --text-lg--line-height: calc(1.75 / 1.125);\n --text-xl: 1.25rem;\n --text-xl--line-height: calc(1.75 / 1.25);\n --font-weight-medium: 500;\n --font-weight-semibold: 600;\n --aspect-video: 16 / 9;\n --default-transition-duration: 150ms;\n --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n --default-font-family: \"Inter Variable\", sans-serif;\n --default-mono-font-family: var(--font-mono);\n }\n}\n@layer base {\n *, ::after, ::before, ::backdrop, ::file-selector-button {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0 solid;\n }\n html, :host {\n line-height: 1.5;\n -webkit-text-size-adjust: 100%;\n tab-size: 4;\n font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\");\n font-feature-settings: var(--default-font-feature-settings, normal);\n font-variation-settings: var(--default-font-variation-settings, normal);\n -webkit-tap-highlight-color: transparent;\n }\n hr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n }\n abbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n }\n h1, h2, h3, h4, h5, h6 {\n font-size: inherit;\n font-weight: inherit;\n }\n a {\n color: inherit;\n -webkit-text-decoration: inherit;\n text-decoration: inherit;\n }\n b, strong {\n font-weight: bolder;\n }\n code, kbd, samp, pre {\n font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);\n font-feature-settings: var(--default-mono-font-feature-settings, normal);\n font-variation-settings: var(--default-mono-font-variation-settings, normal);\n font-size: 1em;\n }\n small {\n font-size: 80%;\n }\n sub, sup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n }\n sub {\n bottom: -0.25em;\n }\n sup {\n top: -0.5em;\n }\n table {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n }\n :-moz-focusring {\n outline: auto;\n }\n progress {\n vertical-align: baseline;\n }\n summary {\n display: list-item;\n }\n ol, ul, menu {\n list-style: none;\n }\n img, svg, video, canvas, audio, iframe, embed, object {\n display: block;\n vertical-align: middle;\n }\n img, video {\n max-width: 100%;\n height: auto;\n }\n button, input, select, optgroup, textarea, ::file-selector-button {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n border-radius: 0;\n background-color: transparent;\n opacity: 1;\n }\n :where(select:is([multiple], [size])) optgroup {\n font-weight: bolder;\n }\n :where(select:is([multiple], [size])) optgroup option {\n padding-inline-start: 20px;\n }\n ::file-selector-button {\n margin-inline-end: 4px;\n }\n ::placeholder {\n opacity: 1;\n }\n @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {\n ::placeholder {\n color: currentcolor;\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, currentcolor 50%, transparent);\n }\n }\n }\n textarea {\n resize: vertical;\n }\n ::-webkit-search-decoration {\n -webkit-appearance: none;\n }\n ::-webkit-date-and-time-value {\n min-height: 1lh;\n text-align: inherit;\n }\n ::-webkit-datetime-edit {\n display: inline-flex;\n }\n ::-webkit-datetime-edit-fields-wrapper {\n padding: 0;\n }\n ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {\n padding-block: 0;\n }\n ::-webkit-calendar-picker-indicator {\n line-height: 1;\n }\n :-moz-ui-invalid {\n box-shadow: none;\n }\n button, input:where([type=\"button\"], [type=\"reset\"], [type=\"submit\"]), ::file-selector-button {\n appearance: button;\n }\n ::-webkit-inner-spin-button, ::-webkit-outer-spin-button {\n height: auto;\n }\n [hidden]:where(:not([hidden=\"until-found\"])) {\n display: none !important;\n }\n}\n@layer utilities {\n .fixed {\n position: fixed;\n }\n .inset-0 {\n inset: calc(var(--spacing) * 0);\n }\n .right-6 {\n right: calc(var(--spacing) * 6);\n }\n .bottom-\\[76px\\] {\n bottom: 76px;\n }\n .z-\\[var\\(--capture-overlay-z-index\\)\\] {\n z-index: var(--capture-overlay-z-index);\n }\n .z-\\[var\\(--capture-z-index\\)\\] {\n z-index: var(--capture-z-index);\n }\n .container {\n width: 100%;\n @media (width >= 40rem) {\n max-width: 40rem;\n }\n @media (width >= 48rem) {\n max-width: 48rem;\n }\n @media (width >= 64rem) {\n max-width: 64rem;\n }\n @media (width >= 80rem) {\n max-width: 80rem;\n }\n @media (width >= 96rem) {\n max-width: 96rem;\n }\n }\n .m-0 {\n margin: calc(var(--spacing) * 0);\n }\n .m-auto {\n margin: auto;\n }\n .mx-5 {\n margin-inline: calc(var(--spacing) * 5);\n }\n .mt-5 {\n margin-top: calc(var(--spacing) * 5);\n }\n .ml-auto {\n margin-left: auto;\n }\n .block {\n display: block;\n }\n .flex {\n display: flex;\n }\n .grid {\n display: grid;\n }\n .hidden {\n display: none;\n }\n .inline-flex {\n display: inline-flex;\n }\n .aspect-video {\n aspect-ratio: var(--aspect-video);\n }\n .size-2 {\n width: calc(var(--spacing) * 2);\n height: calc(var(--spacing) * 2);\n }\n .h-4 {\n height: calc(var(--spacing) * 4);\n }\n .h-5 {\n height: calc(var(--spacing) * 5);\n }\n .h-8 {\n height: calc(var(--spacing) * 8);\n }\n .h-9 {\n height: calc(var(--spacing) * 9);\n }\n .h-\\[min\\(820px\\,calc\\(100dvh-2rem\\)\\)\\] {\n height: min(820px, calc(100dvh - 2rem));\n }\n .h-full {\n height: 100%;\n }\n .max-h-\\[calc\\(100dvh-2rem\\)\\] {\n max-height: calc(100dvh - 2rem);\n }\n .max-h-full {\n max-height: 100%;\n }\n .min-h-0 {\n min-height: calc(var(--spacing) * 0);\n }\n .min-h-24 {\n min-height: calc(var(--spacing) * 24);\n }\n .min-h-32 {\n min-height: calc(var(--spacing) * 32);\n }\n .min-h-\\[320px\\] {\n min-height: 320px;\n }\n .min-h-full {\n min-height: 100%;\n }\n .w-4 {\n width: calc(var(--spacing) * 4);\n }\n .w-5 {\n width: calc(var(--spacing) * 5);\n }\n .w-9 {\n width: calc(var(--spacing) * 9);\n }\n .w-full {\n width: 100%;\n }\n .max-w-\\[560px\\] {\n max-width: 560px;\n }\n .max-w-\\[960px\\] {\n max-width: 960px;\n }\n .max-w-\\[1120px\\] {\n max-width: 1120px;\n }\n .min-w-0 {\n min-width: calc(var(--spacing) * 0);\n }\n .min-w-11 {\n min-width: calc(var(--spacing) * 11);\n }\n .flex-1 {\n flex: 1;\n }\n .shrink-0 {\n flex-shrink: 0;\n }\n .scale-110 {\n --tw-scale-x: 110%;\n --tw-scale-y: 110%;\n --tw-scale-z: 110%;\n scale: var(--tw-scale-x) var(--tw-scale-y);\n }\n .cursor-crosshair {\n cursor: crosshair;\n }\n .cursor-default {\n cursor: default;\n }\n .resize-y {\n resize: vertical;\n }\n .grid-cols-2 {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n }\n .grid-cols-3 {\n grid-template-columns: repeat(3, minmax(0, 1fr));\n }\n .grid-rows-\\[auto_1fr\\] {\n grid-template-rows: auto 1fr;\n }\n .flex-col {\n flex-direction: column;\n }\n .flex-row {\n flex-direction: row;\n }\n .flex-wrap {\n flex-wrap: wrap;\n }\n .items-center {\n align-items: center;\n }\n .items-start {\n align-items: flex-start;\n }\n .justify-between {\n justify-content: space-between;\n }\n .justify-center {\n justify-content: center;\n }\n .gap-0 {\n gap: calc(var(--spacing) * 0);\n }\n .gap-1 {\n gap: calc(var(--spacing) * 1);\n }\n .gap-2 {\n gap: calc(var(--spacing) * 2);\n }\n .gap-3 {\n gap: calc(var(--spacing) * 3);\n }\n .gap-4 {\n gap: calc(var(--spacing) * 4);\n }\n .gap-5 {\n gap: calc(var(--spacing) * 5);\n }\n .overflow-auto {\n overflow: auto;\n }\n .overflow-hidden {\n overflow: hidden;\n }\n .overflow-y-auto {\n overflow-y: auto;\n }\n .rounded-full {\n border-radius: calc(infinity * 1px);\n }\n .rounded-lg {\n border-radius: var(--radius);\n }\n .rounded-md {\n border-radius: calc(var(--radius) - 2px);\n }\n .rounded-xl {\n border-radius: calc(var(--radius) + 4px);\n }\n .border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n .border-b {\n border-bottom-style: var(--tw-border-style);\n border-bottom-width: 1px;\n }\n .border-border {\n border-color: var(--border);\n }\n .border-border\\/70 {\n border-color: var(--border);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--border) 70%, transparent);\n }\n }\n .border-border\\/80 {\n border-color: var(--border);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--border) 80%, transparent);\n }\n }\n .border-foreground {\n border-color: var(--foreground);\n }\n .border-input {\n border-color: var(--input);\n }\n .border-transparent {\n border-color: transparent;\n }\n .bg-black {\n background-color: var(--color-black);\n }\n .bg-black\\/60 {\n background-color: color-mix(in srgb, #000 60%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-black) 60%, transparent);\n }\n }\n .bg-card {\n background-color: var(--card);\n }\n .bg-foreground {\n background-color: var(--foreground);\n }\n .bg-muted {\n background-color: var(--muted);\n }\n .bg-muted\\/20 {\n background-color: var(--muted);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--muted) 20%, transparent);\n }\n }\n .bg-muted\\/40 {\n background-color: var(--muted);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--muted) 40%, transparent);\n }\n }\n .bg-muted\\/60 {\n background-color: var(--muted);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--muted) 60%, transparent);\n }\n }\n .bg-transparent {\n background-color: transparent;\n }\n .bg-white {\n background-color: var(--color-white);\n }\n .object-contain {\n object-fit: contain;\n }\n .p-3 {\n padding: calc(var(--spacing) * 3);\n }\n .p-4 {\n padding: calc(var(--spacing) * 4);\n }\n .p-5 {\n padding: calc(var(--spacing) * 5);\n }\n .px-0 {\n padding-inline: calc(var(--spacing) * 0);\n }\n .px-2 {\n padding-inline: calc(var(--spacing) * 2);\n }\n .px-3 {\n padding-inline: calc(var(--spacing) * 3);\n }\n .px-4 {\n padding-inline: calc(var(--spacing) * 4);\n }\n .px-5 {\n padding-inline: calc(var(--spacing) * 5);\n }\n .py-0 {\n padding-block: calc(var(--spacing) * 0);\n }\n .py-0\\.5 {\n padding-block: calc(var(--spacing) * 0.5);\n }\n .py-2 {\n padding-block: calc(var(--spacing) * 2);\n }\n .py-3 {\n padding-block: calc(var(--spacing) * 3);\n }\n .py-4 {\n padding-block: calc(var(--spacing) * 4);\n }\n .py-8 {\n padding-block: calc(var(--spacing) * 8);\n }\n .pb-0 {\n padding-bottom: calc(var(--spacing) * 0);\n }\n .pb-4 {\n padding-bottom: calc(var(--spacing) * 4);\n }\n .pl-8 {\n padding-left: calc(var(--spacing) * 8);\n }\n .text-center {\n text-align: center;\n }\n .text-right {\n text-align: right;\n }\n .font-mono {\n font-family: var(--font-mono);\n }\n .text-lg {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n }\n .text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n .text-xl {\n font-size: var(--text-xl);\n line-height: var(--tw-leading, var(--text-xl--line-height));\n }\n .text-xs {\n font-size: var(--text-xs);\n line-height: var(--tw-leading, var(--text-xs--line-height));\n }\n .text-\\[11px\\] {\n font-size: 11px;\n }\n .leading-none {\n --tw-leading: 1;\n line-height: 1;\n }\n .font-medium {\n --tw-font-weight: var(--font-weight-medium);\n font-weight: var(--font-weight-medium);\n }\n .font-semibold {\n --tw-font-weight: var(--font-weight-semibold);\n font-weight: var(--font-weight-semibold);\n }\n .text-background {\n color: var(--background);\n }\n .text-card-foreground {\n color: var(--card-foreground);\n }\n .text-destructive {\n color: var(--destructive);\n }\n .text-foreground {\n color: var(--foreground);\n }\n .text-green-700 {\n color: var(--color-green-700);\n }\n .text-muted-foreground {\n color: var(--muted-foreground);\n }\n .shadow-2xl {\n --tw-shadow: 0 25px 50px -12px var(--tw-shadow-color, rgb(0 0 0 / 0.25));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-sm {\n --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-xs {\n --tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.05));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .outline {\n outline-style: var(--tw-outline-style);\n outline-width: 1px;\n }\n .transition-\\[border-color\\,box-shadow\\] {\n transition-property: border-color,box-shadow;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-colors {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-transform {\n transition-property: transform, translate, scale, rotate;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .outline-none {\n --tw-outline-style: none;\n outline-style: none;\n }\n .hover\\:bg-muted\\/80 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--muted);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--muted) 80%, transparent);\n }\n }\n }\n }\n .hover\\:opacity-90 {\n &:hover {\n @media (hover: hover) {\n opacity: 90%;\n }\n }\n }\n .focus-visible\\:border-ring {\n &:focus-visible {\n border-color: var(--ring);\n }\n }\n .focus-visible\\:ring-2 {\n &:focus-visible {\n --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n }\n .focus-visible\\:ring-ring\\/60 {\n &:focus-visible {\n --tw-ring-color: var(--ring);\n @supports (color: color-mix(in lab, red, red)) {\n --tw-ring-color: color-mix(in oklab, var(--ring) 60%, transparent);\n }\n }\n }\n .focus-visible\\:outline-none {\n &:focus-visible {\n --tw-outline-style: none;\n outline-style: none;\n }\n }\n .disabled\\:cursor-not-allowed {\n &:disabled {\n cursor: not-allowed;\n }\n }\n .disabled\\:opacity-50 {\n &:disabled {\n opacity: 50%;\n }\n }\n .sm\\:grid-cols-2 {\n @media (width >= 40rem) {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n }\n }\n .sm\\:flex-row {\n @media (width >= 40rem) {\n flex-direction: row;\n }\n }\n .lg\\:grid-cols-\\[minmax\\(0\\,1\\.5fr\\)_360px\\] {\n @media (width >= 64rem) {\n grid-template-columns: minmax(0,1.5fr) 360px;\n }\n }\n .lg\\:border-r {\n @media (width >= 64rem) {\n border-right-style: var(--tw-border-style);\n border-right-width: 1px;\n }\n }\n .lg\\:border-b-0 {\n @media (width >= 64rem) {\n border-bottom-style: var(--tw-border-style);\n border-bottom-width: 0px;\n }\n }\n}\n:root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.145 0 0);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.145 0 0);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.145 0 0);\n --primary: oklch(0.205 0 0);\n --primary-foreground: oklch(0.985 0 0);\n --secondary: oklch(0.97 0 0);\n --secondary-foreground: oklch(0.205 0 0);\n --muted: oklch(0.97 0 0);\n --muted-foreground: oklch(0.556 0 0);\n --accent: oklch(0.97 0 0);\n --accent-foreground: oklch(0.205 0 0);\n --destructive: oklch(0.58 0.22 27);\n --border: oklch(0.922 0 0);\n --input: oklch(0.922 0 0);\n --ring: oklch(0.708 0 0);\n --radius: 0.625rem;\n}\n@layer base {\n :host {\n font-family: var(--font-sans);\n }\n *,\n ::before,\n ::after {\n box-sizing: border-box;\n border-color: var(--border);\n }\n .crikket-capture-root {\n color: var(--foreground);\n font-family: var(--font-sans);\n }\n .capture-launcher {\n position: fixed;\n right: 24px;\n bottom: 24px;\n z-index: var(--capture-z-index);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 36px;\n padding: 0 16px;\n border: 0;\n border-radius: 9999px;\n background: #111827;\n color: #ffffff;\n font: 500 14px / 1.2 Inter Variable,\n Inter,\n ui-sans-serif,\n system-ui,\n sans-serif;\n box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);\n cursor: pointer;\n transition: opacity 150ms ease;\n }\n .capture-launcher:hover {\n opacity: 0.92;\n }\n .capture-launcher:focus-visible {\n outline: 2px solid rgb(17 24 39 / 0.45);\n outline-offset: 2px;\n }\n .capture-launcher:disabled {\n opacity: 0.7;\n cursor: progress;\n }\n button:not(:disabled),\n [role=\"button\"]:not(:disabled) {\n cursor: pointer;\n }\n}\n@property --tw-scale-x {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n@property --tw-scale-y {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n@property --tw-scale-z {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n@property --tw-border-style {\n syntax: \"*\";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-leading {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-font-weight {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-shadow-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-shadow-alpha {\n syntax: \"<percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-inset-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-shadow-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-inset-shadow-alpha {\n syntax: \"<percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-ring-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-ring-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-ring-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-inset-ring-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-ring-inset {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-ring-offset-width {\n syntax: \"<length>\";\n inherits: false;\n initial-value: 0px;\n}\n@property --tw-ring-offset-color {\n syntax: \"*\";\n inherits: false;\n initial-value: #fff;\n}\n@property --tw-ring-offset-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-outline-style {\n syntax: \"*\";\n inherits: false;\n initial-value: solid;\n}\n@layer properties {\n @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {\n *, ::before, ::after, ::backdrop {\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-scale-z: 1;\n --tw-border-style: solid;\n --tw-leading: initial;\n --tw-font-weight: initial;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-color: initial;\n --tw-shadow-alpha: 100%;\n --tw-inset-shadow: 0 0 #0000;\n --tw-inset-shadow-color: initial;\n --tw-inset-shadow-alpha: 100%;\n --tw-ring-color: initial;\n --tw-ring-shadow: 0 0 #0000;\n --tw-inset-ring-color: initial;\n --tw-inset-ring-shadow: 0 0 #0000;\n --tw-ring-inset: initial;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-outline-style: solid;\n }\n }\n}\n";function le(e,t,r){let o=document.createElement("div"),a=o.attachShadow({mode:"open"}),n=document.createElement("style");n.textContent=Ue;let l=document.createElement("div");a.append(n),a.append(l),e.append(o);let i=Te(l),f=se();return i.render(Me(oe,{callbacks:r,store:f,zIndex:t})),{setHidden:(E)=>{o.style.display=E?"none":""},store:f,unmount:()=>{i.unmount(),o.remove(),f.destroy()}}}class U{runtimeConfig=null;submitTransport;mountedTarget=null;mountedUi=null;debuggerCollector=new P;activeRecording=null;currentMedia=null;currentReview=null;init(e){let t={key:w(e.key),host:k(e.host),submitPath:p(e.submitPath),zIndex:L(e.zIndex)};if(this.runtimeConfig=t,this.submitTransport=e.submitTransport,e.autoMount??!0)this.mount(e.mountTarget);return this}isInitialized(){return this.runtimeConfig!==null}getConfig(){return this.runtimeConfig}mount(e){let t=this.getRuntimeConfig();if(this.ensureBrowserContext(),this.mountedTarget)return;let r=e??document.body;this.mountedUi=le(r,t.zIndex,{onClose:()=>{this.close()},onStartVideo:()=>{return this.startRecording()},onTakeScreenshot:async()=>{if(!await this.takeScreenshot())throw Error("Screenshot capture failed.")},onStopRecording:async()=>{if(!await this.stopRecording())throw Error("Recording capture failed.")},onSubmit:(o,a)=>{return this.submit(o,a).then(()=>{return})},onReset:()=>{this.reset()}}),this.mountedTarget=r}unmount(){this.abortActiveRecording(),this.setUiHidden(!1),this.mountedUi?.unmount(),this.mountedUi=null,this.debuggerCollector.dispose(),this.mountedTarget=null}open(){if(this.getRuntimeConfig(),!this.mountedTarget)this.mount();this.mountedUi?.store.openChooser()}close(){this.setUiHidden(!1),this.mountedUi?.store.close()}destroy(){this.reset(),this.unmount(),this.runtimeConfig=null,this.submitTransport=void 0}async startRecording(){this.getRuntimeConfig(),this.ensureBrowserContext(),this.abortActiveRecording(),await this.debuggerCollector.startRecordingSession();try{await this.hideUiForCapture();let e=await D();return this.debuggerCollector.markRecordingStarted(e.startedAt),this.activeRecording=e,e.finished.then(async(t)=>{if(this.activeRecording!==e)return;this.activeRecording=null,await this.finalizeCapturedMedia({blob:t.blob,captureType:"video",durationMs:t.durationMs})}).catch(()=>{return}),{startedAt:e.startedAt}}catch(e){throw this.setUiHidden(!1),this.debuggerCollector.clearSession(),e}}async stopRecording(){if(!this.activeRecording)return null;let e=this.activeRecording;this.activeRecording=null;let t=await e.stop();return await this.finalizeCapturedMedia({blob:t.blob,captureType:"video",durationMs:t.durationMs}),t.blob}async takeScreenshot(){this.getRuntimeConfig(),this.ensureBrowserContext(),await this.debuggerCollector.startScreenshotSession();let e;try{await this.hideUiForCapture(),e=await O()}catch(t){throw this.setUiHidden(!1),this.debuggerCollector.clearSession(),t}return await this.finalizeCapturedMedia({blob:e,captureType:"screenshot",durationMs:null}),e}async submit(e,t){let r=this.getRuntimeConfig();if(!(this.currentMedia&&this.currentReview))throw Error("No capture is ready to submit. Start a recording or take a screenshot first.");let{submitCapturedReport:o}=await import("./submit-captured-report-behdzdha.js"),a=this.currentMedia.captureType==="screenshot"&&t?.screenshotBlobOverride?{...this.currentMedia,blob:t.screenshotBlobOverride}:this.currentMedia,n=await o({config:r,draft:e,media:a,review:this.currentReview,submitTransport:this.submitTransport});if(this.mountedUi)this.mountedUi.store.showSuccess(n.shareUrl);return n}reset(){this.abortActiveRecording(),this.setUiHidden(!1),this.clearMedia(),this.currentReview=null,this.debuggerCollector.clearSession()}setMedia(e){return this.clearMedia(),this.currentMedia={blob:e.blob,captureType:e.captureType,durationMs:e.durationMs,objectUrl:URL.createObjectURL(e.blob)},this.currentMedia}clearMedia(){if(!this.currentMedia)return;URL.revokeObjectURL(this.currentMedia.objectUrl),this.currentMedia=null}finalizeCapturedMedia(e){this.setUiHidden(!1);let t=this.debuggerCollector.finalizeSession(),r=this.setMedia(e);if(this.currentReview=t,!this.mountedUi)return;this.mountedUi.store.showReview({media:r,warnings:t.warnings,summary:t.debuggerSummary}),this.prefillTitle()}abortActiveRecording(){if(!this.activeRecording)return;this.activeRecording.abort(),this.activeRecording=null}async hideUiForCapture(){this.setUiHidden(!0),await ze()}setUiHidden(e){this.mountedUi?.setHidden(e)}prefillTitle(){let e=document.title.trim();if(e.length===0)return;this.mountedUi?.store.setTitleIfEmpty(e)}getRuntimeConfig(){if(!this.runtimeConfig)throw Error("Capture SDK is not initialized. Call capture.init({ key }) first.");return this.runtimeConfig}ensureBrowserContext(){if(typeof window>"u"||typeof document>"u")throw Error("Capture SDK can only run in a browser environment.")}}function ze(){return new Promise((e)=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{e()})})})}class M{runtimeConfig=null;initOptions=null;submitTransport;mountedTarget=null;mountedLauncher=null;eagerRuntime=null;eagerRuntimePromise=null;lifecycleVersion=0;init(e){let t={key:w(e.key),host:k(e.host),submitPath:p(e.submitPath),zIndex:L(e.zIndex)};if(this.runtimeConfig=t,this.submitTransport=e.submitTransport,this.initOptions={...e,host:t.host,key:t.key,submitPath:t.submitPath,zIndex:t.zIndex,submitTransport:this.submitTransport},e.autoMount??!0)this.mount(e.mountTarget);return this}isInitialized(){return this.runtimeConfig!==null}getConfig(){return this.runtimeConfig}mount(e){if(this.ensureBrowserContext(),this.eagerRuntime){this.eagerRuntime.mount(e);return}let t=e??document.body;if(this.mountedTarget=t,this.mountedLauncher)return;let r=this.getRuntimeConfig();this.mountedLauncher=z(t,{onOpen:()=>{this.open()},onPrefetch:()=>{this.prefetchRuntime().catch(()=>{return})},zIndex:r.zIndex})}unmount(){this.mountedLauncher?.unmount(),this.mountedLauncher=null,this.mountedTarget=null,this.eagerRuntime?.unmount()}open(){this.loadEagerRuntime(!0).catch(()=>{return})}close(){this.eagerRuntime?.close()}destroy(){this.lifecycleVersion+=1,this.mountedLauncher?.unmount(),this.mountedLauncher=null,this.mountedTarget=null,this.eagerRuntimePromise=null,this.eagerRuntime?.destroy(),this.eagerRuntime=null,this.runtimeConfig=null,this.initOptions=null,this.submitTransport=void 0}async startRecording(){return(await this.loadEagerRuntime(!1)).startRecording()}async stopRecording(){if(this.eagerRuntime)return this.eagerRuntime.stopRecording();return(await this.loadEagerRuntime(!1)).stopRecording()}async takeScreenshot(){return(await this.loadEagerRuntime(!1)).takeScreenshot()}async submit(e){return(await this.loadEagerRuntime(!1)).submit(e)}reset(){this.eagerRuntime?.reset()}async prefetchRuntime(){await this.loadEagerRuntimeModule().catch(()=>{return})}async loadEagerRuntime(e){let t=await this.getOrCreateEagerRuntime();if(e)t.open();return t}getOrCreateEagerRuntime(){if(this.eagerRuntime)return Promise.resolve(this.eagerRuntime);if(this.eagerRuntimePromise)return this.eagerRuntimePromise;let e=this.getInitOptions(),t=this.lifecycleVersion;this.mountedLauncher?.setLoading(!0);let r=this.loadEagerRuntimeModule().then(({CaptureSdkRuntime:o})=>{if(t!==this.lifecycleVersion)throw Error("Capture SDK runtime load was cancelled.");let a=new o;return a.init({...e,autoMount:!0,mountTarget:this.mountedTarget??e.mountTarget}),this.eagerRuntime=a,this.mountedLauncher?.unmount(),this.mountedLauncher=null,a}).finally(()=>{if(this.eagerRuntimePromise===r)this.eagerRuntimePromise=null;this.mountedLauncher?.setLoading(!1)});return this.eagerRuntimePromise=r,r}loadEagerRuntimeModule(){return Promise.resolve({CaptureSdkRuntime:U})}getInitOptions(){if(!this.initOptions)throw Error("Capture SDK is not initialized. Call capture.init({ key }) first.");return this.initOptions}getRuntimeConfig(){if(!this.runtimeConfig)throw Error("Capture SDK is not initialized. Call capture.init({ key }) first.");return this.runtimeConfig}ensureBrowserContext(){if(typeof window>"u"||typeof document>"u")throw Error("Capture SDK can only run in a browser environment.")}}var u=new M;function Zt(e){return u.init(e)}function $t(e){u.mount(e)}function Gt(){u.unmount()}function Yt(){u.open()}function jt(){u.close()}function en(){u.destroy()}function tn(){return u.startRecording()}function nn(){return u.stopRecording()}function rn(){return u.takeScreenshot()}function on(e){return u.submit(e)}function an(){u.reset()}function un(){return u.isInitialized()}function sn(){return u.getConfig()}export{Gt as unmount,rn as takeScreenshot,on as submit,nn as stopRecording,tn as startRecording,an as reset,Yt as open,$t as mount,un as isInitialized,Zt as init,sn as getConfig,en as destroy,He as defaultSubmitTransport,jt as close};
2
+ export{Zt as a,$t as b,Gt as c,Yt as d,jt as e,en as f,tn as g,nn as h,rn as i,on as j,an as k,un as l,sn as m};
@@ -0,0 +1,42 @@
1
+ :host {
2
+ all: initial;
3
+ }
4
+
5
+ .capture-launcher {
6
+ position: fixed;
7
+ right: 24px;
8
+ bottom: 24px;
9
+ z-index: var(--capture-z-index);
10
+ display: inline-flex;
11
+ align-items: center;
12
+ justify-content: center;
13
+ height: 36px;
14
+ padding: 0 16px;
15
+ border: 0;
16
+ border-radius: 9999px;
17
+ background: #111827;
18
+ color: #ffffff;
19
+ font:
20
+ 500 14px / 1.2 Inter Variable,
21
+ Inter,
22
+ ui-sans-serif,
23
+ system-ui,
24
+ sans-serif;
25
+ box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
26
+ cursor: pointer;
27
+ transition: opacity 150ms ease;
28
+ }
29
+
30
+ .capture-launcher:hover {
31
+ opacity: 0.92;
32
+ }
33
+
34
+ .capture-launcher:focus-visible {
35
+ outline: 2px solid rgb(17 24 39 / 0.45);
36
+ outline-offset: 2px;
37
+ }
38
+
39
+ .capture-launcher:disabled {
40
+ opacity: 0.7;
41
+ cursor: progress;
42
+ }
@@ -0,0 +1 @@
1
+ export declare function captureScreenshot(): Promise<Blob>;
@@ -0,0 +1,6 @@
1
+ export declare function requestDisplayStream(audio: boolean): Promise<MediaStream>;
2
+ export declare function assertBrowserTabSurface(stream: MediaStream): void;
3
+ export declare function prepareCaptureVideo(video: HTMLVideoElement, stream: MediaStream): Promise<void>;
4
+ export declare function releaseCaptureVideo(video: HTMLVideoElement): void;
5
+ export declare function resolveRecordingMimeType(): string;
6
+ export declare function canvasToBlob(canvas: HTMLCanvasElement, type: string): Promise<Blob>;
@@ -0,0 +1,3 @@
1
+ import type { RecordingController } from "../types.js";
2
+ export declare function captureScreenshot(): Promise<Blob>;
3
+ export declare function startDisplayRecording(): Promise<RecordingController>;
@@ -0,0 +1,2 @@
1
+ import type { RecordingController } from "../types.js";
2
+ export declare function startDisplayRecording(): Promise<RecordingController>;
@@ -0,0 +1,5 @@
1
+ import type { CaptureInitOptions } from "./types.js";
2
+ export type CapturePluginProps = Omit<CaptureInitOptions, "key"> & {
3
+ publicKey: string;
4
+ };
5
+ export declare function CapturePlugin(props: CapturePluginProps): React.JSX.Element | null;
package/dist/plugin.js ADDED
@@ -0,0 +1 @@
1
+ import{a as u}from"./index.js";import"./index-shtqtrh3.js";import"./index-0avnsp70.js";import"./index-ehy0ec5e.js";import"./index-97c5xshv.js";import"./index-331vjad4.js";import{useEffect as o,useRef as a}from"react";function l(t){let e=a(0);return o(()=>{let n=t.publicKey?.trim();if(!n)return;e.current+=1;let r=e.current,i=u({autoMount:t.autoMount,host:t.host,key:n,mountTarget:t.mountTarget,submitPath:t.submitPath,submitTransport:t.submitTransport,zIndex:t.zIndex});return()=>{queueMicrotask(()=>{if(e.current!==r)return;i.destroy()})}},[t.autoMount,t.host,t.mountTarget,t.publicKey,t.submitPath,t.submitTransport,t.zIndex]),null}export{l as CapturePlugin};
@@ -0,0 +1,2 @@
1
+ export type { CapturePluginProps } from "./plugin.js";
2
+ export { CapturePlugin } from "./plugin.js";
package/dist/react.js ADDED
@@ -0,0 +1 @@
1
+ export { CapturePlugin } from "./plugin.js"
@@ -0,0 +1 @@
1
+ import{D as oe,E as Z,F as D,t as C,u as M,v as j,w as s,x as p,y as ee,z as ne}from"./index-shtqtrh3.js";import{V as z}from"./index-97c5xshv.js";import"./index-331vjad4.js";import{useEffect as qe,useRef as Qe,useState as Ue}from"react";import{jsx as W}from"react/jsx-runtime";function x(e){if(e.media?.captureType==="video")return W("video",{className:"block h-full max-h-full w-full bg-black object-contain",controls:!0,playsInline:!0,preload:"metadata",src:e.media.objectUrl,children:W("track",{kind:"captions",label:"English",src:"data:text/vtt,WEBVTT"})});if(e.media?.captureType==="screenshot")return W("img",{alt:"Captured screenshot",className:"block h-full max-h-full w-full object-contain",src:e.media.objectUrl});return null}import{jsx as _}from"react/jsx-runtime";function q(e){return _("div",{...e,className:C("grid gap-2",e.className),children:e.children})}function Q(e){let n=e.errors[0];if(typeof n!=="string"||n.length===0)return null;return _("p",{className:"m-0 text-destructive text-xs",children:n})}import{jsx as ke}from"react/jsx-runtime";function K(e){return ke("textarea",{...e,className:C("min-h-24 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs outline-none transition-[border-color,box-shadow] focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/60 disabled:cursor-not-allowed disabled:opacity-50",e.className)})}import{useEffect as N,useMemo as De,useRef as H,useState as X}from"react";var y=[{label:"Orange",value:"#F97316"},{label:"Red",value:"#EF4444"},{label:"Blue",value:"#3B82F6"},{label:"Green",value:"#22C55E"}];async function f(e){if(e.annotations.length===0)return null;let n=await Me(e.imageUrl),l=document.createElement("canvas");l.width=n.naturalWidth,l.height=n.naturalHeight;let t=l.getContext("2d");if(!t)throw Error("Failed to create screenshot annotation canvas.");return L({annotations:e.annotations,context:t,height:l.height,image:n,width:l.width}),new Promise((o,i)=>{l.toBlob((m)=>{if(!m){i(Error("Failed to export annotated screenshot."));return}o(m)},"image/png")})}function L(e){e.context.clearRect(0,0,e.width,e.height),e.context.drawImage(e.image,0,0,e.width,e.height);for(let n of e.annotations)Se({annotation:n,context:e.context,height:e.height,width:e.width})}function I(e){return{x:P(e.x),y:P(e.y)}}function Se(e){if(e.annotation.kind==="rectangle"){Ee({...e,annotation:e.annotation});return}Ce({...e,annotation:e.annotation})}function Ce(e){if(e.annotation.points.length===0)return;let{context:n,width:l,height:t}=e,o=e.annotation.tool==="highlight"?Math.max(14,Math.round(Math.min(l,t)*0.025)):Math.max(3,Math.round(Math.min(l,t)*0.006)),[i,...m]=e.annotation.points;if(!i)return;n.save(),n.strokeStyle=e.annotation.tool==="highlight"?O(e.annotation.color,0.28):e.annotation.color,n.lineCap="round",n.lineJoin="round",n.lineWidth=o,n.beginPath(),n.moveTo(i.x*l,i.y*t);for(let g of m)n.lineTo(g.x*l,g.y*t);if(m.length===0)n.lineTo(i.x*l+0.01,i.y*t+0.01);n.stroke(),n.restore()}function Ee(e){let{annotation:n,context:l,width:t,height:o}=e,i=n.x*t,m=n.y*o,g=n.width*t,r=n.height*o;l.save(),l.fillStyle=O(n.color,0.08),l.strokeStyle=n.color,l.lineWidth=Math.max(3,Math.round(Math.min(t,o)*0.005)),l.fillRect(i,m,g,r),l.strokeRect(i,m,g,r),l.restore()}function P(e){return Math.min(1,Math.max(0,e))}function Me(e){return new Promise((n,l)=>{let t=new Image;t.decoding="async",t.onload=()=>{n(t)},t.onerror=()=>{l(Error("Failed to load screenshot for annotation."))},t.src=e})}function O(e,n){let l=e.slice(1),t=Number.parseInt(l.slice(0,2),16),o=Number.parseInt(l.slice(2,4),16),i=Number.parseInt(l.slice(4,6),16);return`rgba(${t}, ${o}, ${i}, ${n})`}import{jsx as d,jsxs as U}from"react/jsx-runtime";var Je="draw",Ne=y[0].value;function le(e){let n=H(e.annotations),l=H(null),t=H(null),o=H(null),[i,m]=X(null),[g,r]=X(Je),[w,F]=X(Ne),[u,S]=X(null),$=H(null),[we,de]=X(0);N(()=>{n.current=e.annotations},[e.annotations]),N(()=>{$.current=u},[u]),N(()=>{let c=!0,h=new Image;return h.decoding="async",h.onload=()=>{if(!c)return;m(h)},h.onerror=()=>{if(!c)return;m(null)},h.src=e.src,()=>{c=!1}},[e.src]),N(()=>{let c=l.current;if(!c)return;let h=new ResizeObserver((a)=>{let E=a[0];if(!E)return;de(Math.floor(E.contentRect.width))});return h.observe(c),()=>{h.disconnect()}},[]);let me=i&&i.naturalWidth>0?i.naturalHeight/i.naturalWidth:0.5625,J=Math.max(we,1),T=Math.max(Math.round(J*me),1),A=De(()=>{return u?[...e.annotations,u]:e.annotations},[u,e.annotations]);N(()=>{let c=t.current;if(!(c&&i))return;let h=c.getContext("2d");if(!h)return;let a=window.devicePixelRatio||1;c.width=Math.round(J*a),c.height=Math.round(T*a),c.style.width=`${J}px`,c.style.height=`${T}px`,h.setTransform(a,0,0,a,0,0),L({annotations:A,context:h,height:T,image:i,width:J})},[T,J,i,A]);let ge=(c)=>{if(!c)return;e.onChange([...n.current,c]),S(null),$.current=null,o.current=null},Fe=(c)=>{if(e.disabled||!i||c.button!==0)return;let h=G(c);if(c.currentTarget.setPointerCapture(c.pointerId),g==="rectangle"){o.current=h,S({kind:"rectangle",color:w,x:h.x,y:h.y,width:0,height:0});return}S({color:w,kind:"stroke",points:[h],tool:g})},ae=(c)=>{if(!(u&&i))return;let h=G(c);if(u.kind==="rectangle"){let a=o.current??{x:u.x,y:u.y};S({color:u.color,kind:"rectangle",x:Math.min(a.x,h.x),y:Math.min(a.y,h.y),width:Math.abs(h.x-a.x),height:Math.abs(h.y-a.y)});return}S({...u,points:[...u.points,h]})},Y=(c)=>{if(c.currentTarget.hasPointerCapture(c.pointerId))c.currentTarget.releasePointerCapture(c.pointerId);let h=$.current;if(!h)return;let a=G(c),E=h.kind==="stroke"?{...h,points:[...h.points,a]}:h;if(E.kind==="rectangle"&&(E.width<0.01||E.height<0.01)){S(null),$.current=null,o.current=null;return}ge(E)},v=e.annotations.length>0;return U("div",{className:"grid min-h-full grid-rows-[auto_1fr]",children:[U("div",{className:"flex flex-wrap items-center gap-2 px-0 py-0 pb-4",children:[d(R,{active:g==="draw",disabled:e.disabled,icon:d(j,{className:"h-4 w-4"}),label:"Draw",onClick:()=>{r("draw")}}),d(R,{active:g==="highlight",disabled:e.disabled,icon:d(s,{className:"h-4 w-4"}),label:"Highlight",onClick:()=>{r("highlight")}}),d(R,{active:g==="rectangle",disabled:e.disabled,icon:d(p,{className:"h-4 w-4"}),label:"Rectangle",onClick:()=>{r("rectangle")}}),d("div",{className:"flex items-center gap-2",children:y.map((c)=>d(He,{active:w===c.value,color:c.value,disabled:e.disabled,label:c.label,onClick:()=>{F(c.value)}},c.value))}),U("div",{className:"ml-auto flex flex-wrap items-center gap-2",children:[d(M,{className:"gap-2",disabled:e.disabled||!v,onClick:()=>{e.onChange(e.annotations.slice(0,-1))},size:"icon",type:"button",variant:"outline",children:d(ee,{className:"h-4 w-4"})}),d(M,{className:"gap-2",disabled:e.disabled||!v,onClick:()=>{e.onChange([]),S(null)},size:"icon",type:"button",variant:"outline",children:d(ne,{className:"h-4 w-4"})})]})]}),d("div",{className:"min-h-0 overflow-auto",children:d("div",{className:"flex min-h-full items-center justify-center",children:d("div",{className:"w-full max-w-[960px]",ref:l,children:d("canvas",{"aria-label":"Screenshot annotation editor",className:C("block w-full rounded-xl bg-white shadow-sm",e.disabled?"cursor-default":"cursor-crosshair"),onPointerCancel:Y,onPointerDown:Fe,onPointerMove:ae,onPointerUp:Y,ref:t,style:{touchAction:"none"}})})})})]});function G(c){let h=c.currentTarget.getBoundingClientRect();return I({x:(c.clientX-h.left)/h.width,y:(c.clientY-h.top)/h.height})}}function R(e){return U(M,{className:C("gap-2",e.active?"border-transparent bg-foreground text-background":null),disabled:e.disabled,onClick:e.onClick,size:"sm",type:"button",variant:e.active?"secondary":"outline",children:[d("span",{className:"text-sm",children:e.icon}),d("span",{children:e.label})]})}function He(e){return d("button",{"aria-label":e.label,className:C("h-5 w-5 rounded-full border transition-transform focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/60",e.active?"scale-110 border-foreground":"border-border"),disabled:e.disabled,onClick:e.onClick,style:{backgroundColor:e.color},type:"button"})}import{jsx as ce,jsxs as Xe}from"react/jsx-runtime";function V(e){return Xe("div",{className:"rounded-xl border bg-muted/60 p-3 text-center",children:[ce("strong",{className:"block text-lg",children:e.value}),ce("span",{className:"text-[11px] text-muted-foreground",children:e.label})]})}import{useMemo as te,useState as ue}from"react";var $e=new Set(Object.values(D)),he=new Set(Object.values(z)),ie=[{label:"Critical",value:D.critical},{label:"High",value:D.high},{label:"Medium",value:D.medium},{label:"Low",value:D.low},{label:"None",value:D.none}];function B(e){let n={};if(e.title.length>200)n.title="Title must be at most 200 characters.";if(e.description.length>3000)n.description="Description must be at most 3000 characters.";if(!$e.has(e.priority))n.priority="Select a valid priority.";if(e.visibility!==void 0&&!he.has(e.visibility))n.visibility="Select a valid visibility.";return Object.keys(n).length>0?n:void 0}function re(e){return{description:e.description.trim(),priority:e.priority,title:e.title.trim(),visibility:he.has(e.visibility??"")?e.visibility:z.private}}var Te={description:!1,priority:!1,title:!1,visibility:!1};function be(e){let[n,l]=ue(e.initialDraft),[t,o]=ue(Te),i=te(()=>{return B(n)??{}},[n]),m=te(()=>{let F={};for(let u of Object.keys(t))if(t[u]&&i[u])F[u]=i[u];return F},[i,t]);return{draft:n,handleSubmit:(F)=>{if(F.preventDefault(),F.stopPropagation(),o({description:!0,priority:!0,title:!0,visibility:!0}),B(n))return;e.onSubmit(re(n))},setFieldValue:(F,u)=>{l((S)=>({...S,[F]:u}))},touchField:(F)=>{o((u)=>{if(u[F])return u;return{...u,[F]:!0}})},visibleErrors:m}}import{jsx as b,jsxs as k}from"react/jsx-runtime";function Fn({formKey:e,isSubmitting:n,state:l,onCancel:t,onSubmit:o}){let[i,m]=Ue([]),g=Qe(l.media?.objectUrl);qe(()=>{if(g.current===l.media?.objectUrl)return;g.current=l.media?.objectUrl,m([])},[l.media?.objectUrl]);let r=be({initialDraft:l.reviewDraft,onSubmit:async(w)=>{let F;if(l.media?.captureType==="screenshot"&&i.length>0){let u=await f({annotations:i,imageUrl:l.media.objectUrl});F=u?{screenshotBlobOverride:u}:void 0}o(w,F)}});return k("section",{className:"grid h-full min-h-0 gap-0 lg:grid-cols-[minmax(0,1.5fr)_360px]",children:[k("div",{className:"flex min-h-[320px] min-w-0 flex-col border-b bg-muted/20 lg:border-r lg:border-b-0",children:[b("div",{className:"flex items-center justify-between gap-3 border-b px-5 py-4",children:k("div",{children:[b("p",{className:"font-medium text-sm",children:"Review capture"}),b("p",{className:"text-muted-foreground text-xs",children:l.media?.captureType==="screenshot"?"Annotate the screenshot before submitting.":"Preview the recording before submitting."})]})}),b("div",{className:"min-h-0 flex-1 overflow-auto p-5",children:l.media?.captureType==="screenshot"?b(le,{annotations:i,disabled:l.busy||n,onChange:m,src:l.media.objectUrl}):b("div",{className:"flex min-h-full items-center justify-center",children:b("div",{className:"aspect-video w-full overflow-hidden rounded-xl border border-border/70 bg-black",children:b(x,{media:l.media})})})})]}),b("div",{className:"min-h-0 overflow-y-auto p-5",children:k("div",{className:"grid gap-4",children:[k("div",{className:"grid grid-cols-3 gap-2",children:[b(V,{label:"Actions",value:l.summary.actions}),b(V,{label:"Logs",value:l.summary.logs}),b(V,{label:"Network",value:l.summary.networkRequests})]}),l.warnings.length>0?b("ul",{className:"m-0 grid gap-1 rounded-lg border bg-muted/40 px-4 py-3 pl-8 text-muted-foreground text-xs",children:l.warnings.map((w)=>b("li",{children:w},w))}):null,k("form",{className:"grid gap-4",onSubmit:r.handleSubmit,children:[k(q,{"data-invalid":Boolean(r.visibleErrors.title),children:[b(Z,{htmlFor:`${e}-title`,children:"Title"}),b(oe,{"aria-invalid":Boolean(r.visibleErrors.title),id:`${e}-title`,maxLength:200,onBlur:()=>{r.touchField("title")},onChange:(w)=>{r.setFieldValue("title",w.currentTarget.value)},placeholder:"Enter a title (optional)",value:r.draft.title}),r.visibleErrors.title?b(Q,{errors:[r.visibleErrors.title]}):null]}),k(q,{"data-invalid":Boolean(r.visibleErrors.description),children:[b(Z,{htmlFor:`${e}-description`,children:"Description"}),b(K,{"aria-invalid":Boolean(r.visibleErrors.description),className:"min-h-32 resize-y",id:`${e}-description`,maxLength:4000,onBlur:()=>{r.touchField("description")},onChange:(w)=>{r.setFieldValue("description",w.currentTarget.value)},placeholder:"Enter a description (optional)",value:r.draft.description}),r.visibleErrors.description?b(Q,{errors:[r.visibleErrors.description]}):null]}),k(q,{"data-invalid":Boolean(r.visibleErrors.priority),children:[b(Z,{htmlFor:`${e}-priority`,children:"Priority"}),b("select",{"aria-invalid":Boolean(r.visibleErrors.priority),className:"h-9 w-full rounded-md border border-input bg-transparent px-3 text-sm shadow-xs outline-none transition-[border-color,box-shadow] focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/60",id:`${e}-priority`,onBlur:()=>{r.touchField("priority")},onChange:(w)=>{r.setFieldValue("priority",w.currentTarget.value)},value:r.draft.priority,children:ie.map((w)=>b("option",{value:w.value,children:w.label},w.value))}),r.visibleErrors.priority?b(Q,{errors:[r.visibleErrors.priority]}):null]}),k("div",{className:"grid grid-cols-2 gap-2",children:[b(M,{className:"w-full",disabled:l.busy||n,type:"submit",children:"Submit Report"}),b(M,{className:"w-full",disabled:l.busy||n,onClick:t,type:"button",variant:"outline",children:"Start Over"})]})]})]})})]},e)}export{Fn as ReviewFormSection};
@@ -0,0 +1,36 @@
1
+ import type { CaptureInitOptions, CaptureRuntimeConfig, CaptureRuntimeController, CaptureSubmissionDraft } from "../types.js";
2
+ import type { CaptureReviewSubmitOptions } from "../ui/types.js";
3
+ export declare class CaptureSdkRuntime implements CaptureRuntimeController {
4
+ private runtimeConfig;
5
+ private submitTransport;
6
+ private mountedTarget;
7
+ private mountedUi;
8
+ private readonly debuggerCollector;
9
+ private activeRecording;
10
+ private currentMedia;
11
+ private currentReview;
12
+ init(options: CaptureInitOptions): CaptureRuntimeController;
13
+ isInitialized(): boolean;
14
+ getConfig(): CaptureRuntimeConfig | null;
15
+ mount(target?: HTMLElement): void;
16
+ unmount(): void;
17
+ open(): void;
18
+ close(): void;
19
+ destroy(): void;
20
+ startRecording(): Promise<{
21
+ startedAt: number;
22
+ }>;
23
+ stopRecording(): Promise<Blob | null>;
24
+ takeScreenshot(): Promise<Blob | null>;
25
+ submit(draft: CaptureSubmissionDraft, options?: CaptureReviewSubmitOptions): Promise<import("..").CaptureSubmitResult>;
26
+ reset(): void;
27
+ private setMedia;
28
+ private clearMedia;
29
+ private finalizeCapturedMedia;
30
+ private abortActiveRecording;
31
+ private hideUiForCapture;
32
+ private setUiHidden;
33
+ private prefillTitle;
34
+ private getRuntimeConfig;
35
+ private ensureBrowserContext;
36
+ }
@@ -0,0 +1,33 @@
1
+ import type { CaptureInitOptions, CaptureRuntimeConfig, CaptureRuntimeController, CaptureSubmissionDraft, CaptureSubmitResult } from "../types.js";
2
+ export declare class LazyCaptureSdkRuntime implements CaptureRuntimeController {
3
+ private runtimeConfig;
4
+ private initOptions;
5
+ private submitTransport;
6
+ private mountedTarget;
7
+ private mountedLauncher;
8
+ private eagerRuntime;
9
+ private eagerRuntimePromise;
10
+ private lifecycleVersion;
11
+ init(options: CaptureInitOptions): CaptureRuntimeController;
12
+ isInitialized(): boolean;
13
+ getConfig(): CaptureRuntimeConfig | null;
14
+ mount(target?: HTMLElement): void;
15
+ unmount(): void;
16
+ open(): void;
17
+ close(): void;
18
+ destroy(): void;
19
+ startRecording(): Promise<{
20
+ startedAt: number;
21
+ }>;
22
+ stopRecording(): Promise<Blob | null>;
23
+ takeScreenshot(): Promise<Blob | null>;
24
+ submit(draft: CaptureSubmissionDraft): Promise<CaptureSubmitResult>;
25
+ reset(): void;
26
+ private prefetchRuntime;
27
+ private loadEagerRuntime;
28
+ private getOrCreateEagerRuntime;
29
+ private loadEagerRuntimeModule;
30
+ private getInitOptions;
31
+ private getRuntimeConfig;
32
+ private ensureBrowserContext;
33
+ }
@@ -0,0 +1,8 @@
1
+ import type { CapturedMedia, CaptureRuntimeConfig, CaptureSubmissionDraft, CaptureSubmitResult, CaptureSubmitTransport, ReviewSnapshot } from "../types.js";
2
+ export declare function submitCapturedReport(input: {
3
+ config: CaptureRuntimeConfig;
4
+ draft: CaptureSubmissionDraft;
5
+ media: CapturedMedia;
6
+ review: ReviewSnapshot;
7
+ submitTransport?: CaptureSubmitTransport;
8
+ }): Promise<CaptureSubmitResult>;
@@ -0,0 +1 @@
1
+ import{n as b,o as f,p as E,q as S,r as w}from"./index-nd41xgv7.js";import"./index-331vjad4.js";var m=64000,v=550000;async function T(){let r=await b(!0);f(r);let s=document.createElement("video");await E(s,r),S(s);let a=w(),R=a.length>0?{audioBitsPerSecond:m,mimeType:a,videoBitsPerSecond:v}:{audioBitsPerSecond:m,videoBitsPerSecond:v},t=new MediaRecorder(r,R),i=Date.now(),o=[],d=null,c=null,l=new Promise((e,n)=>{d=e,c=n}),u=()=>{if(t.state!=="inactive")t.stop()};t.addEventListener("dataavailable",(e)=>{if(e.data.size>0)o.push(e.data)}),t.addEventListener("error",(e)=>{c?.(Error(`MediaRecorder error: ${e.type}`))}),t.addEventListener("stop",()=>{for(let p of r.getTracks())p.removeEventListener("ended",u),p.stop();let e=Date.now(),n=new Blob(o,{type:o[0]?.type||"video/webm"});d?.({blob:n,durationMs:Math.max(0,e-i)})});for(let e of r.getTracks())e.addEventListener("ended",u,{once:!0});return t.start(1000),{finished:l,startedAt:i,stop:()=>{if(t.state!=="inactive")t.stop();return l},abort:()=>{if(t.state!=="inactive"){t.stop();return}for(let e of r.getTracks())e.stop()}}}export{T as startDisplayRecording};
@@ -0,0 +1 @@
1
+ import{G as x}from"./index-0avnsp70.js";import{R as j,S as k,T as q}from"./index-ehy0ec5e.js";import{V as w}from"./index-97c5xshv.js";import"./index-331vjad4.js";function F(h){return(h.submitTransport??x)({config:h.config,report:{captureType:h.media.captureType,title:h.draft.title.trim(),description:h.draft.description.trim(),priority:h.draft.priority,visibility:w.private,pageUrl:j(),pageTitle:k(),durationMs:h.media.durationMs,deviceInfo:q(),debuggerPayload:h.review.debuggerPayload,debuggerSummary:h.review.debuggerSummary,media:h.media.blob}})}export{F as submitCapturedReport};
@@ -0,0 +1,2 @@
1
+ import type { CaptureSubmitRequest, CaptureSubmitResult } from "../types.js";
2
+ export declare function defaultSubmitTransport(request: CaptureSubmitRequest): Promise<CaptureSubmitResult>;
@@ -0,0 +1,20 @@
1
+ interface TurnstileRenderOptions {
2
+ appearance?: "always" | "execute" | "interaction-only";
3
+ callback?: (token: string) => void;
4
+ execution?: "execute" | "render";
5
+ "error-callback"?: () => void;
6
+ "expired-callback"?: () => void;
7
+ sitekey: string;
8
+ }
9
+ interface TurnstileApi {
10
+ execute: (widgetId: string) => void;
11
+ remove?: (widgetId: string) => void;
12
+ render: (container: HTMLElement, options: TurnstileRenderOptions) => string;
13
+ }
14
+ declare global {
15
+ interface Window {
16
+ turnstile?: TurnstileApi;
17
+ }
18
+ }
19
+ export declare function runTurnstileChallenge(siteKey: string): Promise<string>;
20
+ export {};