@botsigged/sdk 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/botsigged.js +2 -2
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/dist/botsigged.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(()=>{var{defineProperty:v,getOwnPropertyNames:NA,getOwnPropertyDescriptor:wA}=Object,LA=Object.prototype.hasOwnProperty;var CA=new WeakMap,kA=(A)=>{var B=CA.get(A),Q;if(B)return B;if(B=v({},"__esModule",{value:!0}),A&&typeof A==="object"||typeof A==="function")NA(A).map((E)=>!LA.call(B,E)&&v(B,E,{get:()=>A[E],enumerable:!(Q=wA(A,E))||Q.enumerable}));return CA.set(A,B),B};var g=(A,B)=>{for(var Q in B)v(A,Q,{get:B[Q],enumerable:!0,configurable:!0,set:(E)=>B[Q]=()=>E})};var u=(A,B)=>()=>(A&&(B=A(A=0)),B);var ZA="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";function UA(A){let B=atob(A),Q=new Uint8Array(B.length);for(let E=0;E<B.length;E++)Q[E]=B.charCodeAt(E);return Q}async function
|
|
1
|
+
(()=>{var{defineProperty:v,getOwnPropertyNames:NA,getOwnPropertyDescriptor:wA}=Object,LA=Object.prototype.hasOwnProperty;var CA=new WeakMap,kA=(A)=>{var B=CA.get(A),Q;if(B)return B;if(B=v({},"__esModule",{value:!0}),A&&typeof A==="object"||typeof A==="function")NA(A).map((E)=>!LA.call(B,E)&&v(B,E,{get:()=>A[E],enumerable:!(Q=wA(A,E))||Q.enumerable}));return CA.set(A,B),B};var g=(A,B)=>{for(var Q in B)v(A,Q,{get:B[Q],enumerable:!0,configurable:!0,set:(E)=>B[Q]=()=>E})};var u=(A,B)=>()=>(A&&(B=A(A=0)),B);var ZA="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";function UA(A){let B=atob(A),Q=new Uint8Array(B.length);for(let E=0;E<B.length;E++)Q[E]=B.charCodeAt(E);return Q}async function a(){if(j)return j;return j=(async()=>{try{let A=UA(ZA),B=await WebAssembly.compile(A);return c=(await WebAssembly.instantiate(B,{env:{abort:(E,I,C,Y)=>{}}})).exports,OA(c)}catch(A){throw j=null,A}})(),j}function i(){return c!==null}function OA(A){function B(I){let C=A.__new(I.length,1);return new Uint8Array(A.memory.buffer,C,I.length).set(I),C}function Q(I){let C=new Uint16Array(I.length);for(let Z=0;Z<I.length;Z++)C[Z]=I.charCodeAt(Z);let Y=A.__new(C.length*2,2);return new Uint16Array(A.memory.buffer,Y,C.length).set(C),Y}function E(I,C=1024){let Y=new Uint8Array(A.memory.buffer),G=Y.length;if(I<0||I>=G)return"";let Z=I,K=Math.min(I+C,G);while(Z<K&&Y[Z]!==0)Z++;let X=Y.slice(I,Z);return new TextDecoder().decode(X)}return{xxHash32(I,C=0){let Y=B(I);try{return A.xxHash32(Y,C)}finally{A.__unpin(Y)}},hashString(I,C=0){let Y=Q(I);try{return A.hashString(Y,C)}finally{A.__unpin(Y)}},hashStringToHex(I,C=0){let Y=Q(I);try{let G=A.hashStringToHex(Y,C);return E(G)}finally{A.__unpin(Y)}},verifyHash(I,C,Y=0){let G=B(I);try{return A.verifyHash(G,C,Y)}finally{A.__unpin(G)}},verifyStringHash(I,C,Y=0){let G=Q(I);try{return A.verifyStringHash(G,C,Y)}finally{A.__unpin(G)}}}}function M(){let A=new TextEncoder;function B(E,I=0){let X=($,D)=>($<<D|$>>>32-D)>>>0,N=($,D)=>($[D]|$[D+1]<<8|$[D+2]<<16|$[D+3]<<24)>>>0,V=E.length,z,W=0;if(V>=16){let $=V-16,D=I+2654435761+2246822519>>>0,T=I+2246822519>>>0,x=I>>>0,h=I-2654435761>>>0;while(W<=$)D=Math.imul(X(D+Math.imul(N(E,W),2246822519)>>>0,13),2654435761)>>>0,W+=4,T=Math.imul(X(T+Math.imul(N(E,W),2246822519)>>>0,13),2654435761)>>>0,W+=4,x=Math.imul(X(x+Math.imul(N(E,W),2246822519)>>>0,13),2654435761)>>>0,W+=4,h=Math.imul(X(h+Math.imul(N(E,W),2246822519)>>>0,13),2654435761)>>>0,W+=4;z=X(D,1)+X(T,7)+X(x,12)+X(h,18)>>>0}else z=I+374761393>>>0;z=z+V>>>0;while(W<=V-4)z=Math.imul(X(z+Math.imul(N(E,W),3266489917)>>>0,17),668265263)>>>0,W+=4;while(W<V)z=Math.imul(X(z+Math.imul(E[W],374761393)>>>0,11),2654435761)>>>0,W++;return z^=z>>>15,z=Math.imul(z,2246822519)>>>0,z^=z>>>13,z=Math.imul(z,3266489917)>>>0,z^=z>>>16,z>>>0}function Q(E){return(E>>>0).toString(16).padStart(8,"0")}return{xxHash32:B,hashString(E,I=0){return B(A.encode(E),I)},hashStringToHex(E,I=0){return Q(B(A.encode(E),I))},verifyHash(E,I,C=0){return B(E,C)===I},verifyStringHash(E,I,C=0){return B(A.encode(E),C)===I}}}var c=null,j=null;var XA=()=>{};var zA={};g(zA,{verifySignature:()=>MA,verify:()=>PA,loadHashModule:()=>a,isUsingWasm:()=>jA,isHashModuleLoaded:()=>i,initHashModule:()=>FA,hashToHex:()=>s,hash:()=>_A,getHash:()=>U,createSignature:()=>RA,createFallbackHashModule:()=>M});async function FA(A={}){let{preferWasm:B=!0,onWasmLoaded:Q,onFallback:E}=A;if(H)return H;if(y)return y;return y=(async()=>{if(B)try{return H=await a(),S=!0,Q?.(),H}catch(I){let C=I instanceof Error?I.message:"Unknown error";E?.(C)}else E?.("WASM disabled by configuration");return H=M(),S=!1,H})(),y}function U(){if(H)return H;return H=M(),S=!1,H}function jA(){return S&&i()}function _A(A,B=0){let Q=U();if(typeof A==="string")return Q.hashString(A,B);return Q.xxHash32(A,B)}function s(A,B=0){let Q=U();if(typeof A==="string")return Q.hashStringToHex(A,B);return Q.xxHash32(A,B).toString(16).padStart(8,"0")}function PA(A,B,Q=0){let E=U(),I=typeof B==="string"?parseInt(B,16):B;if(typeof A==="string")return E.verifyStringHash(A,I,Q);return E.verifyHash(A,I,Q)}function RA(A,B){let Q=U(),E=Q.hashString(B,0);return Q.hashString(A,E).toString(16).padStart(8,"0")}function MA(A,B,Q){return RA(A,Q)===B}var H=null,y=null,S=!0;var b=u(()=>{XA()});class BA{overlay=null;messageEl=null;progressEl=null;config;constructor(A){this.config=A}show(){if(!this.config.enabled||this.overlay)return;this.overlay=document.createElement("div"),this.overlay.id="botsigged-challenge-overlay",this.overlay.style.cssText=`
|
|
2
2
|
position: fixed;
|
|
3
3
|
top: 0;
|
|
4
4
|
left: 0;
|
|
@@ -79,4 +79,4 @@
|
|
|
79
79
|
to { transform: rotate(360deg); }
|
|
80
80
|
}
|
|
81
81
|
</style>
|
|
82
|
-
`,document.body.appendChild(this.loadingOverlay)}hideLoading(){if(this.loadingOverlay)this.loadingOverlay.remove(),this.loadingOverlay=null}notifyReady(A){this.isReady=!0,this.hasScore=!0,this.currentScore=A,[...this.pendingSubmissions].forEach((E)=>{this.releaseSubmission(E,!1)}),[...this.pendingRequests].forEach((E)=>{this.releaseRequest(E)}),this.hideLoading()}blockAllPending(A){[...this.pendingSubmissions].forEach((Q)=>{this.config.onBlock?.(Q.form,A),this.releaseSubmission(Q,!0)})}getStatus(){return{mode:this.config.mode,isReady:this.isReady,hasScore:this.hasScore,pendingCount:this.pendingSubmissions.length,protectedFormCount:this.protectedForms.size}}waitUntilReady(){if(this.hasScore)return Promise.resolve({score:this.currentScore,timedOut:!1});return new Promise((A)=>{let B=performance.now(),Q=()=>{if(this.hasScore){A({score:this.currentScore,timedOut:!1});return}if(performance.now()-B>=this.config.maxHoldTime){A({score:null,timedOut:!0});return}setTimeout(Q,50)};Q()})}withProtection(A){return async(...B)=>{let Q=performance.now()-this.startTime;if(O().markFirstSubmitAttempt(this.hasScore),this.config.mode==="blockInstant"&&Q<this.config.minTimeBeforeSubmit)throw this.config.onBlock?.(document.createElement("form"),"instant_submission"),Error("Submission blocked: too fast");if(this.config.mode==="holdUntilReady"&&!this.hasScore){if(this.config.showLoadingUI)this.showLoading(document.createElement("form"));let{timedOut:E}=await this.waitUntilReady();if(this.config.showLoadingUI)this.hideLoading()}return A(...B)}}protectedFetch(){return this.withProtection(async(A,B)=>{return fetch(A,B)})}setMode(A){if(this.config.mode=A,A==="none")[...this.pendingSubmissions].forEach((Q)=>this.releaseSubmission(Q,!1))}setMaxHoldTime(A){this.config.maxHoldTime=A}canSubmit(){let A=performance.now()-this.startTime;if(this.config.mode==="blockInstant"&&A<this.config.minTimeBeforeSubmit)return{allowed:!1,reason:"too_fast",score:this.currentScore};if(this.config.mode==="holdUntilReady"&&!this.hasScore)return{allowed:!1,reason:"waiting_for_score",score:null};return{allowed:!0,score:this.currentScore}}destroy(){if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;if(this.originalFetch)window.fetch=this.originalFetch,this.originalFetch=null;if(this.originalXHROpen)XMLHttpRequest.prototype.open=this.originalXHROpen,this.originalXHROpen=null;if(this.originalXHRSend)XMLHttpRequest.prototype.send=this.originalXHRSend,this.originalXHRSend=null;this.hideLoading(),this.pendingSubmissions=[],this.pendingRequests=[],this.protectedForms.clear()}}var KA={suspicious:40,bot:70},q={name:"_bsid",riskName:"_bsrisk",path:"/",sameSite:"Strict"};function WA(A){if(!A)return null;if(A===!0)return{...q};return{...q,...A}}function yA(A){if(A>=KA.bot)return"bot";if(A>=KA.suspicious)return"suspicious";return"human"}class r{config;sessionIdGetter;sessionCookieSet=!1;currentRiskTier=null;constructor(A,B){this.config={...q,...A},this.sessionIdGetter=B}buildCookieString(A,B){let Q=this.config.path||q.path,E=this.config.sameSite||q.sameSite,I=this.config.secure??location.protocol==="https:",C=[`${encodeURIComponent(A)}=${encodeURIComponent(B)}`,`Path=${Q}`,`SameSite=${E}`];if(I||E==="None")C.push("Secure");return C.join("; ")}deleteCookie(A){let B=this.config.path||q.path;document.cookie=`${encodeURIComponent(A)}=; Path=${B}; Max-Age=0`}setSessionCookie(){if(this.sessionCookieSet)return;let A=this.sessionIdGetter();if(!A)return;let B=this.config.name||q.name;document.cookie=this.buildCookieString(B,A),this.sessionCookieSet=!0}updateRiskTier(A){let B=yA(A);if(B===this.currentRiskTier)return!1;let Q=this.config.riskName||q.riskName;document.cookie=this.buildCookieString(Q,B);let E=this.currentRiskTier;return this.currentRiskTier=B,!0}removeCookies(){let A=this.config.name||q.name,B=this.config.riskName||q.riskName;if(this.sessionCookieSet)this.deleteCookie(A),this.sessionCookieSet=!1;if(this.currentRiskTier!==null)this.deleteCookie(B),this.currentRiskTier=null}setCookie(){this.setSessionCookie()}removeCookie(){this.removeCookies()}isSessionCookieSet(){return this.sessionCookieSet}getCurrentRiskTier(){return this.currentRiskTier}getSessionCookieName(){return this.config.name||q.name}getRiskCookieName(){return this.config.riskName||q.riskName}}var F={name:"X-BotSigged-ID"};function qA(A){if(!A)return null;if(A===!0)return{...F};return{...F,...A}}class e{config;sessionIdGetter;started=!1;originalFetch=null;originalXHROpen=null;originalXHRSend=null;originalXHRSetRequestHeader=null;xhrInjectionMap=new WeakMap;constructor(A,B){this.config={...F,...A},this.sessionIdGetter=B}start(){if(this.started)return;this.started=!0,this.patchFetch(),this.patchXHR()}stop(){if(!this.started)return;if(this.originalFetch)window.fetch=this.originalFetch,this.originalFetch=null;if(this.originalXHROpen)XMLHttpRequest.prototype.open=this.originalXHROpen,this.originalXHROpen=null;if(this.originalXHRSend)XMLHttpRequest.prototype.send=this.originalXHRSend,this.originalXHRSend=null;if(this.originalXHRSetRequestHeader)XMLHttpRequest.prototype.setRequestHeader=this.originalXHRSetRequestHeader,this.originalXHRSetRequestHeader=null;this.started=!1}isSameOrigin(A){try{let B;if(A instanceof Request)B=new URL(A.url,window.location.origin);else if(A instanceof URL)B=A;else B=new URL(A,window.location.origin);return B.origin===window.location.origin}catch{return!0}}patchFetch(){this.originalFetch=window.fetch.bind(window);let A=this,B=this.config.name||F.name;window.fetch=function(Q,E){if(!A.isSameOrigin(Q))return A.originalFetch(Q,E);let I=A.sessionIdGetter();if(!I)return A.originalFetch(Q,E);let C=new Headers(E?.headers);if(!C.has(B))C.set(B,I);return A.originalFetch(Q,{...E,headers:C})}}patchXHR(){this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send,this.originalXHRSetRequestHeader=XMLHttpRequest.prototype.setRequestHeader;let A=this,B=this.config.name||F.name;XMLHttpRequest.prototype.open=function(Q,E,I=!0,C,Y){let G=A.isSameOrigin(E);return A.xhrInjectionMap.set(this,G),A.originalXHROpen.call(this,Q,E,I,C,Y)},XMLHttpRequest.prototype.send=function(Q){if(A.xhrInjectionMap.get(this)){let E=A.sessionIdGetter();if(E)try{A.originalXHRSetRequestHeader.call(this,B,E)}catch{}}return A.originalXHRSend.call(this,Q)}}getHeaderName(){return this.config.name||F.name}isStarted(){return this.started}}var L={selector:"form",inputName:"_bsid"};function VA(A){if(!A)return null;if(A===!0)return{...L};return{...L,...A}}class AA{config;sessionIdGetter;observer=null;started=!1;constructor(A,B){this.config={...L,...A},this.sessionIdGetter=B}start(){if(this.started)return;this.started=!0;let A=()=>{this.setupExistingForms(),this.setupObserver()};if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",A,{once:!0});else A()}stop(){if(!this.started)return;if(this.observer)this.observer.disconnect(),this.observer=null;let A=this.config.selector||L.selector,B=this.config.inputName||L.inputName;document.querySelectorAll(`${A}[data-bs-inject-setup]`).forEach((Q)=>{if(Q instanceof HTMLFormElement)Q.removeEventListener("submit",this.handleSubmit,{capture:!0});Q.removeAttribute("data-bs-inject-setup");let E=Q.querySelector(`input[name="${B}"][data-bs-injected]`);if(E)E.remove()}),this.started=!1}setupExistingForms(){let A=this.config.selector||L.selector;document.querySelectorAll(A).forEach((B)=>{if(B instanceof HTMLFormElement)this.setupForm(B)})}setupObserver(){if(!document.body)return;let A=this.config.selector||L.selector;this.observer=new MutationObserver((B)=>{B.forEach((Q)=>{Q.addedNodes.forEach((E)=>{if(E instanceof HTMLFormElement&&E.matches(A))this.setupForm(E);if(E instanceof HTMLElement)E.querySelectorAll(A).forEach((I)=>{if(I instanceof HTMLFormElement)this.setupForm(I)})})})}),this.observer.observe(document.body,{childList:!0,subtree:!0})}setupForm(A){if(A.hasAttribute("data-bs-inject-setup"))return;A.setAttribute("data-bs-inject-setup","true"),A.addEventListener("submit",this.handleSubmit,{capture:!0})}handleSubmit=(A)=>{let B=A.currentTarget;this.injectInput(B)};injectInput(A){let B=this.config.inputName||L.inputName,Q=A.querySelector(`input[name="${B}"]`);if(Q){if(Q.hasAttribute("data-bs-injected"))Q.value=this.sessionIdGetter();return}let E=document.createElement("input");E.type="hidden",E.name=B,E.value=this.sessionIdGetter(),E.setAttribute("data-bs-injected","true"),A.appendChild(E)}getConfig(){return{...this.config}}isStarted(){return this.started}}class _{config;mouseCollector;scrollCollector;formCollector;browserCollector;fingerprintGenerator;socket=null;sessionId;sequenceNumber=0;isRunning=!1;sendTimer=null;fingerprint=null;browserSignal=null;lastScore=null;hasSentInitial=!1;boundBeforeUnload=null;boundVisibilityChange=null;hashModule=null;formBlocked=!1;formObserver=null;highScoreTriggeredLevels=new Set;challengeManager=null;challengeManagerPromise=null;formProtectionManager=null;formSubmissionStatus="no_submission";cookieManager=null;headerInjector=null;formInjector=null;serverConfig=null;connectionState="disconnected";reconnectTimer=null;readyPromise;readyResolver=null;constructor(A){if(J.markConstructorStart(),!A.apiKey)throw Error("BotSigged: apiKey is required");if(this.config=JA(A),this.sessionId=this.generateSessionId(),this.readyPromise=new Promise((I)=>{this.readyResolver=I}),this.mouseCollector=new p({sampleRate:this.config.mouseSampleRate,maxBufferSize:this.config.maxBufferSize}),this.scrollCollector=new m({maxBufferSize:Math.floor(this.config.maxBufferSize/3)}),this.formCollector=new d({maxKeyEvents:this.config.maxBufferSize,onSubmit:()=>this.handleFormSubmit()}),this.browserCollector=new f,this.fingerprintGenerator=new n,this.config.hashVerification.enabled)this.initializeHashModule();if(this.config.action==="challenge"||this.config.challenge.enabled)this.challengeManagerPromise=this.initializeChallengeManager();if(this.config.formProtection.mode!=="none")this.formProtectionManager=new o({mode:this.config.formProtection.mode,minTimeBeforeSubmit:this.config.formProtection.minTimeBeforeSubmit,maxHoldTime:this.config.formProtection.maxHoldTime,showLoadingUI:this.config.formProtection.showLoadingUI,loadingMessage:this.config.formProtection.loadingMessage,onHold:(I)=>{this.updateFormStatus("challenged"),this.config.formProtection.onHold?.(I)},onRelease:(I,C)=>{if(!C)this.updateFormStatus("completed");this.config.formProtection.onRelease?.(I,C)},onBlock:(I,C)=>{this.updateFormStatus("blocked"),this.config.formProtection.onBlock?.(I,C)},flushAndWaitForScore:()=>this.sendSignalAndGetScore()}),this.log("Form protection enabled:",this.config.formProtection.mode);else this.log("Form protection disabled (mode='none')");let B=WA(this.config.cookie);if(B)this.cookieManager=new r(B,()=>this.sessionId),this.log("Cookie manager enabled:",B.name);let Q=qA(this.config.headers);if(Q)this.headerInjector=new e(Q,()=>this.sessionId),this.headerInjector.start(),this.log("Header injector enabled:",Q.name);let E=VA(this.config.formInject);if(E)this.formInjector=new AA(E,()=>this.sessionId),this.formInjector.start(),this.log("Form injector enabled:",E.inputName);if(this.config.autoStart)if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",()=>this.start());else this.start();J.markConstructorEnd(),this.log("Constructor completed in",(J.getTimings().constructorEnd??0)-(J.getTimings().constructorStart??0),"ms")}async initializeHashModule(){try{let{initHashModule:A}=await Promise.resolve().then(() => (b(),zA));this.hashModule=await A({preferWasm:this.config.hashVerification.preferWasm,onWasmLoaded:()=>{this.log("WASM hash module loaded"),this.config.hashVerification.onWasmLoaded?.()},onFallback:(B)=>{this.log("Using JS hash fallback:",B),this.config.hashVerification.onWasmFallback?.(B)}})}catch(A){this.log("Failed to initialize hash module",A)}}async initializeChallengeManager(){try{let{ChallengeManager:A}=await Promise.resolve().then(() => ($A(),HA));this.challengeManager=new A(this.config.challenge,this.config.debug),this.log("Challenge manager loaded")}catch(A){this.log("Failed to initialize challenge manager",A)}}async start(){if(this.isRunning){this.log("Already running");return}J.markStartCalled(),this.log("Starting BotSigged SDK"),this.isRunning=!0,this.connectionState="connecting";try{this.browserSignal=this.browserCollector.collect(),J.markFormCollectorStart(),this.mouseCollector.start(),this.scrollCollector.start(),this.formCollector.start(),J.markFormCollectorReady(),this.log("Collectors started in",(J.getTimings().formCollectorReady??0)-(J.getTimings().formCollectorStart??0),"ms"),J.markFingerprintStart(),J.markWsConnectStart();let[A]=await Promise.all([this.fingerprintGenerator.generate(),this.connectWithRetry()]);this.fingerprint=A,J.markFingerprintEnd(),this.log("Fingerprint generated in",(J.getTimings().fingerprintEnd??0)-(J.getTimings().fingerprintStart??0),"ms"),await this.joinChannel(),this.connectionState="connected",this.readyResolver?.(),J.markSdkReady(),this.startSendInterval(),this.registerBeforeUnload();let B=J.getSummary();if(this.log("SDK started successfully"),this.log("Total startup time:",B.totalStartupMs,"ms"),this.log("Time to first score:",B.timeToFirstScoreMs,"ms"),this.log("Vulnerability window:",B.vulnerabilityWindowMs,"ms"),this.config.debug)J.logSummary()}catch(A){let B=A instanceof Error?A:Error(String(A));this.log("Failed to start",B),this.handleConnectionFailure(B)}}async stop(){if(!this.isRunning)return;if(this.log("Stopping BotSigged SDK"),this.formProtectionManager)this.formProtectionManager.destroy(),this.formProtectionManager=null;if(this.cookieManager)this.cookieManager.removeCookies(),this.cookieManager=null;if(this.headerInjector)this.headerInjector.stop(),this.headerInjector=null;if(this.formInjector)this.formInjector.stop(),this.formInjector=null;if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;this.unregisterBeforeUnload(),this.mouseCollector.stop(),this.scrollCollector.stop(),this.formCollector.stop(),this.stopSendInterval(),await this.sendSignal(),await this.disconnect(),this.isRunning=!1,this.log("SDK stopped")}async sendSignal(){if(!this.socket?.isReady()){this.log("Cannot send signal: not connected");return}let A=this.buildPayload(),B=A.seq;this.log("Sending signal seq:",B),J.markSignalSent(B);try{let Q=await this.socket.sendSignal(A);J.markSignalResponseReceived(B);let E=J.getTimings().signalRoundtrips||[],I=E[E.length-1];if(I)this.log("Signal roundtrip:",I.roundtripMs,"ms");if(Q.bot_score!==void 0){let C={bot_score:Q.bot_score,classification:Q.classification||"unknown",triggered_rules:Q.triggered_rules||[]};this.lastScore=C,this.config.onScoreUpdate?.(C),this.handleScoreUpdate(C)}this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush(),this.hasSentInitial=!0}catch(Q){let E=Q instanceof Error?Q:Error(String(Q));this.log("Failed to send signal",E),this.config.onError?.(E)}}async sendSignalAndGetScore(){if(!this.socket?.isReady())return this.log("Cannot send signal: not connected"),null;let A=this.buildPayload(),B=A.seq;this.log("Sending signal for form scoring, seq:",B);try{let Q=await this.socket.sendSignal(A);if(Q.bot_score!==void 0){let E={bot_score:Q.bot_score,classification:Q.classification||"unknown",triggered_rules:Q.triggered_rules||[]};return this.lastScore=E,this.config.onScoreUpdate?.(E),this.handleScoreUpdate(E),this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush(),this.hasSentInitial=!0,E.bot_score}return this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush(),this.hasSentInitial=!0,null}catch(Q){let E=Q instanceof Error?Q:Error(String(Q));return this.log("Failed to send signal for form scoring",E),this.config.onError?.(E),null}}getSessionId(){return this.sessionId}getFingerprint(){return this.fingerprint}getFormSubmissionStatus(){return this.formSubmissionStatus}getLastScore(){return this.lastScore}isConnected(){return this.socket?.isReady()??!1}whenReady(){if(this.connectionState==="connected")return Promise.resolve();return this.readyPromise}getConnectionState(){return this.connectionState}getServerConfig(){return this.serverConfig}async identify(A){let{accountId:B}=A;if(!B||typeof B!=="string")throw Error("BotSigged: accountId is required and must be a string");if(B.length>255)throw Error("BotSigged: accountId must be 255 characters or less");this.log("Identifying account:",B),await this.whenReady();try{let Q=await this.socket.sendEvent("identify",{account_id:B,timestamp:Date.now()});if(Q.identified)this.log("Account identified successfully");else throw Error(Q.reason?.toString()||"Failed to identify account")}catch(Q){let E=Q instanceof Error?Q:Error(String(Q));throw this.log("Failed to identify account:",E),this.config.onError?.(E),E}}isDegraded(){return this.connectionState==="degraded"||this.connectionState==="failed"}getCurrentSignals(){return{mouse:this.mouseCollector.getSignal(),scroll:this.scrollCollector.getSignal(),form:this.formCollector.getSignal(),browser:this.browserSignal}}getBufferSizes(){return{mouse:this.mouseCollector.getBufferSize(),scroll:this.scrollCollector.getBufferSize(),form:this.formCollector.getBufferSize()}}resetSignals(){this.mouseCollector.reset(),this.scrollCollector.reset(),this.formCollector.reset(),this.browserCollector.reset(),this.sequenceNumber=0,this.hasSentInitial=!1}async connectSocket(){this.socket=new t({endpoint:this.config.endpoint,apiKey:this.config.apiKey,debug:this.config.debug,onConnectionChange:(A)=>{this.config.onConnectionChange?.(A==="connected")},onError:(A)=>{this.config.onError?.(A)}}),await this.socket.connect(),J.markWsConnectEnd(),this.log("WebSocket connected in",(J.getTimings().wsConnectEnd??0)-(J.getTimings().wsConnectStart??0),"ms")}async connectWithRetry(){let B=[1000,2000,4000];for(let Q=0;Q<3;Q++)try{await this.connectSocket();return}catch(E){if(this.log(`Connection attempt ${Q+1} failed:`,E),Q<2)await this.sleep(B[Q]);else throw E}}sleep(A){return new Promise((B)=>setTimeout(B,A))}handleConnectionFailure(A){this.connectionState="failed";let B=this.config.fallbackMode||"degraded";switch(this.log("Connection failed, applying fallback mode:",B),B){case"open":if(this.connectionState="degraded",this.formProtectionManager)this.formProtectionManager.setMode("none"),this.formProtectionManager.notifyReady(0);break;case"closed":this.blockFormsUntilConnected(),this.scheduleReconnect();break;case"cached":let Q=this.loadCachedConfig();if(Q)this.applyServerConfig(Q),this.connectionState="degraded";else this.applyFallbackConfig();this.scheduleReconnect();break;case"degraded":default:this.applyFallbackConfig(),this.connectionState="degraded",this.scheduleReconnect();break}this.config.onError?.(A),this.config.onConnectionChange?.(!1)}applyFallbackConfig(){if(this.log("Applying fallback config"),this.serverConfig=GA,this.formProtectionManager&&this.serverConfig.form_protection_mode)this.formProtectionManager.setMode(this.serverConfig.form_protection_mode);this.config.onServerConfig?.(this.serverConfig,"fallback")}blockFormsUntilConnected(){if(this.formProtectionManager)this.formProtectionManager.setMode("holdUntilReady"),this.formProtectionManager.setMaxHoldTime(30000)}scheduleReconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer);this.reconnectTimer=setTimeout(()=>{this.attemptReconnect()},5000)}async attemptReconnect(){this.log("Attempting reconnection..."),this.connectionState="connecting";try{if(await this.connectWithRetry(),!this.fingerprint)this.fingerprint=await this.fingerprintGenerator.generate();if(await this.joinChannel(),this.connectionState="connected",this.readyResolver?.(),this.log("Reconnection successful"),!this.sendTimer)this.startSendInterval()}catch(A){this.log("Reconnection failed:",A),this.connectionState="failed"}}cacheServerConfig(A){try{localStorage.setItem(`botsigged_config_${this.config.apiKey}`,JSON.stringify({config:A,timestamp:Date.now()}))}catch{}}loadCachedConfig(){try{let A=localStorage.getItem(`botsigged_config_${this.config.apiKey}`);if(!A)return null;let{config:B,timestamp:Q}=JSON.parse(A);if(Date.now()-Q>86400000)return localStorage.removeItem(`botsigged_config_${this.config.apiKey}`),null;return B}catch{return null}}applyServerConfig(A){if(this.log("Applying server config:",A),this.serverConfig=A,this.formProtectionManager&&A.form_protection_mode)this.formProtectionManager.setMode(A.form_protection_mode);if(A.action&&A.action!=="none")this.applyServerAction(A.action,A.challenge);this.cacheServerConfig(A),this.config.onServerConfig?.(A,"server")}async applyServerAction(A,B){switch(this.log("Applying server action:",A),A){case"block":if(!this.formBlocked)this.blockForms();break;case"challenge":if(!this.challengeManager&&!this.challengeManagerPromise)this.log("Lazily loading challenge manager for server-requested challenge"),this.challengeManagerPromise=this.initializeChallengeManager();if(this.challengeManagerPromise)await this.challengeManagerPromise;if(this.challengeManager){let Q=B?.difficulty?.bot??16,E=Q>=18?"critical":Q>=16?"high":"medium";this.challengeManager.blockFormsUntilSolved(E)}else this.log("Challenge requested but challenge manager failed to load");break;case"flag":this.log("Session flagged by server");break;case"none":default:break}}handleServerAction(A){this.log("Received server action:",A),this.config.onServerAction?.(A);let B=A.challenge?{difficulty:{suspicious:A.challenge.difficulty,bot:A.challenge.difficulty},timeout_ms:A.challenge.timeout_ms}:void 0;this.applyServerAction(A.type,B)}async joinChannel(){if(!this.socket)throw Error("WebSocket not initialized");J.markChannelJoinStart();let A;try{A=await this.socket.joinChannel(this.sessionId,this.fingerprint,this.getSessionData(),this.browserSignal,{onScoreUpdate:(B)=>{this.lastScore=B,this.config.onScoreUpdate?.(B),this.handleScoreUpdate(B)},onError:(B)=>{this.config.onError?.(B)},onAction:(B)=>{this.handleServerAction(B)}},this.config.accountId)}catch(B){if(YA(B)){if(this.log("Usage limit exceeded:",B),this.config.onUsageLimitExceeded)this.config.onUsageLimitExceeded(B);else this.config.onError?.(Error(`Usage limit exceeded: ${B.current_usage}/${B.limit} verifications (${B.plan_name} plan). Please upgrade your plan.`));return}throw B}if(J.markChannelJoinEnd(),this.log("Channel joined in",(J.getTimings().channelJoinEnd??0)-(J.getTimings().channelJoinStart??0),"ms"),A.config){let B=A.config;this.applyServerConfig(B)}if(A.initial_score!==void 0){J.markInitialScoreReceived();let B={bot_score:A.initial_score,classification:A.classification||"unknown",triggered_rules:A.triggered_rules||[]};if(this.lastScore=B,this.config.onScoreUpdate?.(B),this.handleScoreUpdate(B),this.formProtectionManager)this.formProtectionManager.notifyReady(B.bot_score);if(this.cookieManager)this.cookieManager.setCookie();this.log("Initial score received:",B.bot_score,"in",(J.getTimings().initialScoreReceived??0)-(J.getTimings().startCalled??0),"ms from start")}}handleScoreUpdate(A){if(this.cookieManager)this.cookieManager.updateRiskTier(A.bot_score);let B=this.getBotScoreLevel(A.bot_score),Q=A.bot_score>=this.config.actionThreshold;if(this.shouldTriggerAlert(B)){let E={score:A.bot_score,level:B,scoreUpdate:A,sessionId:this.sessionId,fingerprintHash:this.fingerprint?.hash};if(Q&&!this.highScoreTriggeredLevels.has(B))this.executeAction(E);this.config.onHighBotScore?.(E),this.highScoreTriggeredLevels.add(B)}}getBotScoreLevel(A){let B=this.config.botScoreThresholds;if(A>=B.critical)return"critical";if(A>=B.high)return"high";if(A>=B.medium)return"medium";return"low"}shouldTriggerAlert(A){if(this.highScoreTriggeredLevels.has(A))return!1;let B=["low","medium","high","critical"],Q=this.config.minAlertLevel,E=B.indexOf(A),I=B.indexOf(Q);return E>=I}async executeAction(A){let B=this.config.action;switch(this.log(`Executing action '${B}' for score ${A.score}`),B){case"challenge":if(this.challengeManagerPromise)await this.challengeManagerPromise;if(this.challengeManager)this.challengeManager.blockFormsUntilSolved(A.level);break;case"block":if(!this.formBlocked)this.blockForms();break;case"none":default:break}}blockForms(){if(this.formBlocked)return;this.formBlocked=!0,document.querySelectorAll("form").forEach((A)=>{A.addEventListener("submit",this.blockFormSubmit,!0)}),this.formObserver=new MutationObserver((A)=>{A.forEach((B)=>{B.addedNodes.forEach((Q)=>{if(Q instanceof HTMLFormElement)Q.addEventListener("submit",this.blockFormSubmit,!0);if(Q instanceof HTMLElement)Q.querySelectorAll("form").forEach((E)=>{E.addEventListener("submit",this.blockFormSubmit,!0)})})})}),this.formObserver.observe(document.body,{childList:!0,subtree:!0}),this.log("Forms blocked due to high bot score")}blockFormSubmit=(A)=>{A.preventDefault(),A.stopPropagation(),this.log("Form submission blocked due to high bot score");return};isFormsBlocked(){return this.formBlocked}unblockForms(){if(!this.formBlocked)return;if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;document.querySelectorAll("form").forEach((A)=>{A.removeEventListener("submit",this.blockFormSubmit,!0)}),this.formBlocked=!1,this.log("Forms unblocked")}getHashModule(){return this.hashModule}createSignature(A){let B=this.config.hashVerification.secret;if(!B)return this.log("Cannot create signature: no secret configured"),null;return createSignature(A,B)}verifySignature(A,B){let Q=this.config.hashVerification.secret;if(!Q)return this.log("Cannot verify signature: no secret configured"),!1;return verifySignature(A,B,Q)}isChallengeSolving(){return this.challengeManager?.isSolving()??!1}isChallengeSolved(){return this.challengeManager?.isSolved()??!1}getPerformanceSummary(){return J.getSummary()}logPerformance(){J.logSummary()}getPerformanceReport(){return J.getReport()}async waitUntilReady(){if(this.lastScore)return{score:this.lastScore.bot_score,timedOut:!1};if(this.formProtectionManager)return this.formProtectionManager.waitUntilReady();return new Promise((A)=>{let B=performance.now(),Q=5000,E=()=>{if(this.lastScore){A({score:this.lastScore.bot_score,timedOut:!1});return}if(performance.now()-B>=5000){A({score:null,timedOut:!0});return}setTimeout(E,50)};E()})}withProtection(A,B={}){let Q=B.blockThreshold??this.config.actionThreshold;return async(...E)=>{let{score:I,timedOut:C}=await this.waitUntilReady();if(J.markFirstSubmitAttempt(I!==null),I!==null&&I>=Q)throw this.log(`Blocking submission: score ${I} >= threshold ${Q}`),Error(`Submission blocked: bot score ${I} exceeds threshold`);if(C)this.log("Warning: submitting without detection score (timed out)");return A(...E)}}protectedFetch(A={}){return this.withProtection(async(B,Q)=>{return fetch(B,Q)},A)}canSubmit(){if(!this.lastScore)return{allowed:!1,reason:"waiting_for_score",score:null};if(this.lastScore.bot_score>=this.config.actionThreshold)return{allowed:!1,reason:"high_bot_score",score:this.lastScore.bot_score};return{allowed:!0,score:this.lastScore.bot_score}}async triggerChallenge(A="high"){if(this.challengeManagerPromise)await this.challengeManagerPromise;if(!this.challengeManager){this.log("Challenge not enabled");return}this.challengeManager.blockFormsUntilSolved(A)}async disconnect(){if(this.socket)await this.socket.leaveChannel(),this.socket.disconnect(),this.socket=null}startSendInterval(){this.stopSendInterval(),this.sendTimer=setInterval(()=>{this.sendSignal()},this.config.sendInterval)}stopSendInterval(){if(this.sendTimer)clearInterval(this.sendTimer),this.sendTimer=null}registerBeforeUnload(){this.boundBeforeUnload=()=>{this.handleBeforeUnload()},this.boundVisibilityChange=()=>{if(document.visibilityState==="hidden")this.handleBeforeUnload()},window.addEventListener("beforeunload",this.boundBeforeUnload),document.addEventListener("visibilitychange",this.boundVisibilityChange)}unregisterBeforeUnload(){if(this.boundBeforeUnload)window.removeEventListener("beforeunload",this.boundBeforeUnload),this.boundBeforeUnload=null;if(this.boundVisibilityChange)document.removeEventListener("visibilitychange",this.boundVisibilityChange),this.boundVisibilityChange=null}handleBeforeUnload(){if(!this.isRunning||!this.socket)return;try{let A=this.buildPayload();if(this.socket.isReady())this.socket.sendSignal(A).catch(()=>{})}catch{}}handleFormSubmit(){if(!this.isRunning)return;if(J.markFirstSubmitAttempt(this.lastScore!==null),this.log("Form submitted, flushing signals via beacon"),this.log("Had score before submit:",this.lastScore!==null),this.updateFormStatus("completed"),!this.sessionId){this.log("No session ID yet, cannot send beacon");return}let A=this.buildPayload();if(!this.sendViaBeacon(A))this.sendSignal().catch((Q)=>{this.log("Failed to flush signals on form submit",Q)});else this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush()}sendViaBeacon(A){if(!navigator.sendBeacon)return this.log("sendBeacon not available"),!1;try{let B=new URL(this.config.endpoint),Q=`${B.protocol==="wss:"?"https:":"http:"}//${B.host}/api/signal`,E=JSON.stringify({session_id:this.sessionId,api_key:this.config.apiKey,payload:A,form_status:this.formSubmissionStatus}),I=new Blob([E],{type:"application/json"}),C=navigator.sendBeacon(Q,I);return this.log("Beacon sent:",C),C}catch(B){return this.log("Beacon send failed:",B),!1}}buildPayload(){this.sequenceNumber++;let A={session_id:this.sessionId,seq:this.sequenceNumber,mouse:this.mouseCollector.getSignal(),scroll:this.scrollCollector.getSignal(),form:this.formCollector.getSignal(),timestamp:Date.now()};if(!this.hasSentInitial)A.session=this.getSessionData(),A.fingerprint=this.fingerprint,A.browser=this.browserSignal;return A}getSessionData(){let A=new URL(window.location.href),B={};A.searchParams.forEach((E,I)=>{B[I]=E});let Q=null;if(document.referrer)try{Q=new URL(document.referrer).hostname}catch{}return{url_path:A.pathname,url_params:B,referrer_url:document.referrer||null,referrer_domain:Q,user_agent:navigator.userAgent}}generateSessionId(){if(crypto.randomUUID)return crypto.randomUUID();return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(A)=>{let B=Math.random()*16|0;return(A==="x"?B:B&3|8).toString(16)})}updateFormStatus(A){if(this.formSubmissionStatus==="blocked"||this.formSubmissionStatus==="completed"){this.log(`Form status already terminal (${this.formSubmissionStatus}), ignoring ${A}`);return}if(this.formSubmissionStatus==="challenged"&&A!=="completed"){this.log(`Form status is challenged, can only become completed, ignoring ${A}`);return}if(this.formSubmissionStatus=A,this.log(`Form status updated to: ${A}`),this.socket?.isReady())this.socket.sendFormStatus(A).catch((B)=>{this.log("Failed to send form status:",B)})}log(...A){if(this.config.debug);}}var k=null;function QA(A){if(k)return k;return k=new _(A),k}function EA(){return k}async function IA(){if(k)await k.stop(),k=null}var xA=Object.assign(_,{init:QA,getInstance:EA,destroy:IA});if(typeof window<"u")window.BotSigged=xA;})();
|
|
82
|
+
`,document.body.appendChild(this.loadingOverlay)}hideLoading(){if(this.loadingOverlay)this.loadingOverlay.remove(),this.loadingOverlay=null}notifyReady(A){this.isReady=!0,this.hasScore=!0,this.currentScore=A,[...this.pendingSubmissions].forEach((E)=>{this.releaseSubmission(E,!1)}),[...this.pendingRequests].forEach((E)=>{this.releaseRequest(E)}),this.hideLoading()}blockAllPending(A){[...this.pendingSubmissions].forEach((Q)=>{this.config.onBlock?.(Q.form,A),this.releaseSubmission(Q,!0)})}getStatus(){return{mode:this.config.mode,isReady:this.isReady,hasScore:this.hasScore,pendingCount:this.pendingSubmissions.length,protectedFormCount:this.protectedForms.size}}waitUntilReady(){if(this.hasScore)return Promise.resolve({score:this.currentScore,timedOut:!1});return new Promise((A)=>{let B=performance.now(),Q=()=>{if(this.hasScore){A({score:this.currentScore,timedOut:!1});return}if(performance.now()-B>=this.config.maxHoldTime){A({score:null,timedOut:!0});return}setTimeout(Q,50)};Q()})}withProtection(A){return async(...B)=>{let Q=performance.now()-this.startTime;if(O().markFirstSubmitAttempt(this.hasScore),this.config.mode==="blockInstant"&&Q<this.config.minTimeBeforeSubmit)throw this.config.onBlock?.(document.createElement("form"),"instant_submission"),Error("Submission blocked: too fast");if(this.config.mode==="holdUntilReady"&&!this.hasScore){if(this.config.showLoadingUI)this.showLoading(document.createElement("form"));let{timedOut:E}=await this.waitUntilReady();if(this.config.showLoadingUI)this.hideLoading()}return A(...B)}}protectedFetch(){return this.withProtection(async(A,B)=>{return fetch(A,B)})}setMode(A){if(this.config.mode=A,A==="none")[...this.pendingSubmissions].forEach((Q)=>this.releaseSubmission(Q,!1))}setMaxHoldTime(A){this.config.maxHoldTime=A}canSubmit(){let A=performance.now()-this.startTime;if(this.config.mode==="blockInstant"&&A<this.config.minTimeBeforeSubmit)return{allowed:!1,reason:"too_fast",score:this.currentScore};if(this.config.mode==="holdUntilReady"&&!this.hasScore)return{allowed:!1,reason:"waiting_for_score",score:null};return{allowed:!0,score:this.currentScore}}destroy(){if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;if(this.originalFetch)window.fetch=this.originalFetch,this.originalFetch=null;if(this.originalXHROpen)XMLHttpRequest.prototype.open=this.originalXHROpen,this.originalXHROpen=null;if(this.originalXHRSend)XMLHttpRequest.prototype.send=this.originalXHRSend,this.originalXHRSend=null;this.hideLoading(),this.pendingSubmissions=[],this.pendingRequests=[],this.protectedForms.clear()}}var KA={suspicious:40,bot:70},q={name:"_bsid",riskName:"_bsrisk",path:"/",sameSite:"Strict"};function WA(A){if(!A)return null;if(A===!0)return{...q};return{...q,...A}}function yA(A){if(A>=KA.bot)return"bot";if(A>=KA.suspicious)return"suspicious";return"human"}class r{config;sessionIdGetter;sessionCookieSet=!1;currentRiskTier=null;constructor(A,B){this.config={...q,...A},this.sessionIdGetter=B}buildCookieString(A,B){let Q=this.config.path||q.path,E=this.config.sameSite||q.sameSite,I=this.config.secure??location.protocol==="https:",C=[`${encodeURIComponent(A)}=${encodeURIComponent(B)}`,`Path=${Q}`,`SameSite=${E}`];if(I||E==="None")C.push("Secure");return C.join("; ")}deleteCookie(A){let B=this.config.path||q.path;document.cookie=`${encodeURIComponent(A)}=; Path=${B}; Max-Age=0`}setSessionCookie(){if(this.sessionCookieSet)return;let A=this.sessionIdGetter();if(!A)return;let B=this.config.name||q.name;document.cookie=this.buildCookieString(B,A),this.sessionCookieSet=!0}updateRiskTier(A){let B=yA(A);if(B===this.currentRiskTier)return!1;let Q=this.config.riskName||q.riskName;document.cookie=this.buildCookieString(Q,B);let E=this.currentRiskTier;return this.currentRiskTier=B,!0}removeCookies(){let A=this.config.name||q.name,B=this.config.riskName||q.riskName;if(this.sessionCookieSet)this.deleteCookie(A),this.sessionCookieSet=!1;if(this.currentRiskTier!==null)this.deleteCookie(B),this.currentRiskTier=null}setCookie(){this.setSessionCookie()}removeCookie(){this.removeCookies()}isSessionCookieSet(){return this.sessionCookieSet}getCurrentRiskTier(){return this.currentRiskTier}getSessionCookieName(){return this.config.name||q.name}getRiskCookieName(){return this.config.riskName||q.riskName}}var F={name:"X-BotSigged-ID"};function qA(A){if(!A)return null;if(A===!0)return{...F};return{...F,...A}}class e{config;sessionIdGetter;started=!1;originalFetch=null;originalXHROpen=null;originalXHRSend=null;originalXHRSetRequestHeader=null;xhrInjectionMap=new WeakMap;constructor(A,B){this.config={...F,...A},this.sessionIdGetter=B}start(){if(this.started)return;this.started=!0,this.patchFetch(),this.patchXHR()}stop(){if(!this.started)return;if(this.originalFetch)window.fetch=this.originalFetch,this.originalFetch=null;if(this.originalXHROpen)XMLHttpRequest.prototype.open=this.originalXHROpen,this.originalXHROpen=null;if(this.originalXHRSend)XMLHttpRequest.prototype.send=this.originalXHRSend,this.originalXHRSend=null;if(this.originalXHRSetRequestHeader)XMLHttpRequest.prototype.setRequestHeader=this.originalXHRSetRequestHeader,this.originalXHRSetRequestHeader=null;this.started=!1}isSameOrigin(A){try{let B;if(A instanceof Request)B=new URL(A.url,window.location.origin);else if(A instanceof URL)B=A;else B=new URL(A,window.location.origin);return B.origin===window.location.origin}catch{return!0}}patchFetch(){this.originalFetch=window.fetch.bind(window);let A=this,B=this.config.name||F.name;window.fetch=function(Q,E){if(!A.isSameOrigin(Q))return A.originalFetch(Q,E);let I=A.sessionIdGetter();if(!I)return A.originalFetch(Q,E);let C=new Headers(E?.headers);if(!C.has(B))C.set(B,I);return A.originalFetch(Q,{...E,headers:C})}}patchXHR(){this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send,this.originalXHRSetRequestHeader=XMLHttpRequest.prototype.setRequestHeader;let A=this,B=this.config.name||F.name;XMLHttpRequest.prototype.open=function(Q,E,I=!0,C,Y){let G=A.isSameOrigin(E);return A.xhrInjectionMap.set(this,G),A.originalXHROpen.call(this,Q,E,I,C,Y)},XMLHttpRequest.prototype.send=function(Q){if(A.xhrInjectionMap.get(this)){let E=A.sessionIdGetter();if(E)try{A.originalXHRSetRequestHeader.call(this,B,E)}catch{}}return A.originalXHRSend.call(this,Q)}}getHeaderName(){return this.config.name||F.name}isStarted(){return this.started}}var L={selector:"form",inputName:"_bsid"};function VA(A){if(!A)return null;if(A===!0)return{...L};return{...L,...A}}class AA{config;sessionIdGetter;observer=null;started=!1;constructor(A,B){this.config={...L,...A},this.sessionIdGetter=B}start(){if(this.started)return;this.started=!0;let A=()=>{this.setupExistingForms(),this.setupObserver()};if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",A,{once:!0});else A()}stop(){if(!this.started)return;if(this.observer)this.observer.disconnect(),this.observer=null;let A=this.config.selector||L.selector,B=this.config.inputName||L.inputName;document.querySelectorAll(`${A}[data-bs-inject-setup]`).forEach((Q)=>{if(Q instanceof HTMLFormElement)Q.removeEventListener("submit",this.handleSubmit,{capture:!0});Q.removeAttribute("data-bs-inject-setup");let E=Q.querySelector(`input[name="${B}"][data-bs-injected]`);if(E)E.remove()}),this.started=!1}setupExistingForms(){let A=this.config.selector||L.selector;document.querySelectorAll(A).forEach((B)=>{if(B instanceof HTMLFormElement)this.setupForm(B)})}setupObserver(){if(!document.body)return;let A=this.config.selector||L.selector;this.observer=new MutationObserver((B)=>{B.forEach((Q)=>{Q.addedNodes.forEach((E)=>{if(E instanceof HTMLFormElement&&E.matches(A))this.setupForm(E);if(E instanceof HTMLElement)E.querySelectorAll(A).forEach((I)=>{if(I instanceof HTMLFormElement)this.setupForm(I)})})})}),this.observer.observe(document.body,{childList:!0,subtree:!0})}setupForm(A){if(A.hasAttribute("data-bs-inject-setup"))return;A.setAttribute("data-bs-inject-setup","true"),A.addEventListener("submit",this.handleSubmit,{capture:!0})}handleSubmit=(A)=>{let B=A.currentTarget;this.injectInput(B)};injectInput(A){let B=this.config.inputName||L.inputName,Q=A.querySelector(`input[name="${B}"]`);if(Q){if(Q.hasAttribute("data-bs-injected"))Q.value=this.sessionIdGetter();return}let E=document.createElement("input");E.type="hidden",E.name=B,E.value=this.sessionIdGetter(),E.setAttribute("data-bs-injected","true"),A.appendChild(E)}getConfig(){return{...this.config}}isStarted(){return this.started}}class _{config;mouseCollector;scrollCollector;formCollector;browserCollector;fingerprintGenerator;socket=null;sessionId;sequenceNumber=0;isRunning=!1;sendTimer=null;fingerprint=null;browserSignal=null;lastScore=null;hasSentInitial=!1;boundBeforeUnload=null;boundVisibilityChange=null;hashModule=null;formBlocked=!1;formObserver=null;highScoreTriggeredLevels=new Set;challengeManager=null;challengeManagerPromise=null;formProtectionManager=null;formSubmissionStatus="no_submission";cookieManager=null;headerInjector=null;formInjector=null;serverConfig=null;connectionState="disconnected";reconnectTimer=null;readyPromise;readyResolver=null;constructor(A){if(J.markConstructorStart(),!A.apiKey)throw Error("BotSigged: apiKey is required");if(this.config=JA(A),this.sessionId=this.generateSessionId(),this.readyPromise=new Promise((I)=>{this.readyResolver=I}),this.mouseCollector=new p({sampleRate:this.config.mouseSampleRate,maxBufferSize:this.config.maxBufferSize}),this.scrollCollector=new m({maxBufferSize:Math.floor(this.config.maxBufferSize/3)}),this.formCollector=new d({maxKeyEvents:this.config.maxBufferSize,onSubmit:()=>this.handleFormSubmit()}),this.browserCollector=new f,this.fingerprintGenerator=new n,this.config.hashVerification.enabled)this.initializeHashModule();if(this.config.action==="challenge"||this.config.challenge.enabled)this.challengeManagerPromise=this.initializeChallengeManager();if(this.config.formProtection.mode!=="none")this.formProtectionManager=new o({mode:this.config.formProtection.mode,minTimeBeforeSubmit:this.config.formProtection.minTimeBeforeSubmit,maxHoldTime:this.config.formProtection.maxHoldTime,showLoadingUI:this.config.formProtection.showLoadingUI,loadingMessage:this.config.formProtection.loadingMessage,onHold:(I)=>{this.updateFormStatus("challenged"),this.config.formProtection.onHold?.(I)},onRelease:(I,C)=>{if(!C)this.updateFormStatus("completed");this.config.formProtection.onRelease?.(I,C)},onBlock:(I,C)=>{this.updateFormStatus("blocked"),this.config.formProtection.onBlock?.(I,C)},flushAndWaitForScore:()=>this.sendSignalAndGetScore()}),this.log("Form protection enabled:",this.config.formProtection.mode);else this.log("Form protection disabled (mode='none')");let B=WA(this.config.cookie);if(B)this.cookieManager=new r(B,()=>this.sessionId),this.log("Cookie manager enabled:",B.name);let Q=qA(this.config.headers);if(Q)this.headerInjector=new e(Q,()=>this.sessionId),this.headerInjector.start(),this.log("Header injector enabled:",Q.name);let E=VA(this.config.formInject);if(E)this.formInjector=new AA(E,()=>this.sessionId),this.formInjector.start(),this.log("Form injector enabled:",E.inputName);if(this.config.autoStart)if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",()=>this.start());else this.start();J.markConstructorEnd(),this.log("Constructor completed in",(J.getTimings().constructorEnd??0)-(J.getTimings().constructorStart??0),"ms")}async initializeHashModule(){try{let{initHashModule:A}=await Promise.resolve().then(() => (b(),zA));this.hashModule=await A({preferWasm:this.config.hashVerification.preferWasm,onWasmLoaded:()=>{this.log("WASM hash module loaded"),this.config.hashVerification.onWasmLoaded?.()},onFallback:(B)=>{this.log("Using JS hash fallback:",B),this.config.hashVerification.onWasmFallback?.(B)}})}catch(A){this.log("Failed to initialize hash module",A)}}async initializeChallengeManager(){try{let{ChallengeManager:A}=await Promise.resolve().then(() => ($A(),HA));this.challengeManager=new A(this.config.challenge,this.config.debug),this.log("Challenge manager loaded")}catch(A){this.log("Failed to initialize challenge manager",A)}}async start(){if(this.isRunning){this.log("Already running");return}J.markStartCalled(),this.log("Starting BotSigged SDK"),this.isRunning=!0,this.connectionState="connecting";try{this.browserSignal=this.browserCollector.collect(),J.markFormCollectorStart(),this.mouseCollector.start(),this.scrollCollector.start(),this.formCollector.start(),J.markFormCollectorReady(),this.log("Collectors started in",(J.getTimings().formCollectorReady??0)-(J.getTimings().formCollectorStart??0),"ms"),J.markFingerprintStart(),J.markWsConnectStart();let[A]=await Promise.all([this.fingerprintGenerator.generate(),this.connectWithRetry()]);this.fingerprint=A,J.markFingerprintEnd(),this.log("Fingerprint generated in",(J.getTimings().fingerprintEnd??0)-(J.getTimings().fingerprintStart??0),"ms"),await this.joinChannel(),this.connectionState="connected",this.readyResolver?.(),J.markSdkReady(),this.startSendInterval(),this.registerBeforeUnload();let B=J.getSummary();if(this.log("SDK started successfully"),this.log("Total startup time:",B.totalStartupMs,"ms"),this.log("Time to first score:",B.timeToFirstScoreMs,"ms"),this.log("Vulnerability window:",B.vulnerabilityWindowMs,"ms"),this.config.debug)J.logSummary()}catch(A){let B=A instanceof Error?A:Error(String(A));this.log("Failed to start",B),this.handleConnectionFailure(B)}}async stop(){if(!this.isRunning)return;if(this.log("Stopping BotSigged SDK"),this.formProtectionManager)this.formProtectionManager.destroy(),this.formProtectionManager=null;if(this.cookieManager)this.cookieManager.removeCookies(),this.cookieManager=null;if(this.headerInjector)this.headerInjector.stop(),this.headerInjector=null;if(this.formInjector)this.formInjector.stop(),this.formInjector=null;if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;this.unregisterBeforeUnload(),this.mouseCollector.stop(),this.scrollCollector.stop(),this.formCollector.stop(),this.stopSendInterval(),await this.sendSignal(),await this.disconnect(),this.isRunning=!1,this.log("SDK stopped")}async sendSignal(){if(!this.socket?.isReady()){this.log("Cannot send signal: not connected");return}let A=this.buildPayload(),B=A.seq;this.log("Sending signal seq:",B),J.markSignalSent(B);try{let Q=await this.socket.sendSignal(A);J.markSignalResponseReceived(B);let E=J.getTimings().signalRoundtrips||[],I=E[E.length-1];if(I)this.log("Signal roundtrip:",I.roundtripMs,"ms");if(Q.bot_score!==void 0){let C={bot_score:Q.bot_score,classification:Q.classification||"unknown",triggered_rules:Q.triggered_rules||[]};this.lastScore=C,this.config.onScoreUpdate?.(C),this.handleScoreUpdate(C)}this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush(),this.hasSentInitial=!0}catch(Q){let E=Q instanceof Error?Q:Error(String(Q));this.log("Failed to send signal",E),this.config.onError?.(E)}}async sendSignalAndGetScore(){if(!this.socket?.isReady())return this.log("Cannot send signal: not connected"),null;let A=this.buildPayload(),B=A.seq;this.log("Sending signal for form scoring, seq:",B);try{let Q=await this.socket.sendSignal(A);if(Q.bot_score!==void 0){let E={bot_score:Q.bot_score,classification:Q.classification||"unknown",triggered_rules:Q.triggered_rules||[]};return this.lastScore=E,this.config.onScoreUpdate?.(E),this.handleScoreUpdate(E),this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush(),this.hasSentInitial=!0,E.bot_score}return this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush(),this.hasSentInitial=!0,null}catch(Q){let E=Q instanceof Error?Q:Error(String(Q));return this.log("Failed to send signal for form scoring",E),this.config.onError?.(E),null}}getSessionId(){return this.sessionId}getFingerprint(){return this.fingerprint}getFormSubmissionStatus(){return this.formSubmissionStatus}getLastScore(){return this.lastScore}isConnected(){return this.socket?.isReady()??!1}whenReady(){if(this.connectionState==="connected")return Promise.resolve();return this.readyPromise}getConnectionState(){return this.connectionState}getServerConfig(){return this.serverConfig}async identify(A){let{accountId:B}=A;if(!B||typeof B!=="string")throw Error("BotSigged: accountId is required and must be a string");if(B.length>255)throw Error("BotSigged: accountId must be 255 characters or less");this.log("Identifying account:",B),await this.whenReady();try{let Q=await this.socket.sendEvent("identify",{account_id:B,timestamp:Date.now()});if(Q.identified)this.log("Account identified successfully");else throw Error(Q.reason?.toString()||"Failed to identify account")}catch(Q){let E=Q instanceof Error?Q:Error(String(Q));throw this.log("Failed to identify account:",E),this.config.onError?.(E),E}}isDegraded(){return this.connectionState==="degraded"||this.connectionState==="failed"}getCurrentSignals(){return{mouse:this.mouseCollector.getSignal(),scroll:this.scrollCollector.getSignal(),form:this.formCollector.getSignal(),browser:this.browserSignal}}getBufferSizes(){return{mouse:this.mouseCollector.getBufferSize(),scroll:this.scrollCollector.getBufferSize(),form:this.formCollector.getBufferSize()}}resetSignals(){this.mouseCollector.reset(),this.scrollCollector.reset(),this.formCollector.reset(),this.browserCollector.reset(),this.sequenceNumber=0,this.hasSentInitial=!1}async connectSocket(){this.socket=new t({endpoint:this.config.endpoint,apiKey:this.config.apiKey,debug:this.config.debug,onConnectionChange:(A)=>{this.config.onConnectionChange?.(A==="connected")},onError:(A)=>{this.config.onError?.(A)}}),await this.socket.connect(),J.markWsConnectEnd(),this.log("WebSocket connected in",(J.getTimings().wsConnectEnd??0)-(J.getTimings().wsConnectStart??0),"ms")}async connectWithRetry(){let B=[1000,2000,4000];for(let Q=0;Q<3;Q++)try{await this.connectSocket();return}catch(E){if(this.log(`Connection attempt ${Q+1} failed:`,E),Q<2)await this.sleep(B[Q]);else throw E}}sleep(A){return new Promise((B)=>setTimeout(B,A))}handleConnectionFailure(A){this.connectionState="failed";let B=this.config.fallbackMode||"degraded";switch(this.log("Connection failed, applying fallback mode:",B),B){case"open":if(this.connectionState="degraded",this.formProtectionManager)this.formProtectionManager.setMode("none"),this.formProtectionManager.notifyReady(0);break;case"closed":this.blockFormsUntilConnected(),this.scheduleReconnect();break;case"cached":let Q=this.loadCachedConfig();if(Q)this.applyServerConfig(Q),this.connectionState="degraded";else this.applyFallbackConfig();this.scheduleReconnect();break;case"degraded":default:this.applyFallbackConfig(),this.connectionState="degraded",this.scheduleReconnect();break}this.config.onError?.(A),this.config.onConnectionChange?.(!1)}applyFallbackConfig(){if(this.log("Applying fallback config"),this.serverConfig=GA,this.formProtectionManager&&this.serverConfig.form_protection_mode)this.formProtectionManager.setMode(this.serverConfig.form_protection_mode);this.config.onServerConfig?.(this.serverConfig,"fallback")}blockFormsUntilConnected(){if(this.formProtectionManager)this.formProtectionManager.setMode("holdUntilReady"),this.formProtectionManager.setMaxHoldTime(30000)}scheduleReconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer);this.reconnectTimer=setTimeout(()=>{this.attemptReconnect()},5000)}async attemptReconnect(){this.log("Attempting reconnection..."),this.connectionState="connecting";try{if(await this.connectWithRetry(),!this.fingerprint)this.fingerprint=await this.fingerprintGenerator.generate();if(await this.joinChannel(),this.connectionState="connected",this.readyResolver?.(),this.log("Reconnection successful"),!this.sendTimer)this.startSendInterval()}catch(A){this.log("Reconnection failed:",A),this.connectionState="failed"}}cacheServerConfig(A){try{localStorage.setItem(`botsigged_config_${this.config.apiKey}`,JSON.stringify({config:A,timestamp:Date.now()}))}catch{}}loadCachedConfig(){try{let A=localStorage.getItem(`botsigged_config_${this.config.apiKey}`);if(!A)return null;let{config:B,timestamp:Q}=JSON.parse(A);if(Date.now()-Q>86400000)return localStorage.removeItem(`botsigged_config_${this.config.apiKey}`),null;return B}catch{return null}}applyServerConfig(A){if(this.log("Applying server config:",A),this.serverConfig=A,this.formProtectionManager&&A.form_protection_mode)this.formProtectionManager.setMode(A.form_protection_mode);if(A.action&&A.action!=="none")this.applyServerAction(A.action,A.challenge);this.cacheServerConfig(A),this.config.onServerConfig?.(A,"server")}async applyServerAction(A,B){switch(this.log("Applying server action:",A),A){case"block":if(this.updateFormStatus("blocked"),!this.formBlocked)this.blockForms();break;case"challenge":if(this.updateFormStatus("challenged"),!this.challengeManager&&!this.challengeManagerPromise)this.log("Lazily loading challenge manager for server-requested challenge"),this.challengeManagerPromise=this.initializeChallengeManager();if(this.challengeManagerPromise)await this.challengeManagerPromise;if(this.challengeManager){let Q=B?.difficulty?.bot??16,E=Q>=18?"critical":Q>=16?"high":"medium";this.challengeManager.blockFormsUntilSolved(E)}else this.log("Challenge requested but challenge manager failed to load");break;case"flag":this.updateFormStatus("flagged"),this.log("Session flagged by server");break;case"none":default:break}}handleServerAction(A){this.log("Received server action:",A),this.config.onServerAction?.(A);let B=A.challenge?{difficulty:{suspicious:A.challenge.difficulty,bot:A.challenge.difficulty},timeout_ms:A.challenge.timeout_ms}:void 0;this.applyServerAction(A.type,B)}async joinChannel(){if(!this.socket)throw Error("WebSocket not initialized");J.markChannelJoinStart();let A;try{A=await this.socket.joinChannel(this.sessionId,this.fingerprint,this.getSessionData(),this.browserSignal,{onScoreUpdate:(B)=>{this.lastScore=B,this.config.onScoreUpdate?.(B),this.handleScoreUpdate(B)},onError:(B)=>{this.config.onError?.(B)},onAction:(B)=>{this.handleServerAction(B)}},this.config.accountId)}catch(B){if(YA(B)){if(this.log("Usage limit exceeded:",B),this.config.onUsageLimitExceeded)this.config.onUsageLimitExceeded(B);else this.config.onError?.(Error(`Usage limit exceeded: ${B.current_usage}/${B.limit} verifications (${B.plan_name} plan). Please upgrade your plan.`));return}throw B}if(J.markChannelJoinEnd(),this.log("Channel joined in",(J.getTimings().channelJoinEnd??0)-(J.getTimings().channelJoinStart??0),"ms"),A.config){let B=A.config;this.applyServerConfig(B)}if(A.initial_score!==void 0){J.markInitialScoreReceived();let B={bot_score:A.initial_score,classification:A.classification||"unknown",triggered_rules:A.triggered_rules||[]};if(this.lastScore=B,this.config.onScoreUpdate?.(B),this.handleScoreUpdate(B),this.formProtectionManager)this.formProtectionManager.notifyReady(B.bot_score);if(this.cookieManager)this.cookieManager.setCookie();this.log("Initial score received:",B.bot_score,"in",(J.getTimings().initialScoreReceived??0)-(J.getTimings().startCalled??0),"ms from start")}}handleScoreUpdate(A){if(this.cookieManager)this.cookieManager.updateRiskTier(A.bot_score);let B=this.getBotScoreLevel(A.bot_score),Q=A.bot_score>=this.config.actionThreshold;if(this.shouldTriggerAlert(B)){let E={score:A.bot_score,level:B,scoreUpdate:A,sessionId:this.sessionId,fingerprintHash:this.fingerprint?.hash};if(Q&&!this.highScoreTriggeredLevels.has(B))this.executeAction(E);this.config.onHighBotScore?.(E),this.highScoreTriggeredLevels.add(B)}}getBotScoreLevel(A){let B=this.config.botScoreThresholds;if(A>=B.critical)return"critical";if(A>=B.high)return"high";if(A>=B.medium)return"medium";return"low"}shouldTriggerAlert(A){if(this.highScoreTriggeredLevels.has(A))return!1;let B=["low","medium","high","critical"],Q=this.config.minAlertLevel,E=B.indexOf(A),I=B.indexOf(Q);return E>=I}async executeAction(A){let B=this.config.action;switch(this.log(`Executing action '${B}' for score ${A.score}`),B){case"challenge":if(this.challengeManagerPromise)await this.challengeManagerPromise;if(this.challengeManager)this.challengeManager.blockFormsUntilSolved(A.level);break;case"block":if(!this.formBlocked)this.blockForms();break;case"none":default:break}}blockForms(){if(this.formBlocked)return;this.formBlocked=!0,document.querySelectorAll("form").forEach((A)=>{A.addEventListener("submit",this.blockFormSubmit,!0)}),this.formObserver=new MutationObserver((A)=>{A.forEach((B)=>{B.addedNodes.forEach((Q)=>{if(Q instanceof HTMLFormElement)Q.addEventListener("submit",this.blockFormSubmit,!0);if(Q instanceof HTMLElement)Q.querySelectorAll("form").forEach((E)=>{E.addEventListener("submit",this.blockFormSubmit,!0)})})})}),this.formObserver.observe(document.body,{childList:!0,subtree:!0}),this.log("Forms blocked due to high bot score")}blockFormSubmit=(A)=>{A.preventDefault(),A.stopPropagation(),this.log("Form submission blocked due to high bot score");return};isFormsBlocked(){return this.formBlocked}unblockForms(){if(!this.formBlocked)return;if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;document.querySelectorAll("form").forEach((A)=>{A.removeEventListener("submit",this.blockFormSubmit,!0)}),this.formBlocked=!1,this.log("Forms unblocked")}getHashModule(){return this.hashModule}createSignature(A){let B=this.config.hashVerification.secret;if(!B)return this.log("Cannot create signature: no secret configured"),null;return createSignature(A,B)}verifySignature(A,B){let Q=this.config.hashVerification.secret;if(!Q)return this.log("Cannot verify signature: no secret configured"),!1;return verifySignature(A,B,Q)}isChallengeSolving(){return this.challengeManager?.isSolving()??!1}isChallengeSolved(){return this.challengeManager?.isSolved()??!1}getPerformanceSummary(){return J.getSummary()}logPerformance(){J.logSummary()}getPerformanceReport(){return J.getReport()}async waitUntilReady(){if(this.lastScore)return{score:this.lastScore.bot_score,timedOut:!1};if(this.formProtectionManager)return this.formProtectionManager.waitUntilReady();return new Promise((A)=>{let B=performance.now(),Q=5000,E=()=>{if(this.lastScore){A({score:this.lastScore.bot_score,timedOut:!1});return}if(performance.now()-B>=5000){A({score:null,timedOut:!0});return}setTimeout(E,50)};E()})}withProtection(A,B={}){let Q=B.blockThreshold??this.config.actionThreshold;return async(...E)=>{let{score:I,timedOut:C}=await this.waitUntilReady();if(J.markFirstSubmitAttempt(I!==null),I!==null&&I>=Q)throw this.log(`Blocking submission: score ${I} >= threshold ${Q}`),Error(`Submission blocked: bot score ${I} exceeds threshold`);if(C)this.log("Warning: submitting without detection score (timed out)");return A(...E)}}protectedFetch(A={}){return this.withProtection(async(B,Q)=>{return fetch(B,Q)},A)}canSubmit(){if(!this.lastScore)return{allowed:!1,reason:"waiting_for_score",score:null};if(this.lastScore.bot_score>=this.config.actionThreshold)return{allowed:!1,reason:"high_bot_score",score:this.lastScore.bot_score};return{allowed:!0,score:this.lastScore.bot_score}}async triggerChallenge(A="high"){if(this.challengeManagerPromise)await this.challengeManagerPromise;if(!this.challengeManager){this.log("Challenge not enabled");return}this.challengeManager.blockFormsUntilSolved(A)}async disconnect(){if(this.socket)await this.socket.leaveChannel(),this.socket.disconnect(),this.socket=null}startSendInterval(){this.stopSendInterval(),this.sendTimer=setInterval(()=>{this.sendSignal()},this.config.sendInterval)}stopSendInterval(){if(this.sendTimer)clearInterval(this.sendTimer),this.sendTimer=null}registerBeforeUnload(){this.boundBeforeUnload=()=>{this.handleBeforeUnload()},this.boundVisibilityChange=()=>{if(document.visibilityState==="hidden")this.handleBeforeUnload()},window.addEventListener("beforeunload",this.boundBeforeUnload),document.addEventListener("visibilitychange",this.boundVisibilityChange)}unregisterBeforeUnload(){if(this.boundBeforeUnload)window.removeEventListener("beforeunload",this.boundBeforeUnload),this.boundBeforeUnload=null;if(this.boundVisibilityChange)document.removeEventListener("visibilitychange",this.boundVisibilityChange),this.boundVisibilityChange=null}handleBeforeUnload(){if(!this.isRunning||!this.socket)return;try{let A=this.buildPayload();if(this.socket.isReady())this.socket.sendSignal(A).catch(()=>{})}catch{}}handleFormSubmit(){if(!this.isRunning)return;if(J.markFirstSubmitAttempt(this.lastScore!==null),this.log("Form submitted, flushing signals via beacon"),this.log("Had score before submit:",this.lastScore!==null),this.updateFormStatus("completed"),!this.sessionId){this.log("No session ID yet, cannot send beacon");return}let A=this.buildPayload();if(!this.sendViaBeacon(A))this.sendSignal().catch((Q)=>{this.log("Failed to flush signals on form submit",Q)});else this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush()}sendViaBeacon(A){if(!navigator.sendBeacon)return this.log("sendBeacon not available"),!1;try{let B=new URL(this.config.endpoint),Q=`${B.protocol==="wss:"?"https:":"http:"}//${B.host}/api/signal`,E=JSON.stringify({session_id:this.sessionId,api_key:this.config.apiKey,payload:A,form_status:this.formSubmissionStatus}),I=new Blob([E],{type:"application/json"}),C=navigator.sendBeacon(Q,I);return this.log("Beacon sent:",C),C}catch(B){return this.log("Beacon send failed:",B),!1}}buildPayload(){this.sequenceNumber++;let A={session_id:this.sessionId,seq:this.sequenceNumber,mouse:this.mouseCollector.getSignal(),scroll:this.scrollCollector.getSignal(),form:this.formCollector.getSignal(),timestamp:Date.now()};if(!this.hasSentInitial)A.session=this.getSessionData(),A.fingerprint=this.fingerprint,A.browser=this.browserSignal;return A}getSessionData(){let A=new URL(window.location.href),B={};A.searchParams.forEach((E,I)=>{B[I]=E});let Q=null;if(document.referrer)try{Q=new URL(document.referrer).hostname}catch{}return{url_path:A.pathname,url_params:B,referrer_url:document.referrer||null,referrer_domain:Q,user_agent:navigator.userAgent}}generateSessionId(){if(crypto.randomUUID)return crypto.randomUUID();return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(A)=>{let B=Math.random()*16|0;return(A==="x"?B:B&3|8).toString(16)})}updateFormStatus(A){if(this.formSubmissionStatus==="challenged"||this.formSubmissionStatus==="flagged"||this.formSubmissionStatus==="blocked"||this.formSubmissionStatus==="completed"){this.log(`Form status already terminal (${this.formSubmissionStatus}), ignoring ${A}`);return}if(this.formSubmissionStatus=A,this.log(`Form status updated to: ${A}`),this.socket?.isReady())this.socket.sendFormStatus(A).catch((B)=>{this.log("Failed to send form status:",B)})}log(...A){if(this.config.debug);}}var k=null;function QA(A){if(k)return k;return k=new _(A),k}function EA(){return k}async function IA(){if(k)await k.stop(),k=null}var xA=Object.assign(_,{init:QA,getInstance:EA,destroy:IA});if(typeof window<"u")window.BotSigged=xA;})();
|
package/dist/index.js
CHANGED
|
@@ -37,6 +37,6 @@ import{a as y,b as U,d as v}from"./hash-q46pgar4.js";function T(Q){return typeof
|
|
|
37
37
|
to { transform: rotate(360deg); }
|
|
38
38
|
}
|
|
39
39
|
</style>
|
|
40
|
-
`,document.body.appendChild(this.loadingOverlay)}hideLoading(){if(this.loadingOverlay)this.loadingOverlay.remove(),this.loadingOverlay=null}notifyReady(Q){this.isReady=!0,this.hasScore=!0,this.currentScore=Q,[...this.pendingSubmissions].forEach((Z)=>{this.releaseSubmission(Z,!1)}),[...this.pendingRequests].forEach((Z)=>{this.releaseRequest(Z)}),this.hideLoading()}blockAllPending(Q){[...this.pendingSubmissions].forEach((Y)=>{this.config.onBlock?.(Y.form,Q),this.releaseSubmission(Y,!0)})}getStatus(){return{mode:this.config.mode,isReady:this.isReady,hasScore:this.hasScore,pendingCount:this.pendingSubmissions.length,protectedFormCount:this.protectedForms.size}}waitUntilReady(){if(this.hasScore)return Promise.resolve({score:this.currentScore,timedOut:!1});return new Promise((Q)=>{let X=performance.now(),Y=()=>{if(this.hasScore){Q({score:this.currentScore,timedOut:!1});return}if(performance.now()-X>=this.config.maxHoldTime){Q({score:null,timedOut:!0});return}setTimeout(Y,50)};Y()})}withProtection(Q){return async(...X)=>{let Y=performance.now()-this.startTime;if(N().markFirstSubmitAttempt(this.hasScore),this.config.mode==="blockInstant"&&Y<this.config.minTimeBeforeSubmit)throw this.config.onBlock?.(document.createElement("form"),"instant_submission"),Error("Submission blocked: too fast");if(this.config.mode==="holdUntilReady"&&!this.hasScore){if(this.config.showLoadingUI)this.showLoading(document.createElement("form"));let{timedOut:Z}=await this.waitUntilReady();if(this.config.showLoadingUI)this.hideLoading()}return Q(...X)}}protectedFetch(){return this.withProtection(async(Q,X)=>{return fetch(Q,X)})}setMode(Q){if(this.config.mode=Q,Q==="none")[...this.pendingSubmissions].forEach((Y)=>this.releaseSubmission(Y,!1))}setMaxHoldTime(Q){this.config.maxHoldTime=Q}canSubmit(){let Q=performance.now()-this.startTime;if(this.config.mode==="blockInstant"&&Q<this.config.minTimeBeforeSubmit)return{allowed:!1,reason:"too_fast",score:this.currentScore};if(this.config.mode==="holdUntilReady"&&!this.hasScore)return{allowed:!1,reason:"waiting_for_score",score:null};return{allowed:!0,score:this.currentScore}}destroy(){if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;if(this.originalFetch)window.fetch=this.originalFetch,this.originalFetch=null;if(this.originalXHROpen)XMLHttpRequest.prototype.open=this.originalXHROpen,this.originalXHROpen=null;if(this.originalXHRSend)XMLHttpRequest.prototype.send=this.originalXHRSend,this.originalXHRSend=null;this.hideLoading(),this.pendingSubmissions=[],this.pendingRequests=[],this.protectedForms.clear()}}var u={suspicious:40,bot:70},H={name:"_bsid",riskName:"_bsrisk",path:"/",sameSite:"Strict"};function d(Q){if(!Q)return null;if(Q===!0)return{...H};return{...H,...Q}}function a(Q){if(Q>=u.bot)return"bot";if(Q>=u.suspicious)return"suspicious";return"human"}class M{config;sessionIdGetter;sessionCookieSet=!1;currentRiskTier=null;constructor(Q,X){this.config={...H,...Q},this.sessionIdGetter=X}buildCookieString(Q,X){let Y=this.config.path||H.path,Z=this.config.sameSite||H.sameSite,$=this.config.secure??location.protocol==="https:",J=[`${encodeURIComponent(Q)}=${encodeURIComponent(X)}`,`Path=${Y}`,`SameSite=${Z}`];if($||Z==="None")J.push("Secure");return J.join("; ")}deleteCookie(Q){let X=this.config.path||H.path;document.cookie=`${encodeURIComponent(Q)}=; Path=${X}; Max-Age=0`}setSessionCookie(){if(this.sessionCookieSet)return;let Q=this.sessionIdGetter();if(!Q)return;let X=this.config.name||H.name;document.cookie=this.buildCookieString(X,Q),this.sessionCookieSet=!0}updateRiskTier(Q){let X=a(Q);if(X===this.currentRiskTier)return!1;let Y=this.config.riskName||H.riskName;document.cookie=this.buildCookieString(Y,X);let Z=this.currentRiskTier;return this.currentRiskTier=X,!0}removeCookies(){let Q=this.config.name||H.name,X=this.config.riskName||H.riskName;if(this.sessionCookieSet)this.deleteCookie(Q),this.sessionCookieSet=!1;if(this.currentRiskTier!==null)this.deleteCookie(X),this.currentRiskTier=null}setCookie(){this.setSessionCookie()}removeCookie(){this.removeCookies()}isSessionCookieSet(){return this.sessionCookieSet}getCurrentRiskTier(){return this.currentRiskTier}getSessionCookieName(){return this.config.name||H.name}getRiskCookieName(){return this.config.riskName||H.riskName}}var P={name:"X-BotSigged-ID"};function m(Q){if(!Q)return null;if(Q===!0)return{...P};return{...P,...Q}}class E{config;sessionIdGetter;started=!1;originalFetch=null;originalXHROpen=null;originalXHRSend=null;originalXHRSetRequestHeader=null;xhrInjectionMap=new WeakMap;constructor(Q,X){this.config={...P,...Q},this.sessionIdGetter=X}start(){if(this.started)return;this.started=!0,this.patchFetch(),this.patchXHR()}stop(){if(!this.started)return;if(this.originalFetch)window.fetch=this.originalFetch,this.originalFetch=null;if(this.originalXHROpen)XMLHttpRequest.prototype.open=this.originalXHROpen,this.originalXHROpen=null;if(this.originalXHRSend)XMLHttpRequest.prototype.send=this.originalXHRSend,this.originalXHRSend=null;if(this.originalXHRSetRequestHeader)XMLHttpRequest.prototype.setRequestHeader=this.originalXHRSetRequestHeader,this.originalXHRSetRequestHeader=null;this.started=!1}isSameOrigin(Q){try{let X;if(Q instanceof Request)X=new URL(Q.url,window.location.origin);else if(Q instanceof URL)X=Q;else X=new URL(Q,window.location.origin);return X.origin===window.location.origin}catch{return!0}}patchFetch(){this.originalFetch=window.fetch.bind(window);let Q=this,X=this.config.name||P.name;window.fetch=function(Y,Z){if(!Q.isSameOrigin(Y))return Q.originalFetch(Y,Z);let $=Q.sessionIdGetter();if(!$)return Q.originalFetch(Y,Z);let J=new Headers(Z?.headers);if(!J.has(X))J.set(X,$);return Q.originalFetch(Y,{...Z,headers:J})}}patchXHR(){this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send,this.originalXHRSetRequestHeader=XMLHttpRequest.prototype.setRequestHeader;let Q=this,X=this.config.name||P.name;XMLHttpRequest.prototype.open=function(Y,Z,$=!0,J,z){let W=Q.isSameOrigin(Z);return Q.xhrInjectionMap.set(this,W),Q.originalXHROpen.call(this,Y,Z,$,J,z)},XMLHttpRequest.prototype.send=function(Y){if(Q.xhrInjectionMap.get(this)){let Z=Q.sessionIdGetter();if(Z)try{Q.originalXHRSetRequestHeader.call(this,X,Z)}catch{}}return Q.originalXHRSend.call(this,Y)}}getHeaderName(){return this.config.name||P.name}isStarted(){return this.started}}var _={selector:"form",inputName:"_bsid"};function p(Q){if(!Q)return null;if(Q===!0)return{..._};return{..._,...Q}}class I{config;sessionIdGetter;observer=null;started=!1;constructor(Q,X){this.config={..._,...Q},this.sessionIdGetter=X}start(){if(this.started)return;this.started=!0;let Q=()=>{this.setupExistingForms(),this.setupObserver()};if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",Q,{once:!0});else Q()}stop(){if(!this.started)return;if(this.observer)this.observer.disconnect(),this.observer=null;let Q=this.config.selector||_.selector,X=this.config.inputName||_.inputName;document.querySelectorAll(`${Q}[data-bs-inject-setup]`).forEach((Y)=>{if(Y instanceof HTMLFormElement)Y.removeEventListener("submit",this.handleSubmit,{capture:!0});Y.removeAttribute("data-bs-inject-setup");let Z=Y.querySelector(`input[name="${X}"][data-bs-injected]`);if(Z)Z.remove()}),this.started=!1}setupExistingForms(){let Q=this.config.selector||_.selector;document.querySelectorAll(Q).forEach((X)=>{if(X instanceof HTMLFormElement)this.setupForm(X)})}setupObserver(){if(!document.body)return;let Q=this.config.selector||_.selector;this.observer=new MutationObserver((X)=>{X.forEach((Y)=>{Y.addedNodes.forEach((Z)=>{if(Z instanceof HTMLFormElement&&Z.matches(Q))this.setupForm(Z);if(Z instanceof HTMLElement)Z.querySelectorAll(Q).forEach(($)=>{if($ instanceof HTMLFormElement)this.setupForm($)})})})}),this.observer.observe(document.body,{childList:!0,subtree:!0})}setupForm(Q){if(Q.hasAttribute("data-bs-inject-setup"))return;Q.setAttribute("data-bs-inject-setup","true"),Q.addEventListener("submit",this.handleSubmit,{capture:!0})}handleSubmit=(Q)=>{let X=Q.currentTarget;this.injectInput(X)};injectInput(Q){let X=this.config.inputName||_.inputName,Y=Q.querySelector(`input[name="${X}"]`);if(Y){if(Y.hasAttribute("data-bs-injected"))Y.value=this.sessionIdGetter();return}let Z=document.createElement("input");Z.type="hidden",Z.name=X,Z.value=this.sessionIdGetter(),Z.setAttribute("data-bs-injected","true"),Q.appendChild(Z)}getConfig(){return{...this.config}}isStarted(){return this.started}}async function kQ(){return await import("./hash-q46pgar4.js")}class S{config;mouseCollector;scrollCollector;formCollector;browserCollector;fingerprintGenerator;socket=null;sessionId;sequenceNumber=0;isRunning=!1;sendTimer=null;fingerprint=null;browserSignal=null;lastScore=null;hasSentInitial=!1;boundBeforeUnload=null;boundVisibilityChange=null;hashModule=null;formBlocked=!1;formObserver=null;highScoreTriggeredLevels=new Set;challengeManager=null;challengeManagerPromise=null;formProtectionManager=null;formSubmissionStatus="no_submission";cookieManager=null;headerInjector=null;formInjector=null;serverConfig=null;connectionState="disconnected";reconnectTimer=null;readyPromise;readyResolver=null;constructor(Q){if(K.markConstructorStart(),!Q.apiKey)throw Error("BotSigged: apiKey is required");if(this.config=h(Q),this.sessionId=this.generateSessionId(),this.readyPromise=new Promise(($)=>{this.readyResolver=$}),this.mouseCollector=new k({sampleRate:this.config.mouseSampleRate,maxBufferSize:this.config.maxBufferSize}),this.scrollCollector=new x({maxBufferSize:Math.floor(this.config.maxBufferSize/3)}),this.formCollector=new C({maxKeyEvents:this.config.maxBufferSize,onSubmit:()=>this.handleFormSubmit()}),this.browserCollector=new L,this.fingerprintGenerator=new b,this.config.hashVerification.enabled)this.initializeHashModule();if(this.config.action==="challenge"||this.config.challenge.enabled)this.challengeManagerPromise=this.initializeChallengeManager();if(this.config.formProtection.mode!=="none")this.formProtectionManager=new D({mode:this.config.formProtection.mode,minTimeBeforeSubmit:this.config.formProtection.minTimeBeforeSubmit,maxHoldTime:this.config.formProtection.maxHoldTime,showLoadingUI:this.config.formProtection.showLoadingUI,loadingMessage:this.config.formProtection.loadingMessage,onHold:($)=>{this.updateFormStatus("challenged"),this.config.formProtection.onHold?.($)},onRelease:($,J)=>{if(!J)this.updateFormStatus("completed");this.config.formProtection.onRelease?.($,J)},onBlock:($,J)=>{this.updateFormStatus("blocked"),this.config.formProtection.onBlock?.($,J)},flushAndWaitForScore:()=>this.sendSignalAndGetScore()}),this.log("Form protection enabled:",this.config.formProtection.mode);else this.log("Form protection disabled (mode='none')");let X=d(this.config.cookie);if(X)this.cookieManager=new M(X,()=>this.sessionId),this.log("Cookie manager enabled:",X.name);let Y=m(this.config.headers);if(Y)this.headerInjector=new E(Y,()=>this.sessionId),this.headerInjector.start(),this.log("Header injector enabled:",Y.name);let Z=p(this.config.formInject);if(Z)this.formInjector=new I(Z,()=>this.sessionId),this.formInjector.start(),this.log("Form injector enabled:",Z.inputName);if(this.config.autoStart)if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",()=>this.start());else this.start();K.markConstructorEnd(),this.log("Constructor completed in",(K.getTimings().constructorEnd??0)-(K.getTimings().constructorStart??0),"ms")}async initializeHashModule(){try{let{initHashModule:Q}=await import("./hash-q46pgar4.js");this.hashModule=await Q({preferWasm:this.config.hashVerification.preferWasm,onWasmLoaded:()=>{this.log("WASM hash module loaded"),this.config.hashVerification.onWasmLoaded?.()},onFallback:(X)=>{this.log("Using JS hash fallback:",X),this.config.hashVerification.onWasmFallback?.(X)}})}catch(Q){this.log("Failed to initialize hash module",Q)}}async initializeChallengeManager(){try{let{ChallengeManager:Q}=await import("./challenge-8yg1wp51.js");this.challengeManager=new Q(this.config.challenge,this.config.debug),this.log("Challenge manager loaded")}catch(Q){this.log("Failed to initialize challenge manager",Q)}}async start(){if(this.isRunning){this.log("Already running");return}K.markStartCalled(),this.log("Starting BotSigged SDK"),this.isRunning=!0,this.connectionState="connecting";try{this.browserSignal=this.browserCollector.collect(),K.markFormCollectorStart(),this.mouseCollector.start(),this.scrollCollector.start(),this.formCollector.start(),K.markFormCollectorReady(),this.log("Collectors started in",(K.getTimings().formCollectorReady??0)-(K.getTimings().formCollectorStart??0),"ms"),K.markFingerprintStart(),K.markWsConnectStart();let[Q]=await Promise.all([this.fingerprintGenerator.generate(),this.connectWithRetry()]);this.fingerprint=Q,K.markFingerprintEnd(),this.log("Fingerprint generated in",(K.getTimings().fingerprintEnd??0)-(K.getTimings().fingerprintStart??0),"ms"),await this.joinChannel(),this.connectionState="connected",this.readyResolver?.(),K.markSdkReady(),this.startSendInterval(),this.registerBeforeUnload();let X=K.getSummary();if(this.log("SDK started successfully"),this.log("Total startup time:",X.totalStartupMs,"ms"),this.log("Time to first score:",X.timeToFirstScoreMs,"ms"),this.log("Vulnerability window:",X.vulnerabilityWindowMs,"ms"),this.config.debug)K.logSummary()}catch(Q){let X=Q instanceof Error?Q:Error(String(Q));this.log("Failed to start",X),this.handleConnectionFailure(X)}}async stop(){if(!this.isRunning)return;if(this.log("Stopping BotSigged SDK"),this.formProtectionManager)this.formProtectionManager.destroy(),this.formProtectionManager=null;if(this.cookieManager)this.cookieManager.removeCookies(),this.cookieManager=null;if(this.headerInjector)this.headerInjector.stop(),this.headerInjector=null;if(this.formInjector)this.formInjector.stop(),this.formInjector=null;if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;this.unregisterBeforeUnload(),this.mouseCollector.stop(),this.scrollCollector.stop(),this.formCollector.stop(),this.stopSendInterval(),await this.sendSignal(),await this.disconnect(),this.isRunning=!1,this.log("SDK stopped")}async sendSignal(){if(!this.socket?.isReady()){this.log("Cannot send signal: not connected");return}let Q=this.buildPayload(),X=Q.seq;this.log("Sending signal seq:",X),K.markSignalSent(X);try{let Y=await this.socket.sendSignal(Q);K.markSignalResponseReceived(X);let Z=K.getTimings().signalRoundtrips||[],$=Z[Z.length-1];if($)this.log("Signal roundtrip:",$.roundtripMs,"ms");if(Y.bot_score!==void 0){let J={bot_score:Y.bot_score,classification:Y.classification||"unknown",triggered_rules:Y.triggered_rules||[]};this.lastScore=J,this.config.onScoreUpdate?.(J),this.handleScoreUpdate(J)}this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush(),this.hasSentInitial=!0}catch(Y){let Z=Y instanceof Error?Y:Error(String(Y));this.log("Failed to send signal",Z),this.config.onError?.(Z)}}async sendSignalAndGetScore(){if(!this.socket?.isReady())return this.log("Cannot send signal: not connected"),null;let Q=this.buildPayload(),X=Q.seq;this.log("Sending signal for form scoring, seq:",X);try{let Y=await this.socket.sendSignal(Q);if(Y.bot_score!==void 0){let Z={bot_score:Y.bot_score,classification:Y.classification||"unknown",triggered_rules:Y.triggered_rules||[]};return this.lastScore=Z,this.config.onScoreUpdate?.(Z),this.handleScoreUpdate(Z),this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush(),this.hasSentInitial=!0,Z.bot_score}return this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush(),this.hasSentInitial=!0,null}catch(Y){let Z=Y instanceof Error?Y:Error(String(Y));return this.log("Failed to send signal for form scoring",Z),this.config.onError?.(Z),null}}getSessionId(){return this.sessionId}getFingerprint(){return this.fingerprint}getFormSubmissionStatus(){return this.formSubmissionStatus}getLastScore(){return this.lastScore}isConnected(){return this.socket?.isReady()??!1}whenReady(){if(this.connectionState==="connected")return Promise.resolve();return this.readyPromise}getConnectionState(){return this.connectionState}getServerConfig(){return this.serverConfig}async identify(Q){let{accountId:X}=Q;if(!X||typeof X!=="string")throw Error("BotSigged: accountId is required and must be a string");if(X.length>255)throw Error("BotSigged: accountId must be 255 characters or less");this.log("Identifying account:",X),await this.whenReady();try{let Y=await this.socket.sendEvent("identify",{account_id:X,timestamp:Date.now()});if(Y.identified)this.log("Account identified successfully");else throw Error(Y.reason?.toString()||"Failed to identify account")}catch(Y){let Z=Y instanceof Error?Y:Error(String(Y));throw this.log("Failed to identify account:",Z),this.config.onError?.(Z),Z}}isDegraded(){return this.connectionState==="degraded"||this.connectionState==="failed"}getCurrentSignals(){return{mouse:this.mouseCollector.getSignal(),scroll:this.scrollCollector.getSignal(),form:this.formCollector.getSignal(),browser:this.browserSignal}}getBufferSizes(){return{mouse:this.mouseCollector.getBufferSize(),scroll:this.scrollCollector.getBufferSize(),form:this.formCollector.getBufferSize()}}resetSignals(){this.mouseCollector.reset(),this.scrollCollector.reset(),this.formCollector.reset(),this.browserCollector.reset(),this.sequenceNumber=0,this.hasSentInitial=!1}async connectSocket(){this.socket=new A({endpoint:this.config.endpoint,apiKey:this.config.apiKey,debug:this.config.debug,onConnectionChange:(Q)=>{this.config.onConnectionChange?.(Q==="connected")},onError:(Q)=>{this.config.onError?.(Q)}}),await this.socket.connect(),K.markWsConnectEnd(),this.log("WebSocket connected in",(K.getTimings().wsConnectEnd??0)-(K.getTimings().wsConnectStart??0),"ms")}async connectWithRetry(){let X=[1000,2000,4000];for(let Y=0;Y<3;Y++)try{await this.connectSocket();return}catch(Z){if(this.log(`Connection attempt ${Y+1} failed:`,Z),Y<2)await this.sleep(X[Y]);else throw Z}}sleep(Q){return new Promise((X)=>setTimeout(X,Q))}handleConnectionFailure(Q){this.connectionState="failed";let X=this.config.fallbackMode||"degraded";switch(this.log("Connection failed, applying fallback mode:",X),X){case"open":if(this.connectionState="degraded",this.formProtectionManager)this.formProtectionManager.setMode("none"),this.formProtectionManager.notifyReady(0);break;case"closed":this.blockFormsUntilConnected(),this.scheduleReconnect();break;case"cached":let Y=this.loadCachedConfig();if(Y)this.applyServerConfig(Y),this.connectionState="degraded";else this.applyFallbackConfig();this.scheduleReconnect();break;case"degraded":default:this.applyFallbackConfig(),this.connectionState="degraded",this.scheduleReconnect();break}this.config.onError?.(Q),this.config.onConnectionChange?.(!1)}applyFallbackConfig(){if(this.log("Applying fallback config"),this.serverConfig=F,this.formProtectionManager&&this.serverConfig.form_protection_mode)this.formProtectionManager.setMode(this.serverConfig.form_protection_mode);this.config.onServerConfig?.(this.serverConfig,"fallback")}blockFormsUntilConnected(){if(this.formProtectionManager)this.formProtectionManager.setMode("holdUntilReady"),this.formProtectionManager.setMaxHoldTime(30000)}scheduleReconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer);this.reconnectTimer=setTimeout(()=>{this.attemptReconnect()},5000)}async attemptReconnect(){this.log("Attempting reconnection..."),this.connectionState="connecting";try{if(await this.connectWithRetry(),!this.fingerprint)this.fingerprint=await this.fingerprintGenerator.generate();if(await this.joinChannel(),this.connectionState="connected",this.readyResolver?.(),this.log("Reconnection successful"),!this.sendTimer)this.startSendInterval()}catch(Q){this.log("Reconnection failed:",Q),this.connectionState="failed"}}cacheServerConfig(Q){try{localStorage.setItem(`botsigged_config_${this.config.apiKey}`,JSON.stringify({config:Q,timestamp:Date.now()}))}catch{}}loadCachedConfig(){try{let Q=localStorage.getItem(`botsigged_config_${this.config.apiKey}`);if(!Q)return null;let{config:X,timestamp:Y}=JSON.parse(Q);if(Date.now()-Y>86400000)return localStorage.removeItem(`botsigged_config_${this.config.apiKey}`),null;return X}catch{return null}}applyServerConfig(Q){if(this.log("Applying server config:",Q),this.serverConfig=Q,this.formProtectionManager&&Q.form_protection_mode)this.formProtectionManager.setMode(Q.form_protection_mode);if(Q.action&&Q.action!=="none")this.applyServerAction(Q.action,Q.challenge);this.cacheServerConfig(Q),this.config.onServerConfig?.(Q,"server")}async applyServerAction(Q,X){switch(this.log("Applying server action:",Q),Q){case"block":if(!this.formBlocked)this.blockForms();break;case"challenge":if(!this.challengeManager&&!this.challengeManagerPromise)this.log("Lazily loading challenge manager for server-requested challenge"),this.challengeManagerPromise=this.initializeChallengeManager();if(this.challengeManagerPromise)await this.challengeManagerPromise;if(this.challengeManager){let Y=X?.difficulty?.bot??16,Z=Y>=18?"critical":Y>=16?"high":"medium";this.challengeManager.blockFormsUntilSolved(Z)}else this.log("Challenge requested but challenge manager failed to load");break;case"flag":this.log("Session flagged by server");break;case"none":default:break}}handleServerAction(Q){this.log("Received server action:",Q),this.config.onServerAction?.(Q);let X=Q.challenge?{difficulty:{suspicious:Q.challenge.difficulty,bot:Q.challenge.difficulty},timeout_ms:Q.challenge.timeout_ms}:void 0;this.applyServerAction(Q.type,X)}async joinChannel(){if(!this.socket)throw Error("WebSocket not initialized");K.markChannelJoinStart();let Q;try{Q=await this.socket.joinChannel(this.sessionId,this.fingerprint,this.getSessionData(),this.browserSignal,{onScoreUpdate:(X)=>{this.lastScore=X,this.config.onScoreUpdate?.(X),this.handleScoreUpdate(X)},onError:(X)=>{this.config.onError?.(X)},onAction:(X)=>{this.handleServerAction(X)}},this.config.accountId)}catch(X){if(T(X)){if(this.log("Usage limit exceeded:",X),this.config.onUsageLimitExceeded)this.config.onUsageLimitExceeded(X);else this.config.onError?.(Error(`Usage limit exceeded: ${X.current_usage}/${X.limit} verifications (${X.plan_name} plan). Please upgrade your plan.`));return}throw X}if(K.markChannelJoinEnd(),this.log("Channel joined in",(K.getTimings().channelJoinEnd??0)-(K.getTimings().channelJoinStart??0),"ms"),Q.config){let X=Q.config;this.applyServerConfig(X)}if(Q.initial_score!==void 0){K.markInitialScoreReceived();let X={bot_score:Q.initial_score,classification:Q.classification||"unknown",triggered_rules:Q.triggered_rules||[]};if(this.lastScore=X,this.config.onScoreUpdate?.(X),this.handleScoreUpdate(X),this.formProtectionManager)this.formProtectionManager.notifyReady(X.bot_score);if(this.cookieManager)this.cookieManager.setCookie();this.log("Initial score received:",X.bot_score,"in",(K.getTimings().initialScoreReceived??0)-(K.getTimings().startCalled??0),"ms from start")}}handleScoreUpdate(Q){if(this.cookieManager)this.cookieManager.updateRiskTier(Q.bot_score);let X=this.getBotScoreLevel(Q.bot_score),Y=Q.bot_score>=this.config.actionThreshold;if(this.shouldTriggerAlert(X)){let Z={score:Q.bot_score,level:X,scoreUpdate:Q,sessionId:this.sessionId,fingerprintHash:this.fingerprint?.hash};if(Y&&!this.highScoreTriggeredLevels.has(X))this.executeAction(Z);this.config.onHighBotScore?.(Z),this.highScoreTriggeredLevels.add(X)}}getBotScoreLevel(Q){let X=this.config.botScoreThresholds;if(Q>=X.critical)return"critical";if(Q>=X.high)return"high";if(Q>=X.medium)return"medium";return"low"}shouldTriggerAlert(Q){if(this.highScoreTriggeredLevels.has(Q))return!1;let X=["low","medium","high","critical"],Y=this.config.minAlertLevel,Z=X.indexOf(Q),$=X.indexOf(Y);return Z>=$}async executeAction(Q){let X=this.config.action;switch(this.log(`Executing action '${X}' for score ${Q.score}`),X){case"challenge":if(this.challengeManagerPromise)await this.challengeManagerPromise;if(this.challengeManager)this.challengeManager.blockFormsUntilSolved(Q.level);break;case"block":if(!this.formBlocked)this.blockForms();break;case"none":default:break}}blockForms(){if(this.formBlocked)return;this.formBlocked=!0,document.querySelectorAll("form").forEach((Q)=>{Q.addEventListener("submit",this.blockFormSubmit,!0)}),this.formObserver=new MutationObserver((Q)=>{Q.forEach((X)=>{X.addedNodes.forEach((Y)=>{if(Y instanceof HTMLFormElement)Y.addEventListener("submit",this.blockFormSubmit,!0);if(Y instanceof HTMLElement)Y.querySelectorAll("form").forEach((Z)=>{Z.addEventListener("submit",this.blockFormSubmit,!0)})})})}),this.formObserver.observe(document.body,{childList:!0,subtree:!0}),this.log("Forms blocked due to high bot score")}blockFormSubmit=(Q)=>{Q.preventDefault(),Q.stopPropagation(),this.log("Form submission blocked due to high bot score");return};isFormsBlocked(){return this.formBlocked}unblockForms(){if(!this.formBlocked)return;if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;document.querySelectorAll("form").forEach((Q)=>{Q.removeEventListener("submit",this.blockFormSubmit,!0)}),this.formBlocked=!1,this.log("Forms unblocked")}getHashModule(){return this.hashModule}createSignature(Q){let X=this.config.hashVerification.secret;if(!X)return this.log("Cannot create signature: no secret configured"),null;return createSignature(Q,X)}verifySignature(Q,X){let Y=this.config.hashVerification.secret;if(!Y)return this.log("Cannot verify signature: no secret configured"),!1;return verifySignature(Q,X,Y)}isChallengeSolving(){return this.challengeManager?.isSolving()??!1}isChallengeSolved(){return this.challengeManager?.isSolved()??!1}getPerformanceSummary(){return K.getSummary()}logPerformance(){K.logSummary()}getPerformanceReport(){return K.getReport()}async waitUntilReady(){if(this.lastScore)return{score:this.lastScore.bot_score,timedOut:!1};if(this.formProtectionManager)return this.formProtectionManager.waitUntilReady();return new Promise((Q)=>{let X=performance.now(),Y=5000,Z=()=>{if(this.lastScore){Q({score:this.lastScore.bot_score,timedOut:!1});return}if(performance.now()-X>=5000){Q({score:null,timedOut:!0});return}setTimeout(Z,50)};Z()})}withProtection(Q,X={}){let Y=X.blockThreshold??this.config.actionThreshold;return async(...Z)=>{let{score:$,timedOut:J}=await this.waitUntilReady();if(K.markFirstSubmitAttempt($!==null),$!==null&&$>=Y)throw this.log(`Blocking submission: score ${$} >= threshold ${Y}`),Error(`Submission blocked: bot score ${$} exceeds threshold`);if(J)this.log("Warning: submitting without detection score (timed out)");return Q(...Z)}}protectedFetch(Q={}){return this.withProtection(async(X,Y)=>{return fetch(X,Y)},Q)}canSubmit(){if(!this.lastScore)return{allowed:!1,reason:"waiting_for_score",score:null};if(this.lastScore.bot_score>=this.config.actionThreshold)return{allowed:!1,reason:"high_bot_score",score:this.lastScore.bot_score};return{allowed:!0,score:this.lastScore.bot_score}}async triggerChallenge(Q="high"){if(this.challengeManagerPromise)await this.challengeManagerPromise;if(!this.challengeManager){this.log("Challenge not enabled");return}this.challengeManager.blockFormsUntilSolved(Q)}async disconnect(){if(this.socket)await this.socket.leaveChannel(),this.socket.disconnect(),this.socket=null}startSendInterval(){this.stopSendInterval(),this.sendTimer=setInterval(()=>{this.sendSignal()},this.config.sendInterval)}stopSendInterval(){if(this.sendTimer)clearInterval(this.sendTimer),this.sendTimer=null}registerBeforeUnload(){this.boundBeforeUnload=()=>{this.handleBeforeUnload()},this.boundVisibilityChange=()=>{if(document.visibilityState==="hidden")this.handleBeforeUnload()},window.addEventListener("beforeunload",this.boundBeforeUnload),document.addEventListener("visibilitychange",this.boundVisibilityChange)}unregisterBeforeUnload(){if(this.boundBeforeUnload)window.removeEventListener("beforeunload",this.boundBeforeUnload),this.boundBeforeUnload=null;if(this.boundVisibilityChange)document.removeEventListener("visibilitychange",this.boundVisibilityChange),this.boundVisibilityChange=null}handleBeforeUnload(){if(!this.isRunning||!this.socket)return;try{let Q=this.buildPayload();if(this.socket.isReady())this.socket.sendSignal(Q).catch(()=>{})}catch{}}handleFormSubmit(){if(!this.isRunning)return;if(K.markFirstSubmitAttempt(this.lastScore!==null),this.log("Form submitted, flushing signals via beacon"),this.log("Had score before submit:",this.lastScore!==null),this.updateFormStatus("completed"),!this.sessionId){this.log("No session ID yet, cannot send beacon");return}let Q=this.buildPayload();if(!this.sendViaBeacon(Q))this.sendSignal().catch((Y)=>{this.log("Failed to flush signals on form submit",Y)});else this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush()}sendViaBeacon(Q){if(!navigator.sendBeacon)return this.log("sendBeacon not available"),!1;try{let X=new URL(this.config.endpoint),Y=`${X.protocol==="wss:"?"https:":"http:"}//${X.host}/api/signal`,Z=JSON.stringify({session_id:this.sessionId,api_key:this.config.apiKey,payload:Q,form_status:this.formSubmissionStatus}),$=new Blob([Z],{type:"application/json"}),J=navigator.sendBeacon(Y,$);return this.log("Beacon sent:",J),J}catch(X){return this.log("Beacon send failed:",X),!1}}buildPayload(){this.sequenceNumber++;let Q={session_id:this.sessionId,seq:this.sequenceNumber,mouse:this.mouseCollector.getSignal(),scroll:this.scrollCollector.getSignal(),form:this.formCollector.getSignal(),timestamp:Date.now()};if(!this.hasSentInitial)Q.session=this.getSessionData(),Q.fingerprint=this.fingerprint,Q.browser=this.browserSignal;return Q}getSessionData(){let Q=new URL(window.location.href),X={};Q.searchParams.forEach((Z,$)=>{X[$]=Z});let Y=null;if(document.referrer)try{Y=new URL(document.referrer).hostname}catch{}return{url_path:Q.pathname,url_params:X,referrer_url:document.referrer||null,referrer_domain:Y,user_agent:navigator.userAgent}}generateSessionId(){if(crypto.randomUUID)return crypto.randomUUID();return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(Q)=>{let X=Math.random()*16|0;return(Q==="x"?X:X&3|8).toString(16)})}updateFormStatus(Q){if(this.formSubmissionStatus==="blocked"||this.formSubmissionStatus==="completed"){this.log(`Form status already terminal (${this.formSubmissionStatus}), ignoring ${Q}`);return}if(this.formSubmissionStatus==="challenged"&&Q!=="completed"){this.log(`Form status is challenged, can only become completed, ignoring ${Q}`);return}if(this.formSubmissionStatus=Q,this.log(`Form status updated to: ${Q}`),this.socket?.isReady())this.socket.sendFormStatus(Q).catch((X)=>{this.log("Failed to send form status:",X)})}log(...Q){if(this.config.debug);}}var O=null;function xQ(Q){if(O)return O;return O=new S(Q),O}function CQ(){return O}async function LQ(){if(O)await O.stop(),O=null}var AQ=S;export{f as logPerformanceSummary,kQ as loadHashModule,T as isUsageLimitError,xQ as init,l as getPerformanceSummary,N as getPerformanceMetrics,CQ as getInstance,LQ as destroy,AQ as default,q as DEFAULT_CONFIG,S as BotSigged};
|
|
40
|
+
`,document.body.appendChild(this.loadingOverlay)}hideLoading(){if(this.loadingOverlay)this.loadingOverlay.remove(),this.loadingOverlay=null}notifyReady(Q){this.isReady=!0,this.hasScore=!0,this.currentScore=Q,[...this.pendingSubmissions].forEach((Z)=>{this.releaseSubmission(Z,!1)}),[...this.pendingRequests].forEach((Z)=>{this.releaseRequest(Z)}),this.hideLoading()}blockAllPending(Q){[...this.pendingSubmissions].forEach((Y)=>{this.config.onBlock?.(Y.form,Q),this.releaseSubmission(Y,!0)})}getStatus(){return{mode:this.config.mode,isReady:this.isReady,hasScore:this.hasScore,pendingCount:this.pendingSubmissions.length,protectedFormCount:this.protectedForms.size}}waitUntilReady(){if(this.hasScore)return Promise.resolve({score:this.currentScore,timedOut:!1});return new Promise((Q)=>{let X=performance.now(),Y=()=>{if(this.hasScore){Q({score:this.currentScore,timedOut:!1});return}if(performance.now()-X>=this.config.maxHoldTime){Q({score:null,timedOut:!0});return}setTimeout(Y,50)};Y()})}withProtection(Q){return async(...X)=>{let Y=performance.now()-this.startTime;if(N().markFirstSubmitAttempt(this.hasScore),this.config.mode==="blockInstant"&&Y<this.config.minTimeBeforeSubmit)throw this.config.onBlock?.(document.createElement("form"),"instant_submission"),Error("Submission blocked: too fast");if(this.config.mode==="holdUntilReady"&&!this.hasScore){if(this.config.showLoadingUI)this.showLoading(document.createElement("form"));let{timedOut:Z}=await this.waitUntilReady();if(this.config.showLoadingUI)this.hideLoading()}return Q(...X)}}protectedFetch(){return this.withProtection(async(Q,X)=>{return fetch(Q,X)})}setMode(Q){if(this.config.mode=Q,Q==="none")[...this.pendingSubmissions].forEach((Y)=>this.releaseSubmission(Y,!1))}setMaxHoldTime(Q){this.config.maxHoldTime=Q}canSubmit(){let Q=performance.now()-this.startTime;if(this.config.mode==="blockInstant"&&Q<this.config.minTimeBeforeSubmit)return{allowed:!1,reason:"too_fast",score:this.currentScore};if(this.config.mode==="holdUntilReady"&&!this.hasScore)return{allowed:!1,reason:"waiting_for_score",score:null};return{allowed:!0,score:this.currentScore}}destroy(){if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;if(this.originalFetch)window.fetch=this.originalFetch,this.originalFetch=null;if(this.originalXHROpen)XMLHttpRequest.prototype.open=this.originalXHROpen,this.originalXHROpen=null;if(this.originalXHRSend)XMLHttpRequest.prototype.send=this.originalXHRSend,this.originalXHRSend=null;this.hideLoading(),this.pendingSubmissions=[],this.pendingRequests=[],this.protectedForms.clear()}}var u={suspicious:40,bot:70},H={name:"_bsid",riskName:"_bsrisk",path:"/",sameSite:"Strict"};function d(Q){if(!Q)return null;if(Q===!0)return{...H};return{...H,...Q}}function a(Q){if(Q>=u.bot)return"bot";if(Q>=u.suspicious)return"suspicious";return"human"}class M{config;sessionIdGetter;sessionCookieSet=!1;currentRiskTier=null;constructor(Q,X){this.config={...H,...Q},this.sessionIdGetter=X}buildCookieString(Q,X){let Y=this.config.path||H.path,Z=this.config.sameSite||H.sameSite,$=this.config.secure??location.protocol==="https:",J=[`${encodeURIComponent(Q)}=${encodeURIComponent(X)}`,`Path=${Y}`,`SameSite=${Z}`];if($||Z==="None")J.push("Secure");return J.join("; ")}deleteCookie(Q){let X=this.config.path||H.path;document.cookie=`${encodeURIComponent(Q)}=; Path=${X}; Max-Age=0`}setSessionCookie(){if(this.sessionCookieSet)return;let Q=this.sessionIdGetter();if(!Q)return;let X=this.config.name||H.name;document.cookie=this.buildCookieString(X,Q),this.sessionCookieSet=!0}updateRiskTier(Q){let X=a(Q);if(X===this.currentRiskTier)return!1;let Y=this.config.riskName||H.riskName;document.cookie=this.buildCookieString(Y,X);let Z=this.currentRiskTier;return this.currentRiskTier=X,!0}removeCookies(){let Q=this.config.name||H.name,X=this.config.riskName||H.riskName;if(this.sessionCookieSet)this.deleteCookie(Q),this.sessionCookieSet=!1;if(this.currentRiskTier!==null)this.deleteCookie(X),this.currentRiskTier=null}setCookie(){this.setSessionCookie()}removeCookie(){this.removeCookies()}isSessionCookieSet(){return this.sessionCookieSet}getCurrentRiskTier(){return this.currentRiskTier}getSessionCookieName(){return this.config.name||H.name}getRiskCookieName(){return this.config.riskName||H.riskName}}var P={name:"X-BotSigged-ID"};function m(Q){if(!Q)return null;if(Q===!0)return{...P};return{...P,...Q}}class E{config;sessionIdGetter;started=!1;originalFetch=null;originalXHROpen=null;originalXHRSend=null;originalXHRSetRequestHeader=null;xhrInjectionMap=new WeakMap;constructor(Q,X){this.config={...P,...Q},this.sessionIdGetter=X}start(){if(this.started)return;this.started=!0,this.patchFetch(),this.patchXHR()}stop(){if(!this.started)return;if(this.originalFetch)window.fetch=this.originalFetch,this.originalFetch=null;if(this.originalXHROpen)XMLHttpRequest.prototype.open=this.originalXHROpen,this.originalXHROpen=null;if(this.originalXHRSend)XMLHttpRequest.prototype.send=this.originalXHRSend,this.originalXHRSend=null;if(this.originalXHRSetRequestHeader)XMLHttpRequest.prototype.setRequestHeader=this.originalXHRSetRequestHeader,this.originalXHRSetRequestHeader=null;this.started=!1}isSameOrigin(Q){try{let X;if(Q instanceof Request)X=new URL(Q.url,window.location.origin);else if(Q instanceof URL)X=Q;else X=new URL(Q,window.location.origin);return X.origin===window.location.origin}catch{return!0}}patchFetch(){this.originalFetch=window.fetch.bind(window);let Q=this,X=this.config.name||P.name;window.fetch=function(Y,Z){if(!Q.isSameOrigin(Y))return Q.originalFetch(Y,Z);let $=Q.sessionIdGetter();if(!$)return Q.originalFetch(Y,Z);let J=new Headers(Z?.headers);if(!J.has(X))J.set(X,$);return Q.originalFetch(Y,{...Z,headers:J})}}patchXHR(){this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send,this.originalXHRSetRequestHeader=XMLHttpRequest.prototype.setRequestHeader;let Q=this,X=this.config.name||P.name;XMLHttpRequest.prototype.open=function(Y,Z,$=!0,J,z){let W=Q.isSameOrigin(Z);return Q.xhrInjectionMap.set(this,W),Q.originalXHROpen.call(this,Y,Z,$,J,z)},XMLHttpRequest.prototype.send=function(Y){if(Q.xhrInjectionMap.get(this)){let Z=Q.sessionIdGetter();if(Z)try{Q.originalXHRSetRequestHeader.call(this,X,Z)}catch{}}return Q.originalXHRSend.call(this,Y)}}getHeaderName(){return this.config.name||P.name}isStarted(){return this.started}}var _={selector:"form",inputName:"_bsid"};function p(Q){if(!Q)return null;if(Q===!0)return{..._};return{..._,...Q}}class I{config;sessionIdGetter;observer=null;started=!1;constructor(Q,X){this.config={..._,...Q},this.sessionIdGetter=X}start(){if(this.started)return;this.started=!0;let Q=()=>{this.setupExistingForms(),this.setupObserver()};if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",Q,{once:!0});else Q()}stop(){if(!this.started)return;if(this.observer)this.observer.disconnect(),this.observer=null;let Q=this.config.selector||_.selector,X=this.config.inputName||_.inputName;document.querySelectorAll(`${Q}[data-bs-inject-setup]`).forEach((Y)=>{if(Y instanceof HTMLFormElement)Y.removeEventListener("submit",this.handleSubmit,{capture:!0});Y.removeAttribute("data-bs-inject-setup");let Z=Y.querySelector(`input[name="${X}"][data-bs-injected]`);if(Z)Z.remove()}),this.started=!1}setupExistingForms(){let Q=this.config.selector||_.selector;document.querySelectorAll(Q).forEach((X)=>{if(X instanceof HTMLFormElement)this.setupForm(X)})}setupObserver(){if(!document.body)return;let Q=this.config.selector||_.selector;this.observer=new MutationObserver((X)=>{X.forEach((Y)=>{Y.addedNodes.forEach((Z)=>{if(Z instanceof HTMLFormElement&&Z.matches(Q))this.setupForm(Z);if(Z instanceof HTMLElement)Z.querySelectorAll(Q).forEach(($)=>{if($ instanceof HTMLFormElement)this.setupForm($)})})})}),this.observer.observe(document.body,{childList:!0,subtree:!0})}setupForm(Q){if(Q.hasAttribute("data-bs-inject-setup"))return;Q.setAttribute("data-bs-inject-setup","true"),Q.addEventListener("submit",this.handleSubmit,{capture:!0})}handleSubmit=(Q)=>{let X=Q.currentTarget;this.injectInput(X)};injectInput(Q){let X=this.config.inputName||_.inputName,Y=Q.querySelector(`input[name="${X}"]`);if(Y){if(Y.hasAttribute("data-bs-injected"))Y.value=this.sessionIdGetter();return}let Z=document.createElement("input");Z.type="hidden",Z.name=X,Z.value=this.sessionIdGetter(),Z.setAttribute("data-bs-injected","true"),Q.appendChild(Z)}getConfig(){return{...this.config}}isStarted(){return this.started}}async function kQ(){return await import("./hash-q46pgar4.js")}class S{config;mouseCollector;scrollCollector;formCollector;browserCollector;fingerprintGenerator;socket=null;sessionId;sequenceNumber=0;isRunning=!1;sendTimer=null;fingerprint=null;browserSignal=null;lastScore=null;hasSentInitial=!1;boundBeforeUnload=null;boundVisibilityChange=null;hashModule=null;formBlocked=!1;formObserver=null;highScoreTriggeredLevels=new Set;challengeManager=null;challengeManagerPromise=null;formProtectionManager=null;formSubmissionStatus="no_submission";cookieManager=null;headerInjector=null;formInjector=null;serverConfig=null;connectionState="disconnected";reconnectTimer=null;readyPromise;readyResolver=null;constructor(Q){if(K.markConstructorStart(),!Q.apiKey)throw Error("BotSigged: apiKey is required");if(this.config=h(Q),this.sessionId=this.generateSessionId(),this.readyPromise=new Promise(($)=>{this.readyResolver=$}),this.mouseCollector=new k({sampleRate:this.config.mouseSampleRate,maxBufferSize:this.config.maxBufferSize}),this.scrollCollector=new x({maxBufferSize:Math.floor(this.config.maxBufferSize/3)}),this.formCollector=new C({maxKeyEvents:this.config.maxBufferSize,onSubmit:()=>this.handleFormSubmit()}),this.browserCollector=new L,this.fingerprintGenerator=new b,this.config.hashVerification.enabled)this.initializeHashModule();if(this.config.action==="challenge"||this.config.challenge.enabled)this.challengeManagerPromise=this.initializeChallengeManager();if(this.config.formProtection.mode!=="none")this.formProtectionManager=new D({mode:this.config.formProtection.mode,minTimeBeforeSubmit:this.config.formProtection.minTimeBeforeSubmit,maxHoldTime:this.config.formProtection.maxHoldTime,showLoadingUI:this.config.formProtection.showLoadingUI,loadingMessage:this.config.formProtection.loadingMessage,onHold:($)=>{this.updateFormStatus("challenged"),this.config.formProtection.onHold?.($)},onRelease:($,J)=>{if(!J)this.updateFormStatus("completed");this.config.formProtection.onRelease?.($,J)},onBlock:($,J)=>{this.updateFormStatus("blocked"),this.config.formProtection.onBlock?.($,J)},flushAndWaitForScore:()=>this.sendSignalAndGetScore()}),this.log("Form protection enabled:",this.config.formProtection.mode);else this.log("Form protection disabled (mode='none')");let X=d(this.config.cookie);if(X)this.cookieManager=new M(X,()=>this.sessionId),this.log("Cookie manager enabled:",X.name);let Y=m(this.config.headers);if(Y)this.headerInjector=new E(Y,()=>this.sessionId),this.headerInjector.start(),this.log("Header injector enabled:",Y.name);let Z=p(this.config.formInject);if(Z)this.formInjector=new I(Z,()=>this.sessionId),this.formInjector.start(),this.log("Form injector enabled:",Z.inputName);if(this.config.autoStart)if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",()=>this.start());else this.start();K.markConstructorEnd(),this.log("Constructor completed in",(K.getTimings().constructorEnd??0)-(K.getTimings().constructorStart??0),"ms")}async initializeHashModule(){try{let{initHashModule:Q}=await import("./hash-q46pgar4.js");this.hashModule=await Q({preferWasm:this.config.hashVerification.preferWasm,onWasmLoaded:()=>{this.log("WASM hash module loaded"),this.config.hashVerification.onWasmLoaded?.()},onFallback:(X)=>{this.log("Using JS hash fallback:",X),this.config.hashVerification.onWasmFallback?.(X)}})}catch(Q){this.log("Failed to initialize hash module",Q)}}async initializeChallengeManager(){try{let{ChallengeManager:Q}=await import("./challenge-8yg1wp51.js");this.challengeManager=new Q(this.config.challenge,this.config.debug),this.log("Challenge manager loaded")}catch(Q){this.log("Failed to initialize challenge manager",Q)}}async start(){if(this.isRunning){this.log("Already running");return}K.markStartCalled(),this.log("Starting BotSigged SDK"),this.isRunning=!0,this.connectionState="connecting";try{this.browserSignal=this.browserCollector.collect(),K.markFormCollectorStart(),this.mouseCollector.start(),this.scrollCollector.start(),this.formCollector.start(),K.markFormCollectorReady(),this.log("Collectors started in",(K.getTimings().formCollectorReady??0)-(K.getTimings().formCollectorStart??0),"ms"),K.markFingerprintStart(),K.markWsConnectStart();let[Q]=await Promise.all([this.fingerprintGenerator.generate(),this.connectWithRetry()]);this.fingerprint=Q,K.markFingerprintEnd(),this.log("Fingerprint generated in",(K.getTimings().fingerprintEnd??0)-(K.getTimings().fingerprintStart??0),"ms"),await this.joinChannel(),this.connectionState="connected",this.readyResolver?.(),K.markSdkReady(),this.startSendInterval(),this.registerBeforeUnload();let X=K.getSummary();if(this.log("SDK started successfully"),this.log("Total startup time:",X.totalStartupMs,"ms"),this.log("Time to first score:",X.timeToFirstScoreMs,"ms"),this.log("Vulnerability window:",X.vulnerabilityWindowMs,"ms"),this.config.debug)K.logSummary()}catch(Q){let X=Q instanceof Error?Q:Error(String(Q));this.log("Failed to start",X),this.handleConnectionFailure(X)}}async stop(){if(!this.isRunning)return;if(this.log("Stopping BotSigged SDK"),this.formProtectionManager)this.formProtectionManager.destroy(),this.formProtectionManager=null;if(this.cookieManager)this.cookieManager.removeCookies(),this.cookieManager=null;if(this.headerInjector)this.headerInjector.stop(),this.headerInjector=null;if(this.formInjector)this.formInjector.stop(),this.formInjector=null;if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;this.unregisterBeforeUnload(),this.mouseCollector.stop(),this.scrollCollector.stop(),this.formCollector.stop(),this.stopSendInterval(),await this.sendSignal(),await this.disconnect(),this.isRunning=!1,this.log("SDK stopped")}async sendSignal(){if(!this.socket?.isReady()){this.log("Cannot send signal: not connected");return}let Q=this.buildPayload(),X=Q.seq;this.log("Sending signal seq:",X),K.markSignalSent(X);try{let Y=await this.socket.sendSignal(Q);K.markSignalResponseReceived(X);let Z=K.getTimings().signalRoundtrips||[],$=Z[Z.length-1];if($)this.log("Signal roundtrip:",$.roundtripMs,"ms");if(Y.bot_score!==void 0){let J={bot_score:Y.bot_score,classification:Y.classification||"unknown",triggered_rules:Y.triggered_rules||[]};this.lastScore=J,this.config.onScoreUpdate?.(J),this.handleScoreUpdate(J)}this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush(),this.hasSentInitial=!0}catch(Y){let Z=Y instanceof Error?Y:Error(String(Y));this.log("Failed to send signal",Z),this.config.onError?.(Z)}}async sendSignalAndGetScore(){if(!this.socket?.isReady())return this.log("Cannot send signal: not connected"),null;let Q=this.buildPayload(),X=Q.seq;this.log("Sending signal for form scoring, seq:",X);try{let Y=await this.socket.sendSignal(Q);if(Y.bot_score!==void 0){let Z={bot_score:Y.bot_score,classification:Y.classification||"unknown",triggered_rules:Y.triggered_rules||[]};return this.lastScore=Z,this.config.onScoreUpdate?.(Z),this.handleScoreUpdate(Z),this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush(),this.hasSentInitial=!0,Z.bot_score}return this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush(),this.hasSentInitial=!0,null}catch(Y){let Z=Y instanceof Error?Y:Error(String(Y));return this.log("Failed to send signal for form scoring",Z),this.config.onError?.(Z),null}}getSessionId(){return this.sessionId}getFingerprint(){return this.fingerprint}getFormSubmissionStatus(){return this.formSubmissionStatus}getLastScore(){return this.lastScore}isConnected(){return this.socket?.isReady()??!1}whenReady(){if(this.connectionState==="connected")return Promise.resolve();return this.readyPromise}getConnectionState(){return this.connectionState}getServerConfig(){return this.serverConfig}async identify(Q){let{accountId:X}=Q;if(!X||typeof X!=="string")throw Error("BotSigged: accountId is required and must be a string");if(X.length>255)throw Error("BotSigged: accountId must be 255 characters or less");this.log("Identifying account:",X),await this.whenReady();try{let Y=await this.socket.sendEvent("identify",{account_id:X,timestamp:Date.now()});if(Y.identified)this.log("Account identified successfully");else throw Error(Y.reason?.toString()||"Failed to identify account")}catch(Y){let Z=Y instanceof Error?Y:Error(String(Y));throw this.log("Failed to identify account:",Z),this.config.onError?.(Z),Z}}isDegraded(){return this.connectionState==="degraded"||this.connectionState==="failed"}getCurrentSignals(){return{mouse:this.mouseCollector.getSignal(),scroll:this.scrollCollector.getSignal(),form:this.formCollector.getSignal(),browser:this.browserSignal}}getBufferSizes(){return{mouse:this.mouseCollector.getBufferSize(),scroll:this.scrollCollector.getBufferSize(),form:this.formCollector.getBufferSize()}}resetSignals(){this.mouseCollector.reset(),this.scrollCollector.reset(),this.formCollector.reset(),this.browserCollector.reset(),this.sequenceNumber=0,this.hasSentInitial=!1}async connectSocket(){this.socket=new A({endpoint:this.config.endpoint,apiKey:this.config.apiKey,debug:this.config.debug,onConnectionChange:(Q)=>{this.config.onConnectionChange?.(Q==="connected")},onError:(Q)=>{this.config.onError?.(Q)}}),await this.socket.connect(),K.markWsConnectEnd(),this.log("WebSocket connected in",(K.getTimings().wsConnectEnd??0)-(K.getTimings().wsConnectStart??0),"ms")}async connectWithRetry(){let X=[1000,2000,4000];for(let Y=0;Y<3;Y++)try{await this.connectSocket();return}catch(Z){if(this.log(`Connection attempt ${Y+1} failed:`,Z),Y<2)await this.sleep(X[Y]);else throw Z}}sleep(Q){return new Promise((X)=>setTimeout(X,Q))}handleConnectionFailure(Q){this.connectionState="failed";let X=this.config.fallbackMode||"degraded";switch(this.log("Connection failed, applying fallback mode:",X),X){case"open":if(this.connectionState="degraded",this.formProtectionManager)this.formProtectionManager.setMode("none"),this.formProtectionManager.notifyReady(0);break;case"closed":this.blockFormsUntilConnected(),this.scheduleReconnect();break;case"cached":let Y=this.loadCachedConfig();if(Y)this.applyServerConfig(Y),this.connectionState="degraded";else this.applyFallbackConfig();this.scheduleReconnect();break;case"degraded":default:this.applyFallbackConfig(),this.connectionState="degraded",this.scheduleReconnect();break}this.config.onError?.(Q),this.config.onConnectionChange?.(!1)}applyFallbackConfig(){if(this.log("Applying fallback config"),this.serverConfig=F,this.formProtectionManager&&this.serverConfig.form_protection_mode)this.formProtectionManager.setMode(this.serverConfig.form_protection_mode);this.config.onServerConfig?.(this.serverConfig,"fallback")}blockFormsUntilConnected(){if(this.formProtectionManager)this.formProtectionManager.setMode("holdUntilReady"),this.formProtectionManager.setMaxHoldTime(30000)}scheduleReconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer);this.reconnectTimer=setTimeout(()=>{this.attemptReconnect()},5000)}async attemptReconnect(){this.log("Attempting reconnection..."),this.connectionState="connecting";try{if(await this.connectWithRetry(),!this.fingerprint)this.fingerprint=await this.fingerprintGenerator.generate();if(await this.joinChannel(),this.connectionState="connected",this.readyResolver?.(),this.log("Reconnection successful"),!this.sendTimer)this.startSendInterval()}catch(Q){this.log("Reconnection failed:",Q),this.connectionState="failed"}}cacheServerConfig(Q){try{localStorage.setItem(`botsigged_config_${this.config.apiKey}`,JSON.stringify({config:Q,timestamp:Date.now()}))}catch{}}loadCachedConfig(){try{let Q=localStorage.getItem(`botsigged_config_${this.config.apiKey}`);if(!Q)return null;let{config:X,timestamp:Y}=JSON.parse(Q);if(Date.now()-Y>86400000)return localStorage.removeItem(`botsigged_config_${this.config.apiKey}`),null;return X}catch{return null}}applyServerConfig(Q){if(this.log("Applying server config:",Q),this.serverConfig=Q,this.formProtectionManager&&Q.form_protection_mode)this.formProtectionManager.setMode(Q.form_protection_mode);if(Q.action&&Q.action!=="none")this.applyServerAction(Q.action,Q.challenge);this.cacheServerConfig(Q),this.config.onServerConfig?.(Q,"server")}async applyServerAction(Q,X){switch(this.log("Applying server action:",Q),Q){case"block":if(this.updateFormStatus("blocked"),!this.formBlocked)this.blockForms();break;case"challenge":if(this.updateFormStatus("challenged"),!this.challengeManager&&!this.challengeManagerPromise)this.log("Lazily loading challenge manager for server-requested challenge"),this.challengeManagerPromise=this.initializeChallengeManager();if(this.challengeManagerPromise)await this.challengeManagerPromise;if(this.challengeManager){let Y=X?.difficulty?.bot??16,Z=Y>=18?"critical":Y>=16?"high":"medium";this.challengeManager.blockFormsUntilSolved(Z)}else this.log("Challenge requested but challenge manager failed to load");break;case"flag":this.updateFormStatus("flagged"),this.log("Session flagged by server");break;case"none":default:break}}handleServerAction(Q){this.log("Received server action:",Q),this.config.onServerAction?.(Q);let X=Q.challenge?{difficulty:{suspicious:Q.challenge.difficulty,bot:Q.challenge.difficulty},timeout_ms:Q.challenge.timeout_ms}:void 0;this.applyServerAction(Q.type,X)}async joinChannel(){if(!this.socket)throw Error("WebSocket not initialized");K.markChannelJoinStart();let Q;try{Q=await this.socket.joinChannel(this.sessionId,this.fingerprint,this.getSessionData(),this.browserSignal,{onScoreUpdate:(X)=>{this.lastScore=X,this.config.onScoreUpdate?.(X),this.handleScoreUpdate(X)},onError:(X)=>{this.config.onError?.(X)},onAction:(X)=>{this.handleServerAction(X)}},this.config.accountId)}catch(X){if(T(X)){if(this.log("Usage limit exceeded:",X),this.config.onUsageLimitExceeded)this.config.onUsageLimitExceeded(X);else this.config.onError?.(Error(`Usage limit exceeded: ${X.current_usage}/${X.limit} verifications (${X.plan_name} plan). Please upgrade your plan.`));return}throw X}if(K.markChannelJoinEnd(),this.log("Channel joined in",(K.getTimings().channelJoinEnd??0)-(K.getTimings().channelJoinStart??0),"ms"),Q.config){let X=Q.config;this.applyServerConfig(X)}if(Q.initial_score!==void 0){K.markInitialScoreReceived();let X={bot_score:Q.initial_score,classification:Q.classification||"unknown",triggered_rules:Q.triggered_rules||[]};if(this.lastScore=X,this.config.onScoreUpdate?.(X),this.handleScoreUpdate(X),this.formProtectionManager)this.formProtectionManager.notifyReady(X.bot_score);if(this.cookieManager)this.cookieManager.setCookie();this.log("Initial score received:",X.bot_score,"in",(K.getTimings().initialScoreReceived??0)-(K.getTimings().startCalled??0),"ms from start")}}handleScoreUpdate(Q){if(this.cookieManager)this.cookieManager.updateRiskTier(Q.bot_score);let X=this.getBotScoreLevel(Q.bot_score),Y=Q.bot_score>=this.config.actionThreshold;if(this.shouldTriggerAlert(X)){let Z={score:Q.bot_score,level:X,scoreUpdate:Q,sessionId:this.sessionId,fingerprintHash:this.fingerprint?.hash};if(Y&&!this.highScoreTriggeredLevels.has(X))this.executeAction(Z);this.config.onHighBotScore?.(Z),this.highScoreTriggeredLevels.add(X)}}getBotScoreLevel(Q){let X=this.config.botScoreThresholds;if(Q>=X.critical)return"critical";if(Q>=X.high)return"high";if(Q>=X.medium)return"medium";return"low"}shouldTriggerAlert(Q){if(this.highScoreTriggeredLevels.has(Q))return!1;let X=["low","medium","high","critical"],Y=this.config.minAlertLevel,Z=X.indexOf(Q),$=X.indexOf(Y);return Z>=$}async executeAction(Q){let X=this.config.action;switch(this.log(`Executing action '${X}' for score ${Q.score}`),X){case"challenge":if(this.challengeManagerPromise)await this.challengeManagerPromise;if(this.challengeManager)this.challengeManager.blockFormsUntilSolved(Q.level);break;case"block":if(!this.formBlocked)this.blockForms();break;case"none":default:break}}blockForms(){if(this.formBlocked)return;this.formBlocked=!0,document.querySelectorAll("form").forEach((Q)=>{Q.addEventListener("submit",this.blockFormSubmit,!0)}),this.formObserver=new MutationObserver((Q)=>{Q.forEach((X)=>{X.addedNodes.forEach((Y)=>{if(Y instanceof HTMLFormElement)Y.addEventListener("submit",this.blockFormSubmit,!0);if(Y instanceof HTMLElement)Y.querySelectorAll("form").forEach((Z)=>{Z.addEventListener("submit",this.blockFormSubmit,!0)})})})}),this.formObserver.observe(document.body,{childList:!0,subtree:!0}),this.log("Forms blocked due to high bot score")}blockFormSubmit=(Q)=>{Q.preventDefault(),Q.stopPropagation(),this.log("Form submission blocked due to high bot score");return};isFormsBlocked(){return this.formBlocked}unblockForms(){if(!this.formBlocked)return;if(this.formObserver)this.formObserver.disconnect(),this.formObserver=null;document.querySelectorAll("form").forEach((Q)=>{Q.removeEventListener("submit",this.blockFormSubmit,!0)}),this.formBlocked=!1,this.log("Forms unblocked")}getHashModule(){return this.hashModule}createSignature(Q){let X=this.config.hashVerification.secret;if(!X)return this.log("Cannot create signature: no secret configured"),null;return createSignature(Q,X)}verifySignature(Q,X){let Y=this.config.hashVerification.secret;if(!Y)return this.log("Cannot verify signature: no secret configured"),!1;return verifySignature(Q,X,Y)}isChallengeSolving(){return this.challengeManager?.isSolving()??!1}isChallengeSolved(){return this.challengeManager?.isSolved()??!1}getPerformanceSummary(){return K.getSummary()}logPerformance(){K.logSummary()}getPerformanceReport(){return K.getReport()}async waitUntilReady(){if(this.lastScore)return{score:this.lastScore.bot_score,timedOut:!1};if(this.formProtectionManager)return this.formProtectionManager.waitUntilReady();return new Promise((Q)=>{let X=performance.now(),Y=5000,Z=()=>{if(this.lastScore){Q({score:this.lastScore.bot_score,timedOut:!1});return}if(performance.now()-X>=5000){Q({score:null,timedOut:!0});return}setTimeout(Z,50)};Z()})}withProtection(Q,X={}){let Y=X.blockThreshold??this.config.actionThreshold;return async(...Z)=>{let{score:$,timedOut:J}=await this.waitUntilReady();if(K.markFirstSubmitAttempt($!==null),$!==null&&$>=Y)throw this.log(`Blocking submission: score ${$} >= threshold ${Y}`),Error(`Submission blocked: bot score ${$} exceeds threshold`);if(J)this.log("Warning: submitting without detection score (timed out)");return Q(...Z)}}protectedFetch(Q={}){return this.withProtection(async(X,Y)=>{return fetch(X,Y)},Q)}canSubmit(){if(!this.lastScore)return{allowed:!1,reason:"waiting_for_score",score:null};if(this.lastScore.bot_score>=this.config.actionThreshold)return{allowed:!1,reason:"high_bot_score",score:this.lastScore.bot_score};return{allowed:!0,score:this.lastScore.bot_score}}async triggerChallenge(Q="high"){if(this.challengeManagerPromise)await this.challengeManagerPromise;if(!this.challengeManager){this.log("Challenge not enabled");return}this.challengeManager.blockFormsUntilSolved(Q)}async disconnect(){if(this.socket)await this.socket.leaveChannel(),this.socket.disconnect(),this.socket=null}startSendInterval(){this.stopSendInterval(),this.sendTimer=setInterval(()=>{this.sendSignal()},this.config.sendInterval)}stopSendInterval(){if(this.sendTimer)clearInterval(this.sendTimer),this.sendTimer=null}registerBeforeUnload(){this.boundBeforeUnload=()=>{this.handleBeforeUnload()},this.boundVisibilityChange=()=>{if(document.visibilityState==="hidden")this.handleBeforeUnload()},window.addEventListener("beforeunload",this.boundBeforeUnload),document.addEventListener("visibilitychange",this.boundVisibilityChange)}unregisterBeforeUnload(){if(this.boundBeforeUnload)window.removeEventListener("beforeunload",this.boundBeforeUnload),this.boundBeforeUnload=null;if(this.boundVisibilityChange)document.removeEventListener("visibilitychange",this.boundVisibilityChange),this.boundVisibilityChange=null}handleBeforeUnload(){if(!this.isRunning||!this.socket)return;try{let Q=this.buildPayload();if(this.socket.isReady())this.socket.sendSignal(Q).catch(()=>{})}catch{}}handleFormSubmit(){if(!this.isRunning)return;if(K.markFirstSubmitAttempt(this.lastScore!==null),this.log("Form submitted, flushing signals via beacon"),this.log("Had score before submit:",this.lastScore!==null),this.updateFormStatus("completed"),!this.sessionId){this.log("No session ID yet, cannot send beacon");return}let Q=this.buildPayload();if(!this.sendViaBeacon(Q))this.sendSignal().catch((Y)=>{this.log("Failed to flush signals on form submit",Y)});else this.mouseCollector.flush(),this.scrollCollector.flush(),this.formCollector.flush()}sendViaBeacon(Q){if(!navigator.sendBeacon)return this.log("sendBeacon not available"),!1;try{let X=new URL(this.config.endpoint),Y=`${X.protocol==="wss:"?"https:":"http:"}//${X.host}/api/signal`,Z=JSON.stringify({session_id:this.sessionId,api_key:this.config.apiKey,payload:Q,form_status:this.formSubmissionStatus}),$=new Blob([Z],{type:"application/json"}),J=navigator.sendBeacon(Y,$);return this.log("Beacon sent:",J),J}catch(X){return this.log("Beacon send failed:",X),!1}}buildPayload(){this.sequenceNumber++;let Q={session_id:this.sessionId,seq:this.sequenceNumber,mouse:this.mouseCollector.getSignal(),scroll:this.scrollCollector.getSignal(),form:this.formCollector.getSignal(),timestamp:Date.now()};if(!this.hasSentInitial)Q.session=this.getSessionData(),Q.fingerprint=this.fingerprint,Q.browser=this.browserSignal;return Q}getSessionData(){let Q=new URL(window.location.href),X={};Q.searchParams.forEach((Z,$)=>{X[$]=Z});let Y=null;if(document.referrer)try{Y=new URL(document.referrer).hostname}catch{}return{url_path:Q.pathname,url_params:X,referrer_url:document.referrer||null,referrer_domain:Y,user_agent:navigator.userAgent}}generateSessionId(){if(crypto.randomUUID)return crypto.randomUUID();return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(Q)=>{let X=Math.random()*16|0;return(Q==="x"?X:X&3|8).toString(16)})}updateFormStatus(Q){if(this.formSubmissionStatus==="challenged"||this.formSubmissionStatus==="flagged"||this.formSubmissionStatus==="blocked"||this.formSubmissionStatus==="completed"){this.log(`Form status already terminal (${this.formSubmissionStatus}), ignoring ${Q}`);return}if(this.formSubmissionStatus=Q,this.log(`Form status updated to: ${Q}`),this.socket?.isReady())this.socket.sendFormStatus(Q).catch((X)=>{this.log("Failed to send form status:",X)})}log(...Q){if(this.config.debug);}}var O=null;function xQ(Q){if(O)return O;return O=new S(Q),O}function CQ(){return O}async function LQ(){if(O)await O.stop(),O=null}var AQ=S;export{f as logPerformanceSummary,kQ as loadHashModule,T as isUsageLimitError,xQ as init,l as getPerformanceSummary,N as getPerformanceMetrics,CQ as getInstance,LQ as destroy,AQ as default,q as DEFAULT_CONFIG,S as BotSigged};
|
|
41
41
|
|
|
42
|
-
//# debugId=
|
|
42
|
+
//# debugId=67E836F3564839B064756E2164756E21
|