@affogatosoftware/recorder 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,4 +20,31 @@ This can be passed in using the MaskingLevel enum (ex. MaskingLevel.InputAndText
20
20
 
21
21
  ### Masking specific html elements
22
22
 
23
- To mask all text in specific html elements (and their children) add the css class **scry-block**.
23
+ To mask all text in specific html elements (and their children) add the css class **scry-block**.
24
+
25
+ ### User Identification
26
+
27
+ You can identify users in your recordings to connect anonymous sessions with known user identities:
28
+
29
+ ```javascript
30
+ recorder.identify('user_123');
31
+ ```
32
+
33
+ **Key features:**
34
+ * Call `identify()` before or after starting the recorder - it works both ways
35
+ * User identification is automatically sent to your backend
36
+ * Non-blocking - recording continues even if identification fails
37
+ * Overwrites previous identification if called multiple times
38
+
39
+ **Example integration:**
40
+ ```javascript
41
+ const recorder = new window.scryspell.Recorder(window, 'YOUR_API_TOKEN', { maskingLevel: "all" });
42
+ recorder.start();
43
+
44
+ // Later, when user logs in
45
+ fetch('/api/current-user')
46
+ .then(response => response.json())
47
+ .then(user => {
48
+ recorder.identify(user.id);
49
+ });
50
+ ```
@@ -8,5 +8,5 @@ or you can use record.mirror to access the mirror instance during recording.`;le
8
8
  `+reasons.map(renderReason).join(`
9
9
  `):" "+renderReason(reasons[0]):"as no adapter specified";throw new AxiosError$1("There is no suitable adapter to dispatch the request "+s,"ERR_NOT_SUPPORT")}return adapter},adapters:knownAdapters};function throwIfCancellationRequested(config){if(config.cancelToken&&config.cancelToken.throwIfRequested(),config.signal&&config.signal.aborted)throw new CanceledError$1(null,config)}function dispatchRequest(config){return throwIfCancellationRequested(config),config.headers=AxiosHeaders$1.from(config.headers),config.data=transformData.call(config,config.transformRequest),["post","put","patch"].indexOf(config.method)!==-1&&config.headers.setContentType("application/x-www-form-urlencoded",!1),adapters.getAdapter(config.adapter||defaults.adapter)(config).then(function(response){return throwIfCancellationRequested(config),response.data=transformData.call(config,config.transformResponse,response),response.headers=AxiosHeaders$1.from(response.headers),response},function(reason){return isCancel$1(reason)||(throwIfCancellationRequested(config),reason&&reason.response&&(reason.response.data=transformData.call(config,config.transformResponse,reason.response),reason.response.headers=AxiosHeaders$1.from(reason.response.headers))),Promise.reject(reason)})}const VERSION$2="1.11.0",validators$1={};["object","boolean","number","function","string","symbol"].forEach((type,i2)=>{validators$1[type]=function(thing){return typeof thing===type||"a"+(i2<1?"n ":" ")+type}});const deprecatedWarnings={};validators$1.transitional=function(validator2,version,message){function formatMessage(opt,desc){return"[Axios v"+VERSION$2+"] Transitional option '"+opt+"'"+desc+(message?". "+message:"")}return(value,opt,opts)=>{if(validator2===!1)throw new AxiosError$1(formatMessage(opt," has been removed"+(version?" in "+version:"")),AxiosError$1.ERR_DEPRECATED);return version&&!deprecatedWarnings[opt]&&(deprecatedWarnings[opt]=!0,console.warn(formatMessage(opt," has been deprecated since v"+version+" and will be removed in the near future"))),validator2?validator2(value,opt,opts):!0}},validators$1.spelling=function(correctSpelling){return(value,opt)=>(console.warn(`${opt} is likely a misspelling of ${correctSpelling}`),!0)};function assertOptions(options,schema,allowUnknown){if(typeof options!="object")throw new AxiosError$1("options must be an object",AxiosError$1.ERR_BAD_OPTION_VALUE);const keys=Object.keys(options);let i2=keys.length;for(;i2-- >0;){const opt=keys[i2],validator2=schema[opt];if(validator2){const value=options[opt],result=value===void 0||validator2(value,opt,options);if(result!==!0)throw new AxiosError$1("option "+opt+" must be "+result,AxiosError$1.ERR_BAD_OPTION_VALUE);continue}if(allowUnknown!==!0)throw new AxiosError$1("Unknown option "+opt,AxiosError$1.ERR_BAD_OPTION)}}const validator={assertOptions,validators:validators$1},validators=validator.validators;let Axios$1=class{constructor(instanceConfig){this.defaults=instanceConfig||{},this.interceptors={request:new InterceptorManager,response:new InterceptorManager}}async request(configOrUrl,config){try{return await this._request(configOrUrl,config)}catch(err){if(err instanceof Error){let dummy={};Error.captureStackTrace?Error.captureStackTrace(dummy):dummy=new Error;const stack=dummy.stack?dummy.stack.replace(/^.+\n/,""):"";try{err.stack?stack&&!String(err.stack).endsWith(stack.replace(/^.+\n.+\n/,""))&&(err.stack+=`
10
10
  `+stack):err.stack=stack}catch{}}throw err}}_request(configOrUrl,config){typeof configOrUrl=="string"?(config=config||{},config.url=configOrUrl):config=configOrUrl||{},config=mergeConfig$1(this.defaults,config);const{transitional,paramsSerializer,headers}=config;transitional!==void 0&&validator.assertOptions(transitional,{silentJSONParsing:validators.transitional(validators.boolean),forcedJSONParsing:validators.transitional(validators.boolean),clarifyTimeoutError:validators.transitional(validators.boolean)},!1),paramsSerializer!=null&&(utils$1.isFunction(paramsSerializer)?config.paramsSerializer={serialize:paramsSerializer}:validator.assertOptions(paramsSerializer,{encode:validators.function,serialize:validators.function},!0)),config.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?config.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:config.allowAbsoluteUrls=!0),validator.assertOptions(config,{baseUrl:validators.spelling("baseURL"),withXsrfToken:validators.spelling("withXSRFToken")},!0),config.method=(config.method||this.defaults.method||"get").toLowerCase();let contextHeaders=headers&&utils$1.merge(headers.common,headers[config.method]);headers&&utils$1.forEach(["delete","get","head","post","put","patch","common"],method=>{delete headers[method]}),config.headers=AxiosHeaders$1.concat(contextHeaders,headers);const requestInterceptorChain=[];let synchronousRequestInterceptors=!0;this.interceptors.request.forEach(function(interceptor){typeof interceptor.runWhen=="function"&&interceptor.runWhen(config)===!1||(synchronousRequestInterceptors=synchronousRequestInterceptors&&interceptor.synchronous,requestInterceptorChain.unshift(interceptor.fulfilled,interceptor.rejected))});const responseInterceptorChain=[];this.interceptors.response.forEach(function(interceptor){responseInterceptorChain.push(interceptor.fulfilled,interceptor.rejected)});let promise,i2=0,len;if(!synchronousRequestInterceptors){const chain=[dispatchRequest.bind(this),void 0];for(chain.unshift(...requestInterceptorChain),chain.push(...responseInterceptorChain),len=chain.length,promise=Promise.resolve(config);i2<len;)promise=promise.then(chain[i2++],chain[i2++]);return promise}len=requestInterceptorChain.length;let newConfig=config;for(i2=0;i2<len;){const onFulfilled=requestInterceptorChain[i2++],onRejected=requestInterceptorChain[i2++];try{newConfig=onFulfilled(newConfig)}catch(error){onRejected.call(this,error);break}}try{promise=dispatchRequest.call(this,newConfig)}catch(error){return Promise.reject(error)}for(i2=0,len=responseInterceptorChain.length;i2<len;)promise=promise.then(responseInterceptorChain[i2++],responseInterceptorChain[i2++]);return promise}getUri(config){config=mergeConfig$1(this.defaults,config);const fullPath=buildFullPath(config.baseURL,config.url,config.allowAbsoluteUrls);return buildURL(fullPath,config.params,config.paramsSerializer)}};utils$1.forEach(["delete","get","head","options"],function(method){Axios$1.prototype[method]=function(url,config){return this.request(mergeConfig$1(config||{},{method,url,data:(config||{}).data}))}}),utils$1.forEach(["post","put","patch"],function(method){function generateHTTPMethod(isForm){return function(url,data,config){return this.request(mergeConfig$1(config||{},{method,headers:isForm?{"Content-Type":"multipart/form-data"}:{},url,data}))}}Axios$1.prototype[method]=generateHTTPMethod(),Axios$1.prototype[method+"Form"]=generateHTTPMethod(!0)});let CancelToken$1=class CancelToken2{constructor(executor){if(typeof executor!="function")throw new TypeError("executor must be a function.");let resolvePromise;this.promise=new Promise(function(resolve){resolvePromise=resolve});const token=this;this.promise.then(cancel=>{if(!token._listeners)return;let i2=token._listeners.length;for(;i2-- >0;)token._listeners[i2](cancel);token._listeners=null}),this.promise.then=onfulfilled=>{let _resolve;const promise=new Promise(resolve=>{token.subscribe(resolve),_resolve=resolve}).then(onfulfilled);return promise.cancel=function(){token.unsubscribe(_resolve)},promise},executor(function(message,config,request){token.reason||(token.reason=new CanceledError$1(message,config,request),resolvePromise(token.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(listener){if(this.reason){listener(this.reason);return}this._listeners?this._listeners.push(listener):this._listeners=[listener]}unsubscribe(listener){if(!this._listeners)return;const index=this._listeners.indexOf(listener);index!==-1&&this._listeners.splice(index,1)}toAbortSignal(){const controller=new AbortController,abort=err=>{controller.abort(err)};return this.subscribe(abort),controller.signal.unsubscribe=()=>this.unsubscribe(abort),controller.signal}static source(){let cancel;return{token:new CancelToken2(function(c){cancel=c}),cancel}}};function spread$1(callback){return function(arr){return callback.apply(null,arr)}}function isAxiosError$1(payload){return utils$1.isObject(payload)&&payload.isAxiosError===!0}const HttpStatusCode$1={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(HttpStatusCode$1).forEach(([key,value])=>{HttpStatusCode$1[value]=key});function createInstance(defaultConfig){const context=new Axios$1(defaultConfig),instance=bind(Axios$1.prototype.request,context);return utils$1.extend(instance,Axios$1.prototype,context,{allOwnKeys:!0}),utils$1.extend(instance,context,null,{allOwnKeys:!0}),instance.create=function(instanceConfig){return createInstance(mergeConfig$1(defaultConfig,instanceConfig))},instance}const axios=createInstance(defaults);axios.Axios=Axios$1,axios.CanceledError=CanceledError$1,axios.CancelToken=CancelToken$1,axios.isCancel=isCancel$1,axios.VERSION=VERSION$2,axios.toFormData=toFormData$1,axios.AxiosError=AxiosError$1,axios.Cancel=axios.CanceledError,axios.all=function(promises){return Promise.all(promises)},axios.spread=spread$1,axios.isAxiosError=isAxiosError$1,axios.mergeConfig=mergeConfig$1,axios.AxiosHeaders=AxiosHeaders$1,axios.formToJSON=thing=>formDataToJSON(utils$1.isHTMLForm(thing)?new FormData(thing):thing),axios.getAdapter=adapters.getAdapter,axios.HttpStatusCode=HttpStatusCode$1,axios.default=axios;const{Axios,AxiosError,CanceledError,isCancel,CancelToken,VERSION:VERSION$1,all,Cancel,isAxiosError,spread,toFormData,AxiosHeaders,HttpStatusCode,formToJSON,getAdapter,mergeConfig}=axios,api=axios.create({baseURL:"https://scryspell.com",withCredentials:!0}),post=(url,data,config)=>api.post(url,data,config),put=(url,data,config)=>api.put(url,data,config),patch=(url,data,config)=>api.patch(url,data,config),logger={info:(...args)=>{console.log("info",...args)},warn:(...args)=>{console.log("warn",...args)},error:(...args)=>{console.log("error",...args)}};class SessionRecorder{constructor(recorderSettings){this.recorderSettings=recorderSettings,this.buffer={data:[]},this.flushIntervalMs=2e3}capturedSessionId=null;buffer;stopFn;flushIntervalMs;flushTimer;setCapturedSessionId(id){this.capturedSessionId=id}start=()=>{if(Object.assign===void 0)return;this.buffer={data:[]};const recordOptions={emit:event=>{this.buffer.data.push(event)},blockClass:"scry-block"},maskFn=input=>input.replaceAll(/\S/g,"*");switch(this.recorderSettings.maskingLevel){case"none":break;case"all":recordOptions.maskTextFn=maskFn,recordOptions.maskTextSelector="*",recordOptions.maskAllInputs=!0,recordOptions.maskInputFn=maskFn;break;case"input-and-textarea":recordOptions.maskAllInputs=!0;break;case"input-password-or-email-and-textarea":recordOptions.maskInputOptions={password:!0,email:!0,textarea:!0};break;default:recordOptions.maskTextFn=maskFn,recordOptions.maskTextSelector="*",recordOptions.maskAllInputs=!0,recordOptions.maskInputFn=maskFn}this.stopFn=record(recordOptions),this.scheduleFlush()};scheduleFlush=()=>{this.flushTimer&&clearTimeout(this.flushTimer),this.flushTimer=setTimeout(this.flush,this.flushIntervalMs)};flush=async()=>{if(this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=void 0),this.capturedSessionId&&this.buffer.data.length>0)try{let response=await patch(`public/captured-sessions/${this.capturedSessionId}/recording`,this.buffer,{withCredentials:!1});response.status>=400?(logger.error(`status ${response.status} when trying to save session recording data.`),logger.error(response.data)):this.clearAllBufferData()}catch(error){logger.error("Error flushing session data:",error)}this.scheduleFlush()};stop=()=>{this.stopFn&&this.stopFn(),this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=void 0)};clearAllBufferData=()=>{this.buffer.data=[]}}class EventRecorder{constructor(window2,recorderSettings){this.window=window2,this.recorderSettings=recorderSettings}eventsBuffer=[];isRunning=!1;tagsToCapture=new Set(["button","a","select","textarea","input"]);queryParamsAllowed=new Set(["utm_source","source","ref","utm_medium","medium","utm_campaign","campaign","utm_content","content","utm_term","term"]);flushIntervalMs=2e3;capturedSessionId;flushTimerId=null;start=()=>{if(this.isRunning)return;this.isRunning=!0,this.eventsBuffer=[];const originalPushState=this.window.history.pushState.bind(this.window.history);this.window.history.pushState=(data,unused,url)=>{let urlString="";return url instanceof URL?urlString=url.toString():url?urlString=url:urlString="",this.handlePageView(urlString),originalPushState(data,unused,url)},this.window.addEventListener("pageshow",e=>{try{this.handlePageView(this.window.location.pathname)}catch(error){logger.error("Failed to capture URL change event",error)}}),this.window.addEventListener("change",this.handler),this.window.addEventListener("click",this.handler),this.window.addEventListener("keydown",this.handler),this.scheduleFlush()};scheduleFlush=()=>{this.flushTimerId&&clearTimeout(this.flushTimerId),this.flushTimerId=setTimeout(this.flush,this.flushIntervalMs)};flush=async()=>{if(this.eventsBuffer.length>0&&this.capturedSessionId)try{const response=await post(`/public/captured-sessions/${this.capturedSessionId}/ui-events`,this.eventsBuffer,{withCredentials:!1});response.status!==201&&logger.error("Failed to save ui events",response.data),this.eventsBuffer=[]}catch(error){logger.error("Failed to save ui events",error),this.eventsBuffer=[]}this.scheduleFlush()};handlePageView=path=>{if(this.isRunning)try{const timestamp=Date.now();path.charAt(0)==="/"||(path=this.window.location.pathname+"/"+path);const url=new URL(this.window.location.protocol+"//"+this.window.location.host+path+this.window.location.search),sanitizedUrlString=this.sanitizeUrlParams(url.toString(),this.queryParamsAllowed),sanitizedUrl=new URL(sanitizedUrlString),searchParamsArray=Array.from(sanitizedUrl.searchParams),interactionEvent={eventType:"page_view",timestamp,text:path,host:sanitizedUrl.hostname,path};searchParamsArray.length>0&&(interactionEvent.queryParams=searchParamsArray),this.eventsBuffer.push(interactionEvent)}catch(error){logger.error("Failed to capture URL change event",error)}};sanitizeUrlParams=(url,paramsAllowed)=>{try{const urlObj=new URL(url);for(const key of urlObj.searchParams.keys())paramsAllowed.has(key.toLowerCase())||urlObj.searchParams.set(key,"$redacted");return urlObj.toString()}catch(e){return logger.error("Failed to sanitize URL params",e),url}};handler=e=>{if(this.isRunning)try{const eventType=e.type,target=e.target,tagName=target?.tagName.toLowerCase();if(!(tagName&&this.tagsToCapture.has(tagName)))return;const url=new URL(this.window.location.href),host=url.hostname,path=url.pathname,timestamp=Date.now(),domContext=this.captureDomContext(target);switch(e.type){case"click":const clickEvent=this.handleClick(target,tagName,timestamp,host,path);this.eventsBuffer.push(clickEvent);break;case"keydown":const keyEvent=this.handleKeyDown(e,tagName,target,timestamp,host,path);this.eventsBuffer.push(keyEvent);break;case"change":const changeEvent=this.handleChange(target,tagName,timestamp,host,path);this.eventsBuffer.push(changeEvent);break;default:this.eventsBuffer.push({eventType,tagName,timestamp,host,path,text:null,domContext})}}catch(error){logger.error("Failed to capture event",error)}};handleChange(target,tagName,timestamp,host,path){let text=null;switch(target instanceof HTMLSelectElement&&(text=target.options[target.selectedIndex].text),this.recorderSettings.maskingLevel){case"none":break;case"all":text=null;break;case"input-and-textarea":break;case"input-password-or-email-and-textarea":break;default:text=null}return{eventType:"change",tagName,timestamp,text:text===""?null:text,host,path,domContext:this.captureDomContext(target)}}handleClick(target,tagName,timestamp,host,path){let text="";if(target instanceof HTMLInputElement||target instanceof HTMLTextAreaElement){const labelText=this.findInputOrSelectOrTextAreaLabel(target);labelText?text=labelText:target.placeholder&&(text=target.placeholder)}else if(target instanceof HTMLSelectElement){const labelText=this.findInputOrSelectOrTextAreaLabel(target);labelText?text=labelText:text=target.value+" ("+target.options[target.selectedIndex].text+")"}else target instanceof HTMLButtonElement?text=target.innerText:target instanceof HTMLAnchorElement?text=target.href:target instanceof HTMLImageElement&&(text=target.src);switch(this.recorderSettings.maskingLevel){case"none":break;case"all":text=null;break;case"input-and-textarea":(target instanceof HTMLInputElement||target instanceof HTMLTextAreaElement)&&(text=null);break;case"input-password-or-email-and-textarea":(target instanceof HTMLTextAreaElement||target instanceof HTMLInputElement&&(target.type==="password"||target.type==="email"||target.type==="e-mail"))&&(text=null);break;default:text=null}return{eventType:"click",tagName,timestamp,text:text===""?null:text,host,path,domContext:this.captureDomContext(target)}}handleKeyDown(e,tagName,target,timestamp,host,path){const key=e.key;let text=null;if(target instanceof HTMLInputElement||target instanceof HTMLTextAreaElement){const labelText=this.findInputOrSelectOrTextAreaLabel(target);labelText?text=labelText:target.placeholder&&(text=target.placeholder)}switch(this.recorderSettings.maskingLevel){case"none":break;case"all":text=null;break;case"input-and-textarea":(target instanceof HTMLInputElement||target instanceof HTMLTextAreaElement)&&(text=null);break;case"input-password-or-email-and-textarea":(target instanceof HTMLTextAreaElement||target instanceof HTMLInputElement&&(target.type==="password"||target.type==="email"||target.type==="e-mail"))&&(text=null);break;default:text=null}return{eventType:"keydown",tagName,timestamp,text,key,host,path,domContext:this.captureDomContext(target)}}findInputOrSelectOrTextAreaLabel=el=>{if(!el||!new Set(["input","select","textarea"]).has(el.tagName.toLowerCase()))return null;const wrappingLabel=el.closest("label");if(wrappingLabel){const text=Array.from(wrappingLabel.childNodes).filter(node=>node.nodeName.toLowerCase()!=="select").map(node=>(node.textContent??"").trim()).filter(Boolean).join(" ").trim();if(text)return text}const id=el.id;if(id){const explicitLabel=el.ownerDocument.querySelector(`label[for="${CSS.escape(id)}"]`);if(explicitLabel){const text=Array.from(explicitLabel.childNodes).filter(node=>node.nodeName.toLowerCase()!=="select").map(node=>(node.textContent??"").trim()).filter(Boolean).join(" ").trim();if(text)return text}}const ariaLabel=el.getAttribute("aria-label");if(ariaLabel)return ariaLabel.trim();const ariaLabelledBy=el.getAttribute("aria-labelledby");return ariaLabelledBy&&el.ownerDocument.getElementById(ariaLabelledBy)?.textContent?.trim()||null};stop=()=>{this.isRunning=!1,this.window.removeEventListener("change",this.handler),this.window.removeEventListener("click",this.handler),this.window.removeEventListener("keydown",this.handler),this.flushTimerId&&(clearTimeout(this.flushTimerId),this.flushTimerId=null)};captureDomContext=targetElement=>{const context=[];context.push(this.toJsonNode(targetElement));let current=targetElement.parentElement;for(;current!=null&&context.length<6;)context.push(this.toJsonNode(current)),current=current.parentElement;return context};toJsonNode=node=>{const attrs={};return["id","class","name","type","role","aria-label"].forEach(key=>{const val=node.getAttribute(key);val&&(attrs[key]=val)}),{tag:node.tagName.toLowerCase(),attrs}};setCapturedSessionId(uuid){this.capturedSessionId=uuid}}class ErrorRecorder{constructor(window2,consoleErrorSettings){this.window=window2,this.originalConsoleError=console.error.bind(console),this.originalConsoleWarn=console.warn.bind(console),this.enabled=consoleErrorSettings?.enabled??!1}errorsBuffer=[];isRunning=!1;flushIntervalMs=2e3;capturedSessionId;flushTimerId=null;originalConsoleError;originalConsoleWarn;enabled;start=()=>{this.isRunning||!this.enabled||(this.isRunning=!0,this.errorsBuffer=[],console.error=(...args)=>{this.captureConsoleError("console_error",args),this.originalConsoleError(...args)},console.warn=(...args)=>{this.captureConsoleError("console_warn",args),this.originalConsoleWarn(...args)},this.window.addEventListener("error",this.handleUncaughtError),this.window.addEventListener("unhandledrejection",this.handleUnhandledRejection),this.scheduleFlush())};stop=()=>{this.isRunning=!1,console.error=this.originalConsoleError,console.warn=this.originalConsoleWarn,this.window.removeEventListener("error",this.handleUncaughtError),this.window.removeEventListener("unhandledrejection",this.handleUnhandledRejection),this.flushTimerId&&(clearTimeout(this.flushTimerId),this.flushTimerId=null)};captureConsoleError=(errorType,args)=>{if(this.isRunning)try{const message=args.map(arg=>typeof arg=="object"?JSON.stringify(arg):String(arg)).join(" "),error={errorType,message,timestamp:Date.now()};args.length>0&&args[0]instanceof Error&&(error.stack=args[0].stack),this.errorsBuffer.push(error)}catch(captureError){logger.error("Failed to capture console error",captureError)}};handleUncaughtError=event=>{if(this.isRunning)try{const error={errorType:"uncaught_error",message:event.message,stack:event.error?.stack,timestamp:Date.now(),source:event.filename?`${event.filename}:${event.lineno}:${event.colno}`:void 0};this.errorsBuffer.push(error)}catch(captureError){logger.error("Failed to capture uncaught error",captureError)}};handleUnhandledRejection=event=>{if(this.isRunning)try{let message,stack;event.reason instanceof Error?(message=event.reason.message,stack=event.reason.stack):message=String(event.reason);const error={errorType:"unhandled_rejection",message,stack,timestamp:Date.now()};this.errorsBuffer.push(error)}catch(captureError){logger.error("Failed to capture unhandled rejection",captureError)}};scheduleFlush=()=>{this.flushTimerId&&clearTimeout(this.flushTimerId),this.flushTimerId=setTimeout(this.flush,this.flushIntervalMs)};flush=async()=>{if(this.errorsBuffer.length>0&&this.capturedSessionId)try{const response=await post(`/public/captured-sessions/${this.capturedSessionId}/console-errors`,this.errorsBuffer,{withCredentials:!1});this.errorsBuffer=[]}catch(error){logger.error("Failed to flush console errors",error),this.errorsBuffer=[]}this.scheduleFlush()};setCapturedSessionId(uuid){this.capturedSessionId=uuid}}class NetworkRecorder{constructor(window2,settings){this.window=window2,this.originalFetch=this.window.fetch.bind(this.window),this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send,settings&&(this.networkSettings={...this.networkSettings,...settings})}requestsBuffer=[];pendingRequests=new Map;isRunning=!1;flushIntervalMs=2e3;capturedSessionId;flushTimerId=null;originalFetch;originalXHROpen;originalXHRSend;queryParamsAllowed=new Set(["utm_source","source","ref","utm_medium","medium","utm_campaign","campaign","utm_content","content","utm_term","term"]);networkSettings={enabled:!1,maxRequestBodySize:10240,maxResponseBodySize:51200,excludeDomains:[],captureHeaders:!1,captureRequestBodies:!1,captureResponseBodies:!0,excludeHeaders:[]};start=()=>{this.isRunning||!this.networkSettings.enabled||(this.isRunning=!0,this.requestsBuffer=[],this.patchFetch(),this.patchXHR(),this.scheduleFlush())};stop=()=>{this.isRunning=!1,this.window.fetch=this.originalFetch,XMLHttpRequest.prototype.open=this.originalXHROpen,XMLHttpRequest.prototype.send=this.originalXHRSend,this.flushTimerId&&(clearTimeout(this.flushTimerId),this.flushTimerId=null)};setCapturedSessionId(uuid){this.capturedSessionId=uuid}scheduleFlush=()=>{this.flushTimerId&&clearTimeout(this.flushTimerId),this.flushTimerId=setTimeout(this.flush,this.flushIntervalMs)};flush=async()=>{if(this.requestsBuffer.length>0&&this.capturedSessionId)try{const response=await post(`/public/captured-sessions/${this.capturedSessionId}/network-requests`,this.requestsBuffer,{withCredentials:!1});response.status!==201&&logger.error("Failed to save network requests",response.data),this.requestsBuffer=[]}catch(error){logger.error("Failed to save network requests",error),this.requestsBuffer=[]}this.scheduleFlush()};patchFetch=()=>{const self2=this;this.window.fetch=async function(input,init){const requestId=self2.generateRequestId(),timestamp=Date.now();let url="",method="GET",requestHeaders={},requestBody;if(typeof input=="string")url=input;else if(input instanceof URL)url=input.toString();else if(input instanceof Request&&(url=input.url,method=input.method,self2.networkSettings.captureHeaders&&input.headers.forEach((value,key)=>{requestHeaders[key]=value}),self2.networkSettings.captureRequestBodies&&input.body))try{requestBody=await input.clone().text()}catch{}if(init&&(method=init.method||method,self2.networkSettings.captureHeaders&&init.headers&&(init.headers instanceof Headers?init.headers.forEach((value,key)=>{requestHeaders[key]=value}):Array.isArray(init.headers)?init.headers.forEach(([key,value])=>{requestHeaders[key]=value}):Object.assign(requestHeaders,init.headers)),self2.networkSettings.captureRequestBodies&&init.body))if(typeof init.body=="string")requestBody=init.body;else try{requestBody=JSON.stringify(init.body)}catch{requestBody="[Unable to serialize body]"}if(!self2.shouldCaptureRequest(url))return self2.originalFetch(input,init);const sanitizedUrl=self2.sanitizeUrl(url),filteredHeaders=self2.filterHeaders(requestHeaders),truncatedBody=self2.truncateRequestContent(requestBody,self2.networkSettings.maxRequestBodySize),networkRequest={requestId,type:"fetch",method:method.toUpperCase(),url:sanitizedUrl,requestHeaders:Object.keys(filteredHeaders).length>0?filteredHeaders:void 0,requestBody:truncatedBody,timestamp};self2.pendingRequests.set(requestId,networkRequest);try{const response=await self2.originalFetch(input,init),duration=Date.now()-timestamp;let responseHeaders={},responseBody;if(self2.networkSettings.captureHeaders&&response.headers.forEach((value,key)=>{responseHeaders[key]=value}),self2.networkSettings.captureResponseBodies)try{const text=await response.clone().text();responseBody=self2.truncateResponseContent(text,self2.networkSettings.maxResponseBodySize)}catch{responseBody="[Unable to read response body]"}const completedRequest={...networkRequest,responseStatus:response.status,responseHeaders:Object.keys(responseHeaders).length>0?self2.filterHeaders(responseHeaders):void 0,responseBody,duration};return self2.addCompletedRequest(requestId,completedRequest),response}catch(error){const duration=Date.now()-timestamp,errorRequest={...networkRequest,error:error instanceof Error?error.message:String(error),duration};throw self2.addCompletedRequest(requestId,errorRequest),error}}};patchXHR=()=>{const self2=this;XMLHttpRequest.prototype.open=function(method,url,async,username,password){const xhr=this,urlString=typeof url=="string"?url:url.toString();if(self2.shouldCaptureRequest(urlString)){const requestId=self2.generateRequestId(),timestamp=Date.now();xhr.__networkRecorder={requestId,timestamp,method:method.toUpperCase(),url:self2.sanitizeUrl(urlString)}}return self2.originalXHROpen.call(this,method,url,async??!0,username,password)},XMLHttpRequest.prototype.send=function(body){const xhr=this;if(xhr.__networkRecorder){const{requestId,timestamp,method,url}=xhr.__networkRecorder;let requestHeaders={},requestBody;if(self2.networkSettings.captureRequestBodies&&body)if(typeof body=="string")requestBody=body;else try{requestBody=JSON.stringify(body)}catch{requestBody="[Unable to serialize body]"}const networkRequest={requestId,type:"xhr",method,url,requestHeaders:Object.keys(requestHeaders).length>0?self2.filterHeaders(requestHeaders):void 0,requestBody:self2.truncateRequestContent(requestBody,self2.networkSettings.maxRequestBodySize),timestamp};self2.pendingRequests.set(requestId,networkRequest);const originalOnReadyStateChange=xhr.onreadystatechange;xhr.onreadystatechange=function(){if(xhr.readyState===XMLHttpRequest.DONE){const duration=Date.now()-timestamp;let responseHeaders={},responseBody;if(self2.networkSettings.captureHeaders){const headerString=xhr.getAllResponseHeaders();headerString&&headerString.split(`\r
11
- `).forEach(line=>{const parts=line.split(": ");parts.length===2&&(responseHeaders[parts[0]]=parts[1])})}if(self2.networkSettings.captureResponseBodies)try{responseBody=self2.truncateResponseContent(xhr.responseText,self2.networkSettings.maxResponseBodySize)}catch{responseBody="[Unable to read response]"}const completedRequest={...networkRequest,responseStatus:xhr.status,responseHeaders:Object.keys(responseHeaders).length>0?self2.filterHeaders(responseHeaders):void 0,responseBody,duration,error:xhr.status===0?"Network error":void 0};self2.addCompletedRequest(requestId,completedRequest)}originalOnReadyStateChange&&originalOnReadyStateChange.call(this,new Event("readystatechange"))}}return self2.originalXHRSend.call(this,body??null)}};shouldCaptureRequest(url){if(!this.isRunning||!this.networkSettings.enabled)return!1;try{const urlObj=new URL(url,this.window.location.href);return!(urlObj.pathname.includes("/public/captured-sessions")||this.networkSettings.excludeDomains.some(domain=>urlObj.hostname.includes(domain)))}catch{return!1}}sanitizeUrl(url){try{const urlObj=new URL(url,this.window.location.href);for(const key of urlObj.searchParams.keys())this.queryParamsAllowed.has(key.toLowerCase())||urlObj.searchParams.set(key,"$redacted");return urlObj.toString()}catch(e){return logger.error("Failed to sanitize URL",e),url}}filterHeaders(headers){const filtered={},defaultSensitiveHeaders=new Set(["authorization","cookie","x-api-key","x-auth-token","x-csrf-token","x-session-token","set-cookie"]),excludedHeaders=new Set([...defaultSensitiveHeaders,...this.networkSettings.excludeHeaders.map(h=>h.toLowerCase())]);for(const[key,value]of Object.entries(headers))excludedHeaders.has(key.toLowerCase())||(filtered[key]=value);return filtered}truncateRequestContent(content,maxSize){if(!content)return content;let processedContent=content;if(this.networkSettings.requestBodyMaskingFunction)try{processedContent=this.networkSettings.requestBodyMaskingFunction(content)}catch{logger.error("Failed to apply request masking function")}return processedContent.length>maxSize?processedContent.substring(0,maxSize)+`... [truncated from ${processedContent.length} chars]`:processedContent}truncateResponseContent(content,maxSize){if(!content)return content;let processedContent=content;if(this.networkSettings.responseBodyMaskingFunction)try{processedContent=this.networkSettings.responseBodyMaskingFunction(content)}catch{logger.error("Failed to apply response masking function")}return processedContent.length>maxSize?processedContent.substring(0,maxSize)+`... [truncated from ${processedContent.length} chars]`:processedContent}generateRequestId(){return`req_${crypto.randomUUID()}`}addCompletedRequest(requestId,request){this.pendingRequests.delete(requestId),this.isErrorRequest(request)&&this.requestsBuffer.push(request)}isErrorRequest(request){return!!(request.error||request.responseStatus&&request.responseStatus>=400)}}var LIBVERSION="2.0.4",UA_MAX_LENGTH=500,USER_AGENT="user-agent",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",UA_BROWSER="browser",UA_CPU="cpu",UA_DEVICE="device",UA_ENGINE="engine",UA_OS="os",UA_RESULT="result",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",MAJOR="major",MODEL="model",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",XR="xr",EMBEDDED="embedded",INAPP="inapp",BRANDS="brands",FORMFACTORS="formFactors",FULLVERLIST="fullVersionList",PLATFORM="platform",PLATFORMVER="platformVersion",BITNESS="bitness",CH_HEADER="sec-ch-ua",CH_HEADER_FULL_VER_LIST=CH_HEADER+"-full-version-list",CH_HEADER_ARCH=CH_HEADER+"-arch",CH_HEADER_BITNESS=CH_HEADER+"-"+BITNESS,CH_HEADER_FORM_FACTORS=CH_HEADER+"-form-factors",CH_HEADER_MOBILE=CH_HEADER+"-"+MOBILE,CH_HEADER_MODEL=CH_HEADER+"-"+MODEL,CH_HEADER_PLATFORM=CH_HEADER+"-"+PLATFORM,CH_HEADER_PLATFORM_VER=CH_HEADER_PLATFORM+"-version",CH_ALL_VALUES=[BRANDS,FULLVERLIST,MOBILE,MODEL,PLATFORM,PLATFORMVER,ARCHITECTURE,FORMFACTORS,BITNESS],AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",GOOGLE="Google",HUAWEI="Huawei",LENOVO="Lenovo",HONOR="Honor",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",NVIDIA="Nvidia",ONEPLUS="OnePlus",OPPO="OPPO",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",CHROME="Chrome",CHROMIUM="Chromium",CHROMECAST="Chromecast",EDGE="Edge",FIREFOX="Firefox",OPERA="Opera",FACEBOOK="Facebook",SOGOU="Sogou",PREFIX_MOBILE="Mobile ",SUFFIX_BROWSER=" Browser",WINDOWS="Windows",isWindow=typeof window!==UNDEF_TYPE,NAVIGATOR=isWindow&&window.navigator?window.navigator:void 0,NAVIGATOR_UADATA=NAVIGATOR&&NAVIGATOR.userAgentData?NAVIGATOR.userAgentData:void 0,extend=function(defaultRgx,extensions){var mergedRgx={},extraRgx=extensions;if(!isExtensions(extensions)){extraRgx={};for(var i2 in extensions)for(var j in extensions[i2])extraRgx[j]=extensions[i2][j].concat(extraRgx[j]?extraRgx[j]:[])}for(var k in defaultRgx)mergedRgx[k]=extraRgx[k]&&extraRgx[k].length%2===0?extraRgx[k].concat(defaultRgx[k]):defaultRgx[k];return mergedRgx},enumerize=function(arr){for(var enums={},i2=0;i2<arr.length;i2++)enums[arr[i2].toUpperCase()]=arr[i2];return enums},has=function(str1,str2){if(typeof str1===OBJ_TYPE&&str1.length>0){for(var i2 in str1)if(lowerize(str2)==lowerize(str1[i2]))return!0;return!1}return isString(str1)?lowerize(str2)==lowerize(str1):!1},isExtensions=function(obj,deep){for(var prop in obj)return/^(browser|cpu|device|engine|os)$/.test(prop)||(deep?isExtensions(obj[prop]):!1)},isString=function(val){return typeof val===STR_TYPE},itemListToArray=function(header){if(header){for(var arr=[],tokens=strip(/\\?\"/g,header).split(","),i2=0;i2<tokens.length;i2++)if(tokens[i2].indexOf(";")>-1){var token=trim(tokens[i2]).split(";v=");arr[i2]={brand:token[0],version:token[1]}}else arr[i2]=trim(tokens[i2]);return arr}},lowerize=function(str){return isString(str)?str.toLowerCase():str},majorize=function(version){return isString(version)?strip(/[^\d\.]/g,version).split(".")[0]:void 0},setProps=function(arr){for(var i2 in arr){var propName=arr[i2];typeof propName==OBJ_TYPE&&propName.length==2?this[propName[0]]=propName[1]:this[propName]=void 0}return this},strip=function(pattern,str){return isString(str)?str.replace(pattern,EMPTY):str},stripQuotes=function(str){return strip(/\\?\"/g,str)},trim=function(str,len){if(isString(str))return str=strip(/^\s\s*/,str),typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)},rgxMapper=function(ua,arrays){if(!(!ua||!arrays))for(var i2=0,j,k,p,q,matches,match;i2<arrays.length&&!matches;){var regex=arrays[i2],props=arrays[i2+1];for(j=k=0;j<regex.length&&!matches&&regex[j];)if(matches=regex[j++].exec(ua),matches)for(p=0;p<props.length;p++)match=matches[++k],q=props[p],typeof q===OBJ_TYPE&&q.length>0?q.length===2?typeof q[1]==FUNC_TYPE?this[q[0]]=q[1].call(this,match):this[q[0]]=q[1]:q.length>=3&&(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)?q.length>3?this[q[0]]=match?q[1].apply(this,q.slice(2)):void 0:this[q[0]]=match?q[1].call(this,match,q[2]):void 0:q.length==3?this[q[0]]=match?match.replace(q[1],q[2]):void 0:q.length==4?this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):void 0:q.length>4&&(this[q[0]]=match?q[3].apply(this,[match.replace(q[1],q[2])].concat(q.slice(4))):void 0)):this[q]=match||void 0;i2+=2}},strMapper=function(str,map){for(var i2 in map)if(typeof map[i2]===OBJ_TYPE&&map[i2].length>0){for(var j=0;j<map[i2].length;j++)if(has(map[i2][j],str))return i2===UNKNOWN?void 0:i2}else if(has(map[i2],str))return i2===UNKNOWN?void 0:i2;return map.hasOwnProperty("*")?map["*"]:str},windowsVersionMap={ME:"4.90","NT 3.51":"3.51","NT 4.0":"4.0",2e3:["5.0","5.01"],XP:["5.1","5.2"],Vista:"6.0",7:"6.1",8:"6.2","8.1":"6.3",10:["6.4","10.0"],NT:""},formFactorsMap={embedded:"Automotive",mobile:"Mobile",tablet:["Tablet","EInk"],smarttv:"TV",wearable:"Watch",xr:["VR","XR"],"?":["Desktop","Unknown"],"*":void 0},browserHintsMap={Chrome:"Google Chrome",Edge:"Microsoft Edge","Edge WebView2":"Microsoft Edge WebView2","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome","Huawei Browser":"HuaweiBrowser","MIUI Browser":"Miui Browser","Opera Mobi":"OperaMobile",Yandex:"YaBrowser"},defaultRegexes={browser:[[/\b(?:crmo|crios)\/([\w\.]+)/i],[VERSION,[NAME,PREFIX_MOBILE+"Chrome"]],[/webview.+edge\/([\w\.]+)/i],[VERSION,[NAME,EDGE+" WebView"]],[/edg(?:e|ios|a)?\/([\w\.]+)/i],[VERSION,[NAME,"Edge"]],[/(opera mini)\/([-\w\.]+)/i,/(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i,/(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i],[NAME,VERSION],[/opios[\/ ]+([\w\.]+)/i],[VERSION,[NAME,OPERA+" Mini"]],[/\bop(?:rg)?x\/([\w\.]+)/i],[VERSION,[NAME,OPERA+" GX"]],[/\bopr\/([\w\.]+)/i],[VERSION,[NAME,OPERA]],[/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i],[VERSION,[NAME,"Baidu"]],[/\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i],[VERSION,[NAME,"Maxthon"]],[/(kindle)\/([\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,/(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i,/(?:ms|\()(ie) ([\w\.]+)/i,/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|otter|dooble|(?:lg |qute)browser)\/([-\w\.]+)/i,/(heytap|ovi|115|surf)browser\/([\d\.]+)/i,/(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i],[NAME,VERSION],[/quark(?:pc)?\/([-\w\.]+)/i],[VERSION,[NAME,"Quark"]],[/\bddg\/([\w\.]+)/i],[VERSION,[NAME,"DuckDuckGo"]],[/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i],[VERSION,[NAME,"UCBrowser"]],[/microm.+\bqbcore\/([\w\.]+)/i,/\bqbcore\/([\w\.]+).+microm/i,/micromessenger\/([\w\.]+)/i],[VERSION,[NAME,"WeChat"]],[/konqueror\/([\w\.]+)/i],[VERSION,[NAME,"Konqueror"]],[/trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i],[VERSION,[NAME,"IE"]],[/ya(?:search)?browser\/([\w\.]+)/i],[VERSION,[NAME,"Yandex"]],[/slbrowser\/([\w\.]+)/i],[VERSION,[NAME,"Smart "+LENOVO+SUFFIX_BROWSER]],[/(avast|avg)\/([\w\.]+)/i],[[NAME,/(.+)/,"$1 Secure"+SUFFIX_BROWSER],VERSION],[/\bfocus\/([\w\.]+)/i],[VERSION,[NAME,FIREFOX+" Focus"]],[/\bopt\/([\w\.]+)/i],[VERSION,[NAME,OPERA+" Touch"]],[/coc_coc\w+\/([\w\.]+)/i],[VERSION,[NAME,"Coc Coc"]],[/dolfin\/([\w\.]+)/i],[VERSION,[NAME,"Dolphin"]],[/coast\/([\w\.]+)/i],[VERSION,[NAME,OPERA+" Coast"]],[/miuibrowser\/([\w\.]+)/i],[VERSION,[NAME,"MIUI"+SUFFIX_BROWSER]],[/fxios\/([\w\.-]+)/i],[VERSION,[NAME,PREFIX_MOBILE+FIREFOX]],[/\bqihoobrowser\/?([\w\.]*)/i],[VERSION,[NAME,"360"]],[/\b(qq)\/([\w\.]+)/i],[[NAME,/(.+)/,"$1Browser"],VERSION],[/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i],[[NAME,/(.+)/,"$1"+SUFFIX_BROWSER],VERSION],[/samsungbrowser\/([\w\.]+)/i],[VERSION,[NAME,SAMSUNG+" Internet"]],[/metasr[\/ ]?([\d\.]+)/i],[VERSION,[NAME,SOGOU+" Explorer"]],[/(sogou)mo\w+\/([\d\.]+)/i],[[NAME,SOGOU+" Mobile"],VERSION],[/(electron)\/([\w\.]+) safari/i,/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i,/m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i],[NAME,VERSION],[/(lbbrowser|rekonq)/i],[NAME],[/ome\/([\w\.]+) \w* ?(iron) saf/i,/ome\/([\w\.]+).+qihu (360)[es]e/i],[VERSION,NAME],[/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i],[[NAME,FACEBOOK],VERSION,[TYPE,INAPP]],[/(kakao(?:talk|story))[\/ ]([\w\.]+)/i,/(naver)\(.*?(\d+\.[\w\.]+).*\)/i,/(daum)apps[\/ ]([\w\.]+)/i,/safari (line)\/([\w\.]+)/i,/\b(line)\/([\w\.]+)\/iab/i,/(alipay)client\/([\w\.]+)/i,/(twitter)(?:and| f.+e\/([\w\.]+))/i,/(instagram|snapchat|klarna)[\/ ]([-\w\.]+)/i],[NAME,VERSION,[TYPE,INAPP]],[/\bgsa\/([\w\.]+) .*safari\//i],[VERSION,[NAME,"GSA"],[TYPE,INAPP]],[/musical_ly(?:.+app_?version\/|_)([\w\.]+)/i],[VERSION,[NAME,"TikTok"],[TYPE,INAPP]],[/\[(linkedin)app\]/i],[NAME,[TYPE,INAPP]],[/(chromium)[\/ ]([-\w\.]+)/i],[NAME,VERSION],[/headlesschrome(?:\/([\w\.]+)| )/i],[VERSION,[NAME,CHROME+" Headless"]],[/wv\).+chrome\/([\w\.]+).+edgw\//i],[VERSION,[NAME,EDGE+" WebView2"]],[/ wv\).+(chrome)\/([\w\.]+)/i],[[NAME,CHROME+" WebView"],VERSION],[/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i],[VERSION,[NAME,"Android"+SUFFIX_BROWSER]],[/chrome\/([\w\.]+) mobile/i],[VERSION,[NAME,PREFIX_MOBILE+"Chrome"]],[/(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i],[NAME,VERSION],[/version\/([\w\.\,]+) .*mobile(?:\/\w+ | ?)safari/i],[VERSION,[NAME,PREFIX_MOBILE+"Safari"]],[/iphone .*mobile(?:\/\w+ | ?)safari/i],[[NAME,PREFIX_MOBILE+"Safari"]],[/version\/([\w\.\,]+) .*(safari)/i],[VERSION,NAME],[/webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i],[NAME,[VERSION,"1"]],[/(webkit|khtml)\/([\w\.]+)/i],[NAME,VERSION],[/(?:mobile|tablet);.*(firefox)\/([\w\.-]+)/i],[[NAME,PREFIX_MOBILE+FIREFOX],VERSION],[/(navigator|netscape\d?)\/([-\w\.]+)/i],[[NAME,"Netscape"],VERSION],[/(wolvic|librewolf)\/([\w\.]+)/i],[NAME,VERSION],[/mobile vr; rv:([\w\.]+)\).+firefox/i],[VERSION,[NAME,FIREFOX+" Reality"]],[/ekiohf.+(flow)\/([\w\.]+)/i,/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,/(firefox)\/([\w\.]+)/i,/(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i,/(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,/\b(links) \(([\w\.]+)/i],[NAME,[VERSION,/_/g,"."]],[/(cobalt)\/([\w\.]+)/i],[NAME,[VERSION,/[^\d\.]+./,EMPTY]]],cpu:[[/\b((amd|x|x86[-_]?|wow|win)64)\b/i],[[ARCHITECTURE,"amd64"]],[/(ia32(?=;))/i,/\b((i[346]|x)86)(pc)?\b/i],[[ARCHITECTURE,"ia32"]],[/\b(aarch64|arm(v?[89]e?l?|_?64))\b/i],[[ARCHITECTURE,"arm64"]],[/\b(arm(v[67])?ht?n?[fl]p?)\b/i],[[ARCHITECTURE,"armhf"]],[/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i],[[ARCHITECTURE,"arm"]],[/((ppc|powerpc)(64)?)( mac|;|\))/i],[[ARCHITECTURE,/ower/,EMPTY,lowerize]],[/ sun4\w[;\)]/i],[[ARCHITECTURE,"sparc"]],[/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i],[[ARCHITECTURE,lowerize]]],device:[[/\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i],[MODEL,[VENDOR,SAMSUNG],[TYPE,TABLET]],[/\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,/samsung[- ]((?!sm-[lr]|browser)[-\w]+)/i,/sec-(sgh\w+)/i],[MODEL,[VENDOR,SAMSUNG],[TYPE,MOBILE]],[/(?:\/|\()(ip(?:hone|od)[\w, ]*)(?:\/|;)/i],[MODEL,[VENDOR,APPLE],[TYPE,MOBILE]],[/\((ipad);[-\w\),; ]+apple/i,/applecoremedia\/[\w\.]+ \((ipad)/i,/\b(ipad)\d\d?,\d\d?[;\]].+ios/i],[MODEL,[VENDOR,APPLE],[TYPE,TABLET]],[/(macintosh);/i],[MODEL,[VENDOR,APPLE]],[/\b(sh-?[altvz]?\d\d[a-ekm]?)/i],[MODEL,[VENDOR,SHARP],[TYPE,MOBILE]],[/\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i],[MODEL,[VENDOR,HONOR],[TYPE,TABLET]],[/honor([-\w ]+)[;\)]/i],[MODEL,[VENDOR,HONOR],[TYPE,MOBILE]],[/\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i],[MODEL,[VENDOR,HUAWEI],[TYPE,TABLET]],[/(?:huawei)([-\w ]+)[;\)]/i,/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i],[MODEL,[VENDOR,HUAWEI],[TYPE,MOBILE]],[/oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i,/\b((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i],[[MODEL,/_/g," "],[VENDOR,XIAOMI],[TYPE,TABLET]],[/\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i,/\b; (\w+) build\/hm\1/i,/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i,/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i,/oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i,/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i,/ ([\w ]+) miui\/v?\d/i],[[MODEL,/_/g," "],[VENDOR,XIAOMI],[TYPE,MOBILE]],[/droid.+; (cph2[3-6]\d[13579]|((gm|hd)19|(ac|be|in|kb)20|(d[en]|eb|le|mt)21|ne22)[0-2]\d|p[g-k]\w[1m]10)\b/i,/(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i],[MODEL,[VENDOR,ONEPLUS],[TYPE,MOBILE]],[/; (\w+) bui.+ oppo/i,/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i],[MODEL,[VENDOR,OPPO],[TYPE,MOBILE]],[/\b(opd2(\d{3}a?))(?: bui|\))/i],[MODEL,[VENDOR,strMapper,{OnePlus:["203","304","403","404","413","415"],"*":OPPO}],[TYPE,TABLET]],[/(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i],[MODEL,[VENDOR,"BLU"],[TYPE,MOBILE]],[/; vivo (\w+)(?: bui|\))/i,/\b(v[12]\d{3}\w?[at])(?: bui|;)/i],[MODEL,[VENDOR,"Vivo"],[TYPE,MOBILE]],[/\b(rmx[1-3]\d{3})(?: bui|;|\))/i],[MODEL,[VENDOR,"Realme"],[TYPE,MOBILE]],[/(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i,/lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i],[MODEL,[VENDOR,LENOVO],[TYPE,TABLET]],[/lenovo[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i],[MODEL,[VENDOR,LENOVO],[TYPE,MOBILE]],[/\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,/\bmot(?:orola)?[- ]([\w\s]+)(\)| bui)/i,/((?:moto(?! 360)[-\w\(\) ]+|xt\d{3,4}[cgkosw\+]?[-\d]*|nexus 6)(?= bui|\)))/i],[MODEL,[VENDOR,MOTOROLA],[TYPE,MOBILE]],[/\b(mz60\d|xoom[2 ]{0,2}) build\//i],[MODEL,[VENDOR,MOTOROLA],[TYPE,TABLET]],[/((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i],[MODEL,[VENDOR,LG],[TYPE,TABLET]],[/(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,/\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch|webos))(\w+)/i,/\blg-?([\d\w]+) bui/i],[MODEL,[VENDOR,LG],[TYPE,MOBILE]],[/(nokia) (t[12][01])/i],[VENDOR,MODEL,[TYPE,TABLET]],[/(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i,/nokia[-_ ]?(([-\w\. ]*))/i],[[MODEL,/_/g," "],[TYPE,MOBILE],[VENDOR,"Nokia"]],[/(pixel (c|tablet))\b/i],[MODEL,[VENDOR,GOOGLE],[TYPE,TABLET]],[/droid.+;(?: google)? (g(01[13]a|020[aem]|025[jn]|1b60|1f8f|2ybb|4s1m|576d|5nz6|8hhn|8vou|a02099|c15s|d1yq|e2ae|ec77|gh2x|kv4x|p4bc|pj41|r83y|tt9q|ur25|wvk6)|pixel[\d ]*a?( pro)?( xl)?( fold)?( \(5g\))?)( bui|\))/i],[MODEL,[VENDOR,GOOGLE],[TYPE,MOBILE]],[/(google) (pixelbook( go)?)/i],[VENDOR,MODEL],[/droid.+; (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-\w\w\d\d)(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i],[MODEL,[VENDOR,SONY],[TYPE,MOBILE]],[/sony tablet [ps]/i,/\b(?:sony)?sgp\w+(?: bui|\))/i],[[MODEL,"Xperia Tablet"],[VENDOR,SONY],[TYPE,TABLET]],[/(alexa)webm/i,/(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i,/(kf[a-z]+)( bui|\)).+silk\//i],[MODEL,[VENDOR,AMAZON],[TYPE,TABLET]],[/((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i],[[MODEL,/(.+)/g,"Fire Phone $1"],[VENDOR,AMAZON],[TYPE,MOBILE]],[/(playbook);[-\w\),; ]+(rim)/i],[MODEL,VENDOR,[TYPE,TABLET]],[/\b((?:bb[a-f]|st[hv])100-\d)/i,/\(bb10; (\w+)/i],[MODEL,[VENDOR,BLACKBERRY],[TYPE,MOBILE]],[/(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i],[MODEL,[VENDOR,ASUS],[TYPE,TABLET]],[/ (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i],[MODEL,[VENDOR,ASUS],[TYPE,MOBILE]],[/(nexus 9)/i],[MODEL,[VENDOR,"HTC"],[TYPE,TABLET]],[/(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i,/(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,/(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i],[VENDOR,[MODEL,/_/g," "],[TYPE,MOBILE]],[/tcl (xess p17aa)/i,/droid [\w\.]+; ((?:8[14]9[16]|9(?:0(?:48|60|8[01])|1(?:3[27]|66)|2(?:6[69]|9[56])|466))[gqswx])(_\w(\w|\w\w))?(\)| bui)/i],[MODEL,[VENDOR,"TCL"],[TYPE,TABLET]],[/droid [\w\.]+; (418(?:7d|8v)|5087z|5102l|61(?:02[dh]|25[adfh]|27[ai]|56[dh]|59k|65[ah])|a509dl|t(?:43(?:0w|1[adepqu])|50(?:6d|7[adju])|6(?:09dl|10k|12b|71[efho]|76[hjk])|7(?:66[ahju]|67[hw]|7[045][bh]|71[hk]|73o|76[ho]|79w|81[hks]?|82h|90[bhsy]|99b)|810[hs]))(_\w(\w|\w\w))?(\)| bui)/i],[MODEL,[VENDOR,"TCL"],[TYPE,MOBILE]],[/(itel) ((\w+))/i],[[VENDOR,lowerize],MODEL,[TYPE,strMapper,{tablet:["p10001l","w7001"],"*":"mobile"}]],[/droid.+; ([ab][1-7]-?[0178a]\d\d?)/i],[MODEL,[VENDOR,"Acer"],[TYPE,TABLET]],[/droid.+; (m[1-5] note) bui/i,/\bmz-([-\w]{2,})/i],[MODEL,[VENDOR,"Meizu"],[TYPE,MOBILE]],[/; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i],[MODEL,[VENDOR,"Ulefone"],[TYPE,MOBILE]],[/; (energy ?\w+)(?: bui|\))/i,/; energizer ([\w ]+)(?: bui|\))/i],[MODEL,[VENDOR,"Energizer"],[TYPE,MOBILE]],[/; cat (b35);/i,/; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i],[MODEL,[VENDOR,"Cat"],[TYPE,MOBILE]],[/((?:new )?andromax[\w- ]+)(?: bui|\))/i],[MODEL,[VENDOR,"Smartfren"],[TYPE,MOBILE]],[/droid.+; (a(in)?(0(15|59|6[35])|142)p?)/i],[MODEL,[VENDOR,"Nothing"],[TYPE,MOBILE]],[/; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i,/archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i],[MODEL,[VENDOR,"Archos"],[TYPE,TABLET]],[/archos ([\w ]+)( b|\))/i,/; (ac[3-6]\d\w{2,8})( b|\))/i],[MODEL,[VENDOR,"Archos"],[TYPE,MOBILE]],[/; (n159v)/i],[MODEL,[VENDOR,"HMD"],[TYPE,MOBILE]],[/(imo) (tab \w+)/i,/(infinix|tecno) (x1101b?|p904|dp(7c|8d|10a)( pro)?|p70[1-3]a?|p904|t1101)/i],[VENDOR,MODEL,[TYPE,TABLET]],[/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|tecno|micromax|advan)[-_ ]?([-\w]*)/i,/; (blu|hmd|imo|infinix|lava|oneplus|tcl)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i,/(hp) ([\w ]+\w)/i,/(microsoft); (lumia[\w ]+)/i,/(oppo) ?([\w ]+) bui/i],[VENDOR,MODEL,[TYPE,MOBILE]],[/(kobo)\s(ereader|touch)/i,/(hp).+(touchpad(?!.+tablet)|tablet)/i,/(kindle)\/([\w\.]+)/i],[VENDOR,MODEL,[TYPE,TABLET]],[/(surface duo)/i],[MODEL,[VENDOR,MICROSOFT],[TYPE,TABLET]],[/droid [\d\.]+; (fp\du?)(?: b|\))/i],[MODEL,[VENDOR,"Fairphone"],[TYPE,MOBILE]],[/((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i],[MODEL,[VENDOR,NVIDIA],[TYPE,TABLET]],[/(sprint) (\w+)/i],[VENDOR,MODEL,[TYPE,MOBILE]],[/(kin\.[onetw]{3})/i],[[MODEL,/\./g," "],[VENDOR,MICROSOFT],[TYPE,MOBILE]],[/droid.+; ([c6]+|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i],[MODEL,[VENDOR,ZEBRA],[TYPE,TABLET]],[/droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i],[MODEL,[VENDOR,ZEBRA],[TYPE,MOBILE]],[/smart-tv.+(samsung)/i],[VENDOR,[TYPE,SMARTTV]],[/hbbtv.+maple;(\d+)/i],[[MODEL,/^/,"SmartTV"],[VENDOR,SAMSUNG],[TYPE,SMARTTV]],[/(vizio)(?: |.+model\/)(\w+-\w+)/i,/tcast.+(lg)e?. ([-\w]+)/i],[VENDOR,MODEL,[TYPE,SMARTTV]],[/(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i],[[VENDOR,LG],[TYPE,SMARTTV]],[/(apple) ?tv/i],[VENDOR,[MODEL,APPLE+" TV"],[TYPE,SMARTTV]],[/crkey.*devicetype\/chromecast/i],[[MODEL,CHROMECAST+" Third Generation"],[VENDOR,GOOGLE],[TYPE,SMARTTV]],[/crkey.*devicetype\/([^/]*)/i],[[MODEL,/^/,"Chromecast "],[VENDOR,GOOGLE],[TYPE,SMARTTV]],[/fuchsia.*crkey/i],[[MODEL,CHROMECAST+" Nest Hub"],[VENDOR,GOOGLE],[TYPE,SMARTTV]],[/crkey/i],[[MODEL,CHROMECAST],[VENDOR,GOOGLE],[TYPE,SMARTTV]],[/(portaltv)/i],[MODEL,[VENDOR,FACEBOOK],[TYPE,SMARTTV]],[/droid.+aft(\w+)( bui|\))/i],[MODEL,[VENDOR,AMAZON],[TYPE,SMARTTV]],[/(shield \w+ tv)/i],[MODEL,[VENDOR,NVIDIA],[TYPE,SMARTTV]],[/\(dtv[\);].+(aquos)/i,/(aquos-tv[\w ]+)\)/i],[MODEL,[VENDOR,SHARP],[TYPE,SMARTTV]],[/(bravia[\w ]+)( bui|\))/i],[MODEL,[VENDOR,SONY],[TYPE,SMARTTV]],[/(mi(tv|box)-?\w+) bui/i],[MODEL,[VENDOR,XIAOMI],[TYPE,SMARTTV]],[/Hbbtv.*(technisat) (.*);/i],[VENDOR,MODEL,[TYPE,SMARTTV]],[/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i,/hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i],[[VENDOR,/.+\/(\w+)/,"$1",strMapper,{LG:"lge"}],[MODEL,trim],[TYPE,SMARTTV]],[/droid.+; ([\w- ]+) (?:android tv|smart[- ]?tv)/i],[MODEL,[TYPE,SMARTTV]],[/\b(android tv|smart[- ]?tv|opera tv|tv; rv:|large screen[\w ]+safari)\b/i],[[TYPE,SMARTTV]],[/(playstation \w+)/i],[MODEL,[VENDOR,SONY],[TYPE,CONSOLE]],[/\b(xbox(?: one)?(?!; xbox))[\); ]/i],[MODEL,[VENDOR,MICROSOFT],[TYPE,CONSOLE]],[/(ouya)/i,/(nintendo) (\w+)/i,/(retroid) (pocket ([^\)]+))/i],[VENDOR,MODEL,[TYPE,CONSOLE]],[/droid.+; (shield)( bui|\))/i],[MODEL,[VENDOR,NVIDIA],[TYPE,CONSOLE]],[/\b(sm-[lr]\d\d[0156][fnuw]?s?|gear live)\b/i],[MODEL,[VENDOR,SAMSUNG],[TYPE,WEARABLE]],[/((pebble))app/i,/(asus|google|lg|oppo) ((pixel |zen)?watch[\w ]*)( bui|\))/i],[VENDOR,MODEL,[TYPE,WEARABLE]],[/(ow(?:19|20)?we?[1-3]{1,3})/i],[MODEL,[VENDOR,OPPO],[TYPE,WEARABLE]],[/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i],[MODEL,[VENDOR,APPLE],[TYPE,WEARABLE]],[/(opwwe\d{3})/i],[MODEL,[VENDOR,ONEPLUS],[TYPE,WEARABLE]],[/(moto 360)/i],[MODEL,[VENDOR,MOTOROLA],[TYPE,WEARABLE]],[/(smartwatch 3)/i],[MODEL,[VENDOR,SONY],[TYPE,WEARABLE]],[/(g watch r)/i],[MODEL,[VENDOR,LG],[TYPE,WEARABLE]],[/droid.+; (wt63?0{2,3})\)/i],[MODEL,[VENDOR,ZEBRA],[TYPE,WEARABLE]],[/droid.+; (glass) \d/i],[MODEL,[VENDOR,GOOGLE],[TYPE,XR]],[/(pico) (4|neo3(?: link|pro)?)/i],[VENDOR,MODEL,[TYPE,XR]],[/(quest( \d| pro)?s?).+vr/i],[MODEL,[VENDOR,FACEBOOK],[TYPE,XR]],[/mobile vr; rv.+firefox/i],[[TYPE,XR]],[/(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i],[VENDOR,[TYPE,EMBEDDED]],[/(aeobc)\b/i],[MODEL,[VENDOR,AMAZON],[TYPE,EMBEDDED]],[/(homepod).+mac os/i],[MODEL,[VENDOR,APPLE],[TYPE,EMBEDDED]],[/windows iot/i],[[TYPE,EMBEDDED]],[/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+?(mobile|vr|\d) safari/i],[MODEL,[TYPE,strMapper,{mobile:"Mobile",xr:"VR","*":TABLET}]],[/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i],[[TYPE,TABLET]],[/(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i],[[TYPE,MOBILE]],[/droid .+?; ([\w\. -]+)( bui|\))/i],[MODEL,[VENDOR,"Generic"]]],engine:[[/windows.+ edge\/([\w\.]+)/i],[VERSION,[NAME,EDGE+"HTML"]],[/(arkweb)\/([\w\.]+)/i],[NAME,VERSION],[/webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i],[VERSION,[NAME,"Blink"]],[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i,/ekioh(flow)\/([\w\.]+)/i,/(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i,/(icab)[\/ ]([23]\.[\d\.]+)/i,/\b(libweb)/i],[NAME,VERSION],[/ladybird\//i],[[NAME,"LibWeb"]],[/rv\:([\w\.]{1,9})\b.+(gecko)/i],[VERSION,NAME]],os:[[/(windows nt) (6\.[23]); arm/i],[[NAME,/N/,"R"],[VERSION,strMapper,windowsVersionMap]],[/(windows (?:phone|mobile|iot))(?: os)?[\/ ]?([\d\.]*( se)?)/i,/(windows)[\/ ](1[01]|2000|3\.1|7|8(\.1)?|9[58]|me|server 20\d\d( r2)?|vista|xp)/i],[NAME,VERSION],[/windows nt ?([\d\.\)]*)(?!.+xbox)/i,/\bwin(?=3| ?9|n)(?:nt| 9x )?([\d\.;]*)/i],[[VERSION,/(;|\))/g,"",strMapper,windowsVersionMap],[NAME,WINDOWS]],[/(windows ce)\/?([\d\.]*)/i],[NAME,VERSION],[/[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i,/(?:ios;fbsv\/|iphone.+ios[\/ ])([\d\.]+)/i,/cfnetwork\/.+darwin/i],[[VERSION,/_/g,"."],[NAME,"iOS"]],[/(mac os x) ?([\w\. ]*)/i,/(macintosh|mac_powerpc\b)(?!.+(haiku|morphos))/i],[[NAME,"macOS"],[VERSION,/_/g,"."]],[/android ([\d\.]+).*crkey/i],[VERSION,[NAME,CHROMECAST+" Android"]],[/fuchsia.*crkey\/([\d\.]+)/i],[VERSION,[NAME,CHROMECAST+" Fuchsia"]],[/crkey\/([\d\.]+).*devicetype\/smartspeaker/i],[VERSION,[NAME,CHROMECAST+" SmartSpeaker"]],[/linux.*crkey\/([\d\.]+)/i],[VERSION,[NAME,CHROMECAST+" Linux"]],[/crkey\/([\d\.]+)/i],[VERSION,[NAME,CHROMECAST]],[/droid ([\w\.]+)\b.+(android[- ]x86)/i],[VERSION,NAME],[/(ubuntu) ([\w\.]+) like android/i],[[NAME,/(.+)/,"$1 Touch"],VERSION],[/(harmonyos)[\/ ]?([\d\.]*)/i,/(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen)\w*[-\/\.; ]?([\d\.]*)/i],[NAME,VERSION],[/\(bb(10);/i],[VERSION,[NAME,BLACKBERRY]],[/(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\/ ]?([\w\.]*)/i],[VERSION,[NAME,"Symbian"]],[/mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i],[VERSION,[NAME,FIREFOX+" OS"]],[/\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i,/webos(?:[ \/]?|\.tv-20(?=2[2-9]))(\d[\d\.]*)/i],[VERSION,[NAME,"webOS"]],[/web0s;.+?(?:chr[o0]me|safari)\/(\d+)/i],[[VERSION,strMapper,{25:"120",24:"108",23:"94",22:"87",6:"79",5:"68",4:"53",3:"38",2:"538",1:"537","*":"TV"}],[NAME,"webOS"]],[/watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i],[VERSION,[NAME,"watchOS"]],[/(cros) [\w]+(?:\)| ([\w\.]+)\b)/i],[[NAME,"Chrome OS"],VERSION],[/panasonic;(viera)/i,/(netrange)mmh/i,/(nettv)\/(\d+\.[\w\.]+)/i,/(nintendo|playstation) (\w+)/i,/(xbox); +xbox ([^\);]+)/i,/(pico) .+os([\w\.]+)/i,/\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i,/linux.+(mint)[\/\(\) ]?([\w\.]*)/i,/(mageia|vectorlinux|fuchsia|arcaos|arch(?= ?linux))[;l ]([\d\.]*)/i,/([kxln]?ubuntu|debian|suse|opensuse|gentoo|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire|knoppix)(?: gnu[\/ ]linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,/((?:open)?solaris)[-\/ ]?([\w\.]*)/i,/\b(aix)[; ]([1-9\.]{0,4})/i,/(hurd|linux|morphos)(?: (?:arm|x86|ppc)\w*| ?)([\w\.]*)/i,/(gnu) ?([\w\.]*)/i,/\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i,/(haiku) ?(r\d)?/i],[NAME,VERSION],[/(sunos) ?([\d\.]*)/i],[[NAME,"Solaris"],VERSION],[/\b(beos|os\/2|amigaos|openvms|hp-ux|serenityos)/i,/(unix) ?([\w\.]*)/i],[NAME,VERSION]]},defaultProps=function(){var props={init:{},isIgnore:{},isIgnoreRgx:{},toString:{}};return setProps.call(props.init,[[UA_BROWSER,[NAME,VERSION,MAJOR,TYPE]],[UA_CPU,[ARCHITECTURE]],[UA_DEVICE,[TYPE,MODEL,VENDOR]],[UA_ENGINE,[NAME,VERSION]],[UA_OS,[NAME,VERSION]]]),setProps.call(props.isIgnore,[[UA_BROWSER,[VERSION,MAJOR]],[UA_ENGINE,[VERSION]],[UA_OS,[VERSION]]]),setProps.call(props.isIgnoreRgx,[[UA_BROWSER,/ ?browser$/i],[UA_OS,/ ?os$/i]]),setProps.call(props.toString,[[UA_BROWSER,[NAME,VERSION]],[UA_CPU,[ARCHITECTURE]],[UA_DEVICE,[VENDOR,MODEL]],[UA_ENGINE,[NAME,VERSION]],[UA_OS,[NAME,VERSION]]]),props}(),createIData=function(item,itemType){var init_props=defaultProps.init[itemType],is_ignoreProps=defaultProps.isIgnore[itemType]||0,is_ignoreRgx=defaultProps.isIgnoreRgx[itemType]||0,toString_props=defaultProps.toString[itemType]||0;function IData(){setProps.call(this,init_props)}return IData.prototype.getItem=function(){return item},IData.prototype.withClientHints=function(){return NAVIGATOR_UADATA?NAVIGATOR_UADATA.getHighEntropyValues(CH_ALL_VALUES).then(function(res){return item.setCH(new UACHData(res,!1)).parseCH().get()}):item.parseCH().get()},IData.prototype.withFeatureCheck=function(){return item.detectFeature().get()},itemType!=UA_RESULT&&(IData.prototype.is=function(strToCheck){var is=!1;for(var i2 in this)if(this.hasOwnProperty(i2)&&!has(is_ignoreProps,i2)&&lowerize(is_ignoreRgx?strip(is_ignoreRgx,this[i2]):this[i2])==lowerize(is_ignoreRgx?strip(is_ignoreRgx,strToCheck):strToCheck)){if(is=!0,strToCheck!=UNDEF_TYPE)break}else if(strToCheck==UNDEF_TYPE&&is){is=!is;break}return is},IData.prototype.toString=function(){var str=EMPTY;for(var i2 in toString_props)typeof this[toString_props[i2]]!==UNDEF_TYPE&&(str+=(str?" ":EMPTY)+this[toString_props[i2]]);return str||UNDEF_TYPE}),NAVIGATOR_UADATA||(IData.prototype.then=function(cb){var that=this,IDataResolve=function(){for(var prop in that)that.hasOwnProperty(prop)&&(this[prop]=that[prop])};IDataResolve.prototype={is:IData.prototype.is,toString:IData.prototype.toString};var resolveData=new IDataResolve;return cb(resolveData),resolveData}),new IData};function UACHData(uach,isHttpUACH){if(uach=uach||{},setProps.call(this,CH_ALL_VALUES),isHttpUACH)setProps.call(this,[[BRANDS,itemListToArray(uach[CH_HEADER])],[FULLVERLIST,itemListToArray(uach[CH_HEADER_FULL_VER_LIST])],[MOBILE,/\?1/.test(uach[CH_HEADER_MOBILE])],[MODEL,stripQuotes(uach[CH_HEADER_MODEL])],[PLATFORM,stripQuotes(uach[CH_HEADER_PLATFORM])],[PLATFORMVER,stripQuotes(uach[CH_HEADER_PLATFORM_VER])],[ARCHITECTURE,stripQuotes(uach[CH_HEADER_ARCH])],[FORMFACTORS,itemListToArray(uach[CH_HEADER_FORM_FACTORS])],[BITNESS,stripQuotes(uach[CH_HEADER_BITNESS])]]);else for(var prop in uach)this.hasOwnProperty(prop)&&typeof uach[prop]!==UNDEF_TYPE&&(this[prop]=uach[prop])}function UAItem(itemType,ua,rgxMap,uaCH){return this.get=function(prop){return prop?this.data.hasOwnProperty(prop)?this.data[prop]:void 0:this.data},this.set=function(prop,val){return this.data[prop]=val,this},this.setCH=function(ch){return this.uaCH=ch,this},this.detectFeature=function(){if(NAVIGATOR&&NAVIGATOR.userAgent==this.ua)switch(this.itemType){case UA_BROWSER:NAVIGATOR.brave&&typeof NAVIGATOR.brave.isBrave==FUNC_TYPE&&this.set(NAME,"Brave");break;case UA_DEVICE:!this.get(TYPE)&&NAVIGATOR_UADATA&&NAVIGATOR_UADATA[MOBILE]&&this.set(TYPE,MOBILE),this.get(MODEL)=="Macintosh"&&NAVIGATOR&&typeof NAVIGATOR.standalone!==UNDEF_TYPE&&NAVIGATOR.maxTouchPoints&&NAVIGATOR.maxTouchPoints>2&&this.set(MODEL,"iPad").set(TYPE,TABLET);break;case UA_OS:!this.get(NAME)&&NAVIGATOR_UADATA&&NAVIGATOR_UADATA[PLATFORM]&&this.set(NAME,NAVIGATOR_UADATA[PLATFORM]);break;case UA_RESULT:var data=this.data,detect=function(itemType2){return data[itemType2].getItem().detectFeature().get()};this.set(UA_BROWSER,detect(UA_BROWSER)).set(UA_CPU,detect(UA_CPU)).set(UA_DEVICE,detect(UA_DEVICE)).set(UA_ENGINE,detect(UA_ENGINE)).set(UA_OS,detect(UA_OS))}return this},this.parseUA=function(){return this.itemType!=UA_RESULT&&rgxMapper.call(this.data,this.ua,this.rgxMap),this.itemType==UA_BROWSER&&this.set(MAJOR,majorize(this.get(VERSION))),this},this.parseCH=function(){var uaCH2=this.uaCH,rgxMap2=this.rgxMap;switch(this.itemType){case UA_BROWSER:case UA_ENGINE:var brands=uaCH2[FULLVERLIST]||uaCH2[BRANDS],prevName;if(brands)for(var i2 in brands){var brandName=brands[i2].brand||brands[i2],brandVersion=brands[i2].version;this.itemType==UA_BROWSER&&!/not.a.brand/i.test(brandName)&&(!prevName||/Chrom/.test(prevName)&&brandName!=CHROMIUM||prevName==EDGE&&/WebView2/.test(brandName))&&(brandName=strMapper(brandName,browserHintsMap),prevName=this.get(NAME),prevName&&!/Chrom/.test(prevName)&&/Chrom/.test(brandName)||this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion)),prevName=brandName),this.itemType==UA_ENGINE&&brandName==CHROMIUM&&this.set(VERSION,brandVersion)}break;case UA_CPU:var archName=uaCH2[ARCHITECTURE];archName&&(archName&&uaCH2[BITNESS]=="64"&&(archName+="64"),rgxMapper.call(this.data,archName+";",rgxMap2));break;case UA_DEVICE:if(uaCH2[MOBILE]&&this.set(TYPE,MOBILE),uaCH2[MODEL]&&(this.set(MODEL,uaCH2[MODEL]),!this.get(TYPE)||!this.get(VENDOR))){var reParse={};rgxMapper.call(reParse,"droid 9; "+uaCH2[MODEL]+")",rgxMap2),!this.get(TYPE)&&reParse.type&&this.set(TYPE,reParse.type),!this.get(VENDOR)&&reParse.vendor&&this.set(VENDOR,reParse.vendor)}if(uaCH2[FORMFACTORS]){var ff;if(typeof uaCH2[FORMFACTORS]!="string")for(var idx=0;!ff&&idx<uaCH2[FORMFACTORS].length;)ff=strMapper(uaCH2[FORMFACTORS][idx++],formFactorsMap);else ff=strMapper(uaCH2[FORMFACTORS],formFactorsMap);this.set(TYPE,ff)}break;case UA_OS:var osName=uaCH2[PLATFORM];if(osName){var osVersion=uaCH2[PLATFORMVER];osName==WINDOWS&&(osVersion=parseInt(majorize(osVersion),10)>=13?"11":"10"),this.set(NAME,osName).set(VERSION,osVersion)}this.get(NAME)==WINDOWS&&uaCH2[MODEL]=="Xbox"&&this.set(NAME,"Xbox").set(VERSION,void 0);break;case UA_RESULT:var data=this.data,parse=function(itemType2){return data[itemType2].getItem().setCH(uaCH2).parseCH().get()};this.set(UA_BROWSER,parse(UA_BROWSER)).set(UA_CPU,parse(UA_CPU)).set(UA_DEVICE,parse(UA_DEVICE)).set(UA_ENGINE,parse(UA_ENGINE)).set(UA_OS,parse(UA_OS))}return this},setProps.call(this,[["itemType",itemType],["ua",ua],["uaCH",uaCH],["rgxMap",rgxMap],["data",createIData(this,itemType)]]),this}function UAParser(ua,extensions,headers){if(typeof ua===OBJ_TYPE?(isExtensions(ua,!0)?(typeof extensions===OBJ_TYPE&&(headers=extensions),extensions=ua):(headers=ua,extensions=void 0),ua=void 0):typeof ua===STR_TYPE&&!isExtensions(extensions,!0)&&(headers=extensions,extensions=void 0),headers&&typeof headers.append===FUNC_TYPE){var kv={};headers.forEach(function(v,k){kv[k]=v}),headers=kv}if(!(this instanceof UAParser))return new UAParser(ua,extensions,headers).getResult();var userAgent=typeof ua===STR_TYPE?ua:headers&&headers[USER_AGENT]?headers[USER_AGENT]:NAVIGATOR&&NAVIGATOR.userAgent?NAVIGATOR.userAgent:EMPTY,httpUACH=new UACHData(headers,!0),regexMap=extensions?extend(defaultRegexes,extensions):defaultRegexes,createItemFunc=function(itemType){return itemType==UA_RESULT?function(){return new UAItem(itemType,userAgent,regexMap,httpUACH).set("ua",userAgent).set(UA_BROWSER,this.getBrowser()).set(UA_CPU,this.getCPU()).set(UA_DEVICE,this.getDevice()).set(UA_ENGINE,this.getEngine()).set(UA_OS,this.getOS()).get()}:function(){return new UAItem(itemType,userAgent,regexMap[itemType],httpUACH).parseUA().get()}};return setProps.call(this,[["getBrowser",createItemFunc(UA_BROWSER)],["getCPU",createItemFunc(UA_CPU)],["getDevice",createItemFunc(UA_DEVICE)],["getEngine",createItemFunc(UA_ENGINE)],["getOS",createItemFunc(UA_OS)],["getResult",createItemFunc(UA_RESULT)],["getUA",function(){return userAgent}],["setUA",function(ua2){return isString(ua2)&&(userAgent=ua2.length>UA_MAX_LENGTH?trim(ua2,UA_MAX_LENGTH):ua2),this}]]).setUA(userAgent),this}UAParser.VERSION=LIBVERSION,UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR,TYPE]),UAParser.CPU=enumerize([ARCHITECTURE]),UAParser.DEVICE=enumerize([MODEL,VENDOR,TYPE,CONSOLE,MOBILE,SMARTTV,TABLET,WEARABLE,EMBEDDED]),UAParser.ENGINE=UAParser.OS=enumerize([NAME,VERSION]);class Recorder{constructor(window2,publicToken,userSettings={}){this.window=window2,this.publicToken=publicToken;const defaultSettings={maskingLevel:"all",consoleRecording:{enabled:!1},networkRecording:{enabled:!1,maxRequestBodySize:10*1024,maxResponseBodySize:50*1024,excludeDomains:[],captureHeaders:!0,captureRequestBodies:!0,captureResponseBodies:!0,excludeHeaders:[]}};this.recorderSettings={...defaultSettings,...userSettings,consoleRecording:{...defaultSettings.consoleRecording,...userSettings.consoleRecording||{}},networkRecording:{...defaultSettings.networkRecording,...userSettings.networkRecording||{}}},this.sessionRecorder=new SessionRecorder(this.recorderSettings),this.eventRecorder=new EventRecorder(window2,this.recorderSettings),this.errorRecorder=new ErrorRecorder(window2,this.recorderSettings.consoleRecording),this.networkRecorder=new NetworkRecorder(window2,this.recorderSettings.networkRecording),post("public/captured-sessions",{publicToken},{withCredentials:!1}).then(response=>{const id=response.data;this.capturedSessionId=id,this.sessionRecorder.setCapturedSessionId(id),this.eventRecorder.setCapturedSessionId(id),this.errorRecorder.setCapturedSessionId(id),this.networkRecorder.setCapturedSessionId(id),this.schedulePing();const capturedUserMetadata=this.collectCapturedUserMetadata();post(`public/captured-sessions/${this.capturedSessionId}/captured-session/metadata`,capturedUserMetadata,{withCredentials:!1})}).catch(error=>{console.error(error),this.sessionRecorder.stop(),this.eventRecorder.stop(),this.errorRecorder.stop(),this.networkRecorder.stop()})}sessionRecorder;eventRecorder;errorRecorder;networkRecorder;recorderSettings;capturedSessionId=null;pingIntervalMs=2e4;pingTimeout=null;schedulePing(){this.pingTimeout&&clearTimeout(this.pingTimeout),this.pingTimeout=setTimeout(this.ping,this.pingIntervalMs)}ping=async()=>{await put(`public/captured-sessions/${this.capturedSessionId}/ping`,{},{withCredentials:!1}),this.schedulePing()};start(){this.sessionRecorder.start(),this.eventRecorder.start(),this.errorRecorder.start(),this.networkRecorder.start()}stop(){this.sessionRecorder.stop(),this.eventRecorder.stop(),this.errorRecorder.stop(),this.networkRecorder.stop()}collectCapturedUserMetadata=()=>{const ua=new UAParser,browserName=ua.getBrowser().name,browserVersion=ua.getBrowser().version,osName=ua.getOS().name,osVersion=ua.getOS().version,deviceType=ua.getDevice().type??"desktop",browserLanguage=navigator.language,browserTimeZone=Intl.DateTimeFormat().resolvedOptions().timeZone,referringUrl=document.referrer||void 0;let referringDomain;try{referringDomain=referringUrl?new URL(referringUrl).hostname:void 0}catch{}const viewportWidth=window.innerWidth||document.documentElement.clientWidth,viewportHeight=window.innerHeight||document.documentElement.clientHeight,url=new URL(window.location.href),host=window.location.hostname,utmSource=url.searchParams.get("utm_source")||url.searchParams.get("source")||url.searchParams.get("ref")||void 0,utmMedium=url.searchParams.get("utm_medium")||url.searchParams.get("medium")||void 0,utmCampaign=url.searchParams.get("utm_campaign")||url.searchParams.get("campaign")||void 0,utmContent=url.searchParams.get("utm_content")||url.searchParams.get("content")||void 0,utmTerm=url.searchParams.get("utm_term")||url.searchParams.get("term")||void 0;return{browserName,browserVersion,osName,osVersion,deviceType,browserLanguage,browserTimeZone,referringUrl,referringDomain,viewportWidth,viewportHeight,host,utmSource,utmMedium,utmCampaign,utmContent,utmTerm}}}return exports.NetworkRecorder=NetworkRecorder,exports.Recorder=Recorder,Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),exports}({});
11
+ `).forEach(line=>{const parts=line.split(": ");parts.length===2&&(responseHeaders[parts[0]]=parts[1])})}if(self2.networkSettings.captureResponseBodies)try{responseBody=self2.truncateResponseContent(xhr.responseText,self2.networkSettings.maxResponseBodySize)}catch{responseBody="[Unable to read response]"}const completedRequest={...networkRequest,responseStatus:xhr.status,responseHeaders:Object.keys(responseHeaders).length>0?self2.filterHeaders(responseHeaders):void 0,responseBody,duration,error:xhr.status===0?"Network error":void 0};self2.addCompletedRequest(requestId,completedRequest)}originalOnReadyStateChange&&originalOnReadyStateChange.call(this,new Event("readystatechange"))}}return self2.originalXHRSend.call(this,body??null)}};shouldCaptureRequest(url){if(!this.isRunning||!this.networkSettings.enabled)return!1;try{const urlObj=new URL(url,this.window.location.href);return!(urlObj.pathname.includes("/public/captured-sessions")||this.networkSettings.excludeDomains.some(domain=>urlObj.hostname.includes(domain)))}catch{return!1}}sanitizeUrl(url){try{const urlObj=new URL(url,this.window.location.href);for(const key of urlObj.searchParams.keys())this.queryParamsAllowed.has(key.toLowerCase())||urlObj.searchParams.set(key,"$redacted");return urlObj.toString()}catch(e){return logger.error("Failed to sanitize URL",e),url}}filterHeaders(headers){const filtered={},defaultSensitiveHeaders=new Set(["authorization","cookie","x-api-key","x-auth-token","x-csrf-token","x-session-token","set-cookie"]),excludedHeaders=new Set([...defaultSensitiveHeaders,...this.networkSettings.excludeHeaders.map(h=>h.toLowerCase())]);for(const[key,value]of Object.entries(headers))excludedHeaders.has(key.toLowerCase())||(filtered[key]=value);return filtered}truncateRequestContent(content,maxSize){if(!content)return content;let processedContent=content;if(this.networkSettings.requestBodyMaskingFunction)try{processedContent=this.networkSettings.requestBodyMaskingFunction(content)}catch{logger.error("Failed to apply request masking function")}return processedContent.length>maxSize?processedContent.substring(0,maxSize)+`... [truncated from ${processedContent.length} chars]`:processedContent}truncateResponseContent(content,maxSize){if(!content)return content;let processedContent=content;if(this.networkSettings.responseBodyMaskingFunction)try{processedContent=this.networkSettings.responseBodyMaskingFunction(content)}catch{logger.error("Failed to apply response masking function")}return processedContent.length>maxSize?processedContent.substring(0,maxSize)+`... [truncated from ${processedContent.length} chars]`:processedContent}generateRequestId(){return`req_${crypto.randomUUID()}`}addCompletedRequest(requestId,request){this.pendingRequests.delete(requestId),this.isErrorRequest(request)&&this.requestsBuffer.push(request)}isErrorRequest(request){return!!(request.error||request.responseStatus&&request.responseStatus>=400)}}var LIBVERSION="2.0.4",UA_MAX_LENGTH=500,USER_AGENT="user-agent",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",UA_BROWSER="browser",UA_CPU="cpu",UA_DEVICE="device",UA_ENGINE="engine",UA_OS="os",UA_RESULT="result",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",MAJOR="major",MODEL="model",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",XR="xr",EMBEDDED="embedded",INAPP="inapp",BRANDS="brands",FORMFACTORS="formFactors",FULLVERLIST="fullVersionList",PLATFORM="platform",PLATFORMVER="platformVersion",BITNESS="bitness",CH_HEADER="sec-ch-ua",CH_HEADER_FULL_VER_LIST=CH_HEADER+"-full-version-list",CH_HEADER_ARCH=CH_HEADER+"-arch",CH_HEADER_BITNESS=CH_HEADER+"-"+BITNESS,CH_HEADER_FORM_FACTORS=CH_HEADER+"-form-factors",CH_HEADER_MOBILE=CH_HEADER+"-"+MOBILE,CH_HEADER_MODEL=CH_HEADER+"-"+MODEL,CH_HEADER_PLATFORM=CH_HEADER+"-"+PLATFORM,CH_HEADER_PLATFORM_VER=CH_HEADER_PLATFORM+"-version",CH_ALL_VALUES=[BRANDS,FULLVERLIST,MOBILE,MODEL,PLATFORM,PLATFORMVER,ARCHITECTURE,FORMFACTORS,BITNESS],AMAZON="Amazon",APPLE="Apple",ASUS="ASUS",BLACKBERRY="BlackBerry",GOOGLE="Google",HUAWEI="Huawei",LENOVO="Lenovo",HONOR="Honor",LG="LG",MICROSOFT="Microsoft",MOTOROLA="Motorola",NVIDIA="Nvidia",ONEPLUS="OnePlus",OPPO="OPPO",SAMSUNG="Samsung",SHARP="Sharp",SONY="Sony",XIAOMI="Xiaomi",ZEBRA="Zebra",CHROME="Chrome",CHROMIUM="Chromium",CHROMECAST="Chromecast",EDGE="Edge",FIREFOX="Firefox",OPERA="Opera",FACEBOOK="Facebook",SOGOU="Sogou",PREFIX_MOBILE="Mobile ",SUFFIX_BROWSER=" Browser",WINDOWS="Windows",isWindow=typeof window!==UNDEF_TYPE,NAVIGATOR=isWindow&&window.navigator?window.navigator:void 0,NAVIGATOR_UADATA=NAVIGATOR&&NAVIGATOR.userAgentData?NAVIGATOR.userAgentData:void 0,extend=function(defaultRgx,extensions){var mergedRgx={},extraRgx=extensions;if(!isExtensions(extensions)){extraRgx={};for(var i2 in extensions)for(var j in extensions[i2])extraRgx[j]=extensions[i2][j].concat(extraRgx[j]?extraRgx[j]:[])}for(var k in defaultRgx)mergedRgx[k]=extraRgx[k]&&extraRgx[k].length%2===0?extraRgx[k].concat(defaultRgx[k]):defaultRgx[k];return mergedRgx},enumerize=function(arr){for(var enums={},i2=0;i2<arr.length;i2++)enums[arr[i2].toUpperCase()]=arr[i2];return enums},has=function(str1,str2){if(typeof str1===OBJ_TYPE&&str1.length>0){for(var i2 in str1)if(lowerize(str2)==lowerize(str1[i2]))return!0;return!1}return isString(str1)?lowerize(str2)==lowerize(str1):!1},isExtensions=function(obj,deep){for(var prop in obj)return/^(browser|cpu|device|engine|os)$/.test(prop)||(deep?isExtensions(obj[prop]):!1)},isString=function(val){return typeof val===STR_TYPE},itemListToArray=function(header){if(header){for(var arr=[],tokens=strip(/\\?\"/g,header).split(","),i2=0;i2<tokens.length;i2++)if(tokens[i2].indexOf(";")>-1){var token=trim(tokens[i2]).split(";v=");arr[i2]={brand:token[0],version:token[1]}}else arr[i2]=trim(tokens[i2]);return arr}},lowerize=function(str){return isString(str)?str.toLowerCase():str},majorize=function(version){return isString(version)?strip(/[^\d\.]/g,version).split(".")[0]:void 0},setProps=function(arr){for(var i2 in arr){var propName=arr[i2];typeof propName==OBJ_TYPE&&propName.length==2?this[propName[0]]=propName[1]:this[propName]=void 0}return this},strip=function(pattern,str){return isString(str)?str.replace(pattern,EMPTY):str},stripQuotes=function(str){return strip(/\\?\"/g,str)},trim=function(str,len){if(isString(str))return str=strip(/^\s\s*/,str),typeof len===UNDEF_TYPE?str:str.substring(0,UA_MAX_LENGTH)},rgxMapper=function(ua,arrays){if(!(!ua||!arrays))for(var i2=0,j,k,p,q,matches,match;i2<arrays.length&&!matches;){var regex=arrays[i2],props=arrays[i2+1];for(j=k=0;j<regex.length&&!matches&&regex[j];)if(matches=regex[j++].exec(ua),matches)for(p=0;p<props.length;p++)match=matches[++k],q=props[p],typeof q===OBJ_TYPE&&q.length>0?q.length===2?typeof q[1]==FUNC_TYPE?this[q[0]]=q[1].call(this,match):this[q[0]]=q[1]:q.length>=3&&(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)?q.length>3?this[q[0]]=match?q[1].apply(this,q.slice(2)):void 0:this[q[0]]=match?q[1].call(this,match,q[2]):void 0:q.length==3?this[q[0]]=match?match.replace(q[1],q[2]):void 0:q.length==4?this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):void 0:q.length>4&&(this[q[0]]=match?q[3].apply(this,[match.replace(q[1],q[2])].concat(q.slice(4))):void 0)):this[q]=match||void 0;i2+=2}},strMapper=function(str,map){for(var i2 in map)if(typeof map[i2]===OBJ_TYPE&&map[i2].length>0){for(var j=0;j<map[i2].length;j++)if(has(map[i2][j],str))return i2===UNKNOWN?void 0:i2}else if(has(map[i2],str))return i2===UNKNOWN?void 0:i2;return map.hasOwnProperty("*")?map["*"]:str},windowsVersionMap={ME:"4.90","NT 3.51":"3.51","NT 4.0":"4.0",2e3:["5.0","5.01"],XP:["5.1","5.2"],Vista:"6.0",7:"6.1",8:"6.2","8.1":"6.3",10:["6.4","10.0"],NT:""},formFactorsMap={embedded:"Automotive",mobile:"Mobile",tablet:["Tablet","EInk"],smarttv:"TV",wearable:"Watch",xr:["VR","XR"],"?":["Desktop","Unknown"],"*":void 0},browserHintsMap={Chrome:"Google Chrome",Edge:"Microsoft Edge","Edge WebView2":"Microsoft Edge WebView2","Chrome WebView":"Android WebView","Chrome Headless":"HeadlessChrome","Huawei Browser":"HuaweiBrowser","MIUI Browser":"Miui Browser","Opera Mobi":"OperaMobile",Yandex:"YaBrowser"},defaultRegexes={browser:[[/\b(?:crmo|crios)\/([\w\.]+)/i],[VERSION,[NAME,PREFIX_MOBILE+"Chrome"]],[/webview.+edge\/([\w\.]+)/i],[VERSION,[NAME,EDGE+" WebView"]],[/edg(?:e|ios|a)?\/([\w\.]+)/i],[VERSION,[NAME,"Edge"]],[/(opera mini)\/([-\w\.]+)/i,/(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i,/(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i],[NAME,VERSION],[/opios[\/ ]+([\w\.]+)/i],[VERSION,[NAME,OPERA+" Mini"]],[/\bop(?:rg)?x\/([\w\.]+)/i],[VERSION,[NAME,OPERA+" GX"]],[/\bopr\/([\w\.]+)/i],[VERSION,[NAME,OPERA]],[/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i],[VERSION,[NAME,"Baidu"]],[/\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i],[VERSION,[NAME,"Maxthon"]],[/(kindle)\/([\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,/(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i,/(?:ms|\()(ie) ([\w\.]+)/i,/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|otter|dooble|(?:lg |qute)browser)\/([-\w\.]+)/i,/(heytap|ovi|115|surf)browser\/([\d\.]+)/i,/(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i],[NAME,VERSION],[/quark(?:pc)?\/([-\w\.]+)/i],[VERSION,[NAME,"Quark"]],[/\bddg\/([\w\.]+)/i],[VERSION,[NAME,"DuckDuckGo"]],[/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i],[VERSION,[NAME,"UCBrowser"]],[/microm.+\bqbcore\/([\w\.]+)/i,/\bqbcore\/([\w\.]+).+microm/i,/micromessenger\/([\w\.]+)/i],[VERSION,[NAME,"WeChat"]],[/konqueror\/([\w\.]+)/i],[VERSION,[NAME,"Konqueror"]],[/trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i],[VERSION,[NAME,"IE"]],[/ya(?:search)?browser\/([\w\.]+)/i],[VERSION,[NAME,"Yandex"]],[/slbrowser\/([\w\.]+)/i],[VERSION,[NAME,"Smart "+LENOVO+SUFFIX_BROWSER]],[/(avast|avg)\/([\w\.]+)/i],[[NAME,/(.+)/,"$1 Secure"+SUFFIX_BROWSER],VERSION],[/\bfocus\/([\w\.]+)/i],[VERSION,[NAME,FIREFOX+" Focus"]],[/\bopt\/([\w\.]+)/i],[VERSION,[NAME,OPERA+" Touch"]],[/coc_coc\w+\/([\w\.]+)/i],[VERSION,[NAME,"Coc Coc"]],[/dolfin\/([\w\.]+)/i],[VERSION,[NAME,"Dolphin"]],[/coast\/([\w\.]+)/i],[VERSION,[NAME,OPERA+" Coast"]],[/miuibrowser\/([\w\.]+)/i],[VERSION,[NAME,"MIUI"+SUFFIX_BROWSER]],[/fxios\/([\w\.-]+)/i],[VERSION,[NAME,PREFIX_MOBILE+FIREFOX]],[/\bqihoobrowser\/?([\w\.]*)/i],[VERSION,[NAME,"360"]],[/\b(qq)\/([\w\.]+)/i],[[NAME,/(.+)/,"$1Browser"],VERSION],[/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i],[[NAME,/(.+)/,"$1"+SUFFIX_BROWSER],VERSION],[/samsungbrowser\/([\w\.]+)/i],[VERSION,[NAME,SAMSUNG+" Internet"]],[/metasr[\/ ]?([\d\.]+)/i],[VERSION,[NAME,SOGOU+" Explorer"]],[/(sogou)mo\w+\/([\d\.]+)/i],[[NAME,SOGOU+" Mobile"],VERSION],[/(electron)\/([\w\.]+) safari/i,/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i,/m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i],[NAME,VERSION],[/(lbbrowser|rekonq)/i],[NAME],[/ome\/([\w\.]+) \w* ?(iron) saf/i,/ome\/([\w\.]+).+qihu (360)[es]e/i],[VERSION,NAME],[/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i],[[NAME,FACEBOOK],VERSION,[TYPE,INAPP]],[/(kakao(?:talk|story))[\/ ]([\w\.]+)/i,/(naver)\(.*?(\d+\.[\w\.]+).*\)/i,/(daum)apps[\/ ]([\w\.]+)/i,/safari (line)\/([\w\.]+)/i,/\b(line)\/([\w\.]+)\/iab/i,/(alipay)client\/([\w\.]+)/i,/(twitter)(?:and| f.+e\/([\w\.]+))/i,/(instagram|snapchat|klarna)[\/ ]([-\w\.]+)/i],[NAME,VERSION,[TYPE,INAPP]],[/\bgsa\/([\w\.]+) .*safari\//i],[VERSION,[NAME,"GSA"],[TYPE,INAPP]],[/musical_ly(?:.+app_?version\/|_)([\w\.]+)/i],[VERSION,[NAME,"TikTok"],[TYPE,INAPP]],[/\[(linkedin)app\]/i],[NAME,[TYPE,INAPP]],[/(chromium)[\/ ]([-\w\.]+)/i],[NAME,VERSION],[/headlesschrome(?:\/([\w\.]+)| )/i],[VERSION,[NAME,CHROME+" Headless"]],[/wv\).+chrome\/([\w\.]+).+edgw\//i],[VERSION,[NAME,EDGE+" WebView2"]],[/ wv\).+(chrome)\/([\w\.]+)/i],[[NAME,CHROME+" WebView"],VERSION],[/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i],[VERSION,[NAME,"Android"+SUFFIX_BROWSER]],[/chrome\/([\w\.]+) mobile/i],[VERSION,[NAME,PREFIX_MOBILE+"Chrome"]],[/(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i],[NAME,VERSION],[/version\/([\w\.\,]+) .*mobile(?:\/\w+ | ?)safari/i],[VERSION,[NAME,PREFIX_MOBILE+"Safari"]],[/iphone .*mobile(?:\/\w+ | ?)safari/i],[[NAME,PREFIX_MOBILE+"Safari"]],[/version\/([\w\.\,]+) .*(safari)/i],[VERSION,NAME],[/webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i],[NAME,[VERSION,"1"]],[/(webkit|khtml)\/([\w\.]+)/i],[NAME,VERSION],[/(?:mobile|tablet);.*(firefox)\/([\w\.-]+)/i],[[NAME,PREFIX_MOBILE+FIREFOX],VERSION],[/(navigator|netscape\d?)\/([-\w\.]+)/i],[[NAME,"Netscape"],VERSION],[/(wolvic|librewolf)\/([\w\.]+)/i],[NAME,VERSION],[/mobile vr; rv:([\w\.]+)\).+firefox/i],[VERSION,[NAME,FIREFOX+" Reality"]],[/ekiohf.+(flow)\/([\w\.]+)/i,/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,/(firefox)\/([\w\.]+)/i,/(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i,/(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,/\b(links) \(([\w\.]+)/i],[NAME,[VERSION,/_/g,"."]],[/(cobalt)\/([\w\.]+)/i],[NAME,[VERSION,/[^\d\.]+./,EMPTY]]],cpu:[[/\b((amd|x|x86[-_]?|wow|win)64)\b/i],[[ARCHITECTURE,"amd64"]],[/(ia32(?=;))/i,/\b((i[346]|x)86)(pc)?\b/i],[[ARCHITECTURE,"ia32"]],[/\b(aarch64|arm(v?[89]e?l?|_?64))\b/i],[[ARCHITECTURE,"arm64"]],[/\b(arm(v[67])?ht?n?[fl]p?)\b/i],[[ARCHITECTURE,"armhf"]],[/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i],[[ARCHITECTURE,"arm"]],[/((ppc|powerpc)(64)?)( mac|;|\))/i],[[ARCHITECTURE,/ower/,EMPTY,lowerize]],[/ sun4\w[;\)]/i],[[ARCHITECTURE,"sparc"]],[/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i],[[ARCHITECTURE,lowerize]]],device:[[/\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i],[MODEL,[VENDOR,SAMSUNG],[TYPE,TABLET]],[/\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,/samsung[- ]((?!sm-[lr]|browser)[-\w]+)/i,/sec-(sgh\w+)/i],[MODEL,[VENDOR,SAMSUNG],[TYPE,MOBILE]],[/(?:\/|\()(ip(?:hone|od)[\w, ]*)(?:\/|;)/i],[MODEL,[VENDOR,APPLE],[TYPE,MOBILE]],[/\((ipad);[-\w\),; ]+apple/i,/applecoremedia\/[\w\.]+ \((ipad)/i,/\b(ipad)\d\d?,\d\d?[;\]].+ios/i],[MODEL,[VENDOR,APPLE],[TYPE,TABLET]],[/(macintosh);/i],[MODEL,[VENDOR,APPLE]],[/\b(sh-?[altvz]?\d\d[a-ekm]?)/i],[MODEL,[VENDOR,SHARP],[TYPE,MOBILE]],[/\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i],[MODEL,[VENDOR,HONOR],[TYPE,TABLET]],[/honor([-\w ]+)[;\)]/i],[MODEL,[VENDOR,HONOR],[TYPE,MOBILE]],[/\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i],[MODEL,[VENDOR,HUAWEI],[TYPE,TABLET]],[/(?:huawei)([-\w ]+)[;\)]/i,/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i],[MODEL,[VENDOR,HUAWEI],[TYPE,MOBILE]],[/oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i,/\b((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i],[[MODEL,/_/g," "],[VENDOR,XIAOMI],[TYPE,TABLET]],[/\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i,/\b; (\w+) build\/hm\1/i,/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i,/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i,/oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i,/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i,/ ([\w ]+) miui\/v?\d/i],[[MODEL,/_/g," "],[VENDOR,XIAOMI],[TYPE,MOBILE]],[/droid.+; (cph2[3-6]\d[13579]|((gm|hd)19|(ac|be|in|kb)20|(d[en]|eb|le|mt)21|ne22)[0-2]\d|p[g-k]\w[1m]10)\b/i,/(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i],[MODEL,[VENDOR,ONEPLUS],[TYPE,MOBILE]],[/; (\w+) bui.+ oppo/i,/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i],[MODEL,[VENDOR,OPPO],[TYPE,MOBILE]],[/\b(opd2(\d{3}a?))(?: bui|\))/i],[MODEL,[VENDOR,strMapper,{OnePlus:["203","304","403","404","413","415"],"*":OPPO}],[TYPE,TABLET]],[/(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i],[MODEL,[VENDOR,"BLU"],[TYPE,MOBILE]],[/; vivo (\w+)(?: bui|\))/i,/\b(v[12]\d{3}\w?[at])(?: bui|;)/i],[MODEL,[VENDOR,"Vivo"],[TYPE,MOBILE]],[/\b(rmx[1-3]\d{3})(?: bui|;|\))/i],[MODEL,[VENDOR,"Realme"],[TYPE,MOBILE]],[/(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i,/lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i],[MODEL,[VENDOR,LENOVO],[TYPE,TABLET]],[/lenovo[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i],[MODEL,[VENDOR,LENOVO],[TYPE,MOBILE]],[/\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,/\bmot(?:orola)?[- ]([\w\s]+)(\)| bui)/i,/((?:moto(?! 360)[-\w\(\) ]+|xt\d{3,4}[cgkosw\+]?[-\d]*|nexus 6)(?= bui|\)))/i],[MODEL,[VENDOR,MOTOROLA],[TYPE,MOBILE]],[/\b(mz60\d|xoom[2 ]{0,2}) build\//i],[MODEL,[VENDOR,MOTOROLA],[TYPE,TABLET]],[/((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i],[MODEL,[VENDOR,LG],[TYPE,TABLET]],[/(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,/\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch|webos))(\w+)/i,/\blg-?([\d\w]+) bui/i],[MODEL,[VENDOR,LG],[TYPE,MOBILE]],[/(nokia) (t[12][01])/i],[VENDOR,MODEL,[TYPE,TABLET]],[/(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i,/nokia[-_ ]?(([-\w\. ]*))/i],[[MODEL,/_/g," "],[TYPE,MOBILE],[VENDOR,"Nokia"]],[/(pixel (c|tablet))\b/i],[MODEL,[VENDOR,GOOGLE],[TYPE,TABLET]],[/droid.+;(?: google)? (g(01[13]a|020[aem]|025[jn]|1b60|1f8f|2ybb|4s1m|576d|5nz6|8hhn|8vou|a02099|c15s|d1yq|e2ae|ec77|gh2x|kv4x|p4bc|pj41|r83y|tt9q|ur25|wvk6)|pixel[\d ]*a?( pro)?( xl)?( fold)?( \(5g\))?)( bui|\))/i],[MODEL,[VENDOR,GOOGLE],[TYPE,MOBILE]],[/(google) (pixelbook( go)?)/i],[VENDOR,MODEL],[/droid.+; (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-\w\w\d\d)(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i],[MODEL,[VENDOR,SONY],[TYPE,MOBILE]],[/sony tablet [ps]/i,/\b(?:sony)?sgp\w+(?: bui|\))/i],[[MODEL,"Xperia Tablet"],[VENDOR,SONY],[TYPE,TABLET]],[/(alexa)webm/i,/(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i,/(kf[a-z]+)( bui|\)).+silk\//i],[MODEL,[VENDOR,AMAZON],[TYPE,TABLET]],[/((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i],[[MODEL,/(.+)/g,"Fire Phone $1"],[VENDOR,AMAZON],[TYPE,MOBILE]],[/(playbook);[-\w\),; ]+(rim)/i],[MODEL,VENDOR,[TYPE,TABLET]],[/\b((?:bb[a-f]|st[hv])100-\d)/i,/\(bb10; (\w+)/i],[MODEL,[VENDOR,BLACKBERRY],[TYPE,MOBILE]],[/(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i],[MODEL,[VENDOR,ASUS],[TYPE,TABLET]],[/ (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i],[MODEL,[VENDOR,ASUS],[TYPE,MOBILE]],[/(nexus 9)/i],[MODEL,[VENDOR,"HTC"],[TYPE,TABLET]],[/(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i,/(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,/(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i],[VENDOR,[MODEL,/_/g," "],[TYPE,MOBILE]],[/tcl (xess p17aa)/i,/droid [\w\.]+; ((?:8[14]9[16]|9(?:0(?:48|60|8[01])|1(?:3[27]|66)|2(?:6[69]|9[56])|466))[gqswx])(_\w(\w|\w\w))?(\)| bui)/i],[MODEL,[VENDOR,"TCL"],[TYPE,TABLET]],[/droid [\w\.]+; (418(?:7d|8v)|5087z|5102l|61(?:02[dh]|25[adfh]|27[ai]|56[dh]|59k|65[ah])|a509dl|t(?:43(?:0w|1[adepqu])|50(?:6d|7[adju])|6(?:09dl|10k|12b|71[efho]|76[hjk])|7(?:66[ahju]|67[hw]|7[045][bh]|71[hk]|73o|76[ho]|79w|81[hks]?|82h|90[bhsy]|99b)|810[hs]))(_\w(\w|\w\w))?(\)| bui)/i],[MODEL,[VENDOR,"TCL"],[TYPE,MOBILE]],[/(itel) ((\w+))/i],[[VENDOR,lowerize],MODEL,[TYPE,strMapper,{tablet:["p10001l","w7001"],"*":"mobile"}]],[/droid.+; ([ab][1-7]-?[0178a]\d\d?)/i],[MODEL,[VENDOR,"Acer"],[TYPE,TABLET]],[/droid.+; (m[1-5] note) bui/i,/\bmz-([-\w]{2,})/i],[MODEL,[VENDOR,"Meizu"],[TYPE,MOBILE]],[/; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i],[MODEL,[VENDOR,"Ulefone"],[TYPE,MOBILE]],[/; (energy ?\w+)(?: bui|\))/i,/; energizer ([\w ]+)(?: bui|\))/i],[MODEL,[VENDOR,"Energizer"],[TYPE,MOBILE]],[/; cat (b35);/i,/; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i],[MODEL,[VENDOR,"Cat"],[TYPE,MOBILE]],[/((?:new )?andromax[\w- ]+)(?: bui|\))/i],[MODEL,[VENDOR,"Smartfren"],[TYPE,MOBILE]],[/droid.+; (a(in)?(0(15|59|6[35])|142)p?)/i],[MODEL,[VENDOR,"Nothing"],[TYPE,MOBILE]],[/; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i,/archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i],[MODEL,[VENDOR,"Archos"],[TYPE,TABLET]],[/archos ([\w ]+)( b|\))/i,/; (ac[3-6]\d\w{2,8})( b|\))/i],[MODEL,[VENDOR,"Archos"],[TYPE,MOBILE]],[/; (n159v)/i],[MODEL,[VENDOR,"HMD"],[TYPE,MOBILE]],[/(imo) (tab \w+)/i,/(infinix|tecno) (x1101b?|p904|dp(7c|8d|10a)( pro)?|p70[1-3]a?|p904|t1101)/i],[VENDOR,MODEL,[TYPE,TABLET]],[/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|tecno|micromax|advan)[-_ ]?([-\w]*)/i,/; (blu|hmd|imo|infinix|lava|oneplus|tcl)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i,/(hp) ([\w ]+\w)/i,/(microsoft); (lumia[\w ]+)/i,/(oppo) ?([\w ]+) bui/i],[VENDOR,MODEL,[TYPE,MOBILE]],[/(kobo)\s(ereader|touch)/i,/(hp).+(touchpad(?!.+tablet)|tablet)/i,/(kindle)\/([\w\.]+)/i],[VENDOR,MODEL,[TYPE,TABLET]],[/(surface duo)/i],[MODEL,[VENDOR,MICROSOFT],[TYPE,TABLET]],[/droid [\d\.]+; (fp\du?)(?: b|\))/i],[MODEL,[VENDOR,"Fairphone"],[TYPE,MOBILE]],[/((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i],[MODEL,[VENDOR,NVIDIA],[TYPE,TABLET]],[/(sprint) (\w+)/i],[VENDOR,MODEL,[TYPE,MOBILE]],[/(kin\.[onetw]{3})/i],[[MODEL,/\./g," "],[VENDOR,MICROSOFT],[TYPE,MOBILE]],[/droid.+; ([c6]+|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i],[MODEL,[VENDOR,ZEBRA],[TYPE,TABLET]],[/droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i],[MODEL,[VENDOR,ZEBRA],[TYPE,MOBILE]],[/smart-tv.+(samsung)/i],[VENDOR,[TYPE,SMARTTV]],[/hbbtv.+maple;(\d+)/i],[[MODEL,/^/,"SmartTV"],[VENDOR,SAMSUNG],[TYPE,SMARTTV]],[/(vizio)(?: |.+model\/)(\w+-\w+)/i,/tcast.+(lg)e?. ([-\w]+)/i],[VENDOR,MODEL,[TYPE,SMARTTV]],[/(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i],[[VENDOR,LG],[TYPE,SMARTTV]],[/(apple) ?tv/i],[VENDOR,[MODEL,APPLE+" TV"],[TYPE,SMARTTV]],[/crkey.*devicetype\/chromecast/i],[[MODEL,CHROMECAST+" Third Generation"],[VENDOR,GOOGLE],[TYPE,SMARTTV]],[/crkey.*devicetype\/([^/]*)/i],[[MODEL,/^/,"Chromecast "],[VENDOR,GOOGLE],[TYPE,SMARTTV]],[/fuchsia.*crkey/i],[[MODEL,CHROMECAST+" Nest Hub"],[VENDOR,GOOGLE],[TYPE,SMARTTV]],[/crkey/i],[[MODEL,CHROMECAST],[VENDOR,GOOGLE],[TYPE,SMARTTV]],[/(portaltv)/i],[MODEL,[VENDOR,FACEBOOK],[TYPE,SMARTTV]],[/droid.+aft(\w+)( bui|\))/i],[MODEL,[VENDOR,AMAZON],[TYPE,SMARTTV]],[/(shield \w+ tv)/i],[MODEL,[VENDOR,NVIDIA],[TYPE,SMARTTV]],[/\(dtv[\);].+(aquos)/i,/(aquos-tv[\w ]+)\)/i],[MODEL,[VENDOR,SHARP],[TYPE,SMARTTV]],[/(bravia[\w ]+)( bui|\))/i],[MODEL,[VENDOR,SONY],[TYPE,SMARTTV]],[/(mi(tv|box)-?\w+) bui/i],[MODEL,[VENDOR,XIAOMI],[TYPE,SMARTTV]],[/Hbbtv.*(technisat) (.*);/i],[VENDOR,MODEL,[TYPE,SMARTTV]],[/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i,/hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i],[[VENDOR,/.+\/(\w+)/,"$1",strMapper,{LG:"lge"}],[MODEL,trim],[TYPE,SMARTTV]],[/droid.+; ([\w- ]+) (?:android tv|smart[- ]?tv)/i],[MODEL,[TYPE,SMARTTV]],[/\b(android tv|smart[- ]?tv|opera tv|tv; rv:|large screen[\w ]+safari)\b/i],[[TYPE,SMARTTV]],[/(playstation \w+)/i],[MODEL,[VENDOR,SONY],[TYPE,CONSOLE]],[/\b(xbox(?: one)?(?!; xbox))[\); ]/i],[MODEL,[VENDOR,MICROSOFT],[TYPE,CONSOLE]],[/(ouya)/i,/(nintendo) (\w+)/i,/(retroid) (pocket ([^\)]+))/i],[VENDOR,MODEL,[TYPE,CONSOLE]],[/droid.+; (shield)( bui|\))/i],[MODEL,[VENDOR,NVIDIA],[TYPE,CONSOLE]],[/\b(sm-[lr]\d\d[0156][fnuw]?s?|gear live)\b/i],[MODEL,[VENDOR,SAMSUNG],[TYPE,WEARABLE]],[/((pebble))app/i,/(asus|google|lg|oppo) ((pixel |zen)?watch[\w ]*)( bui|\))/i],[VENDOR,MODEL,[TYPE,WEARABLE]],[/(ow(?:19|20)?we?[1-3]{1,3})/i],[MODEL,[VENDOR,OPPO],[TYPE,WEARABLE]],[/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i],[MODEL,[VENDOR,APPLE],[TYPE,WEARABLE]],[/(opwwe\d{3})/i],[MODEL,[VENDOR,ONEPLUS],[TYPE,WEARABLE]],[/(moto 360)/i],[MODEL,[VENDOR,MOTOROLA],[TYPE,WEARABLE]],[/(smartwatch 3)/i],[MODEL,[VENDOR,SONY],[TYPE,WEARABLE]],[/(g watch r)/i],[MODEL,[VENDOR,LG],[TYPE,WEARABLE]],[/droid.+; (wt63?0{2,3})\)/i],[MODEL,[VENDOR,ZEBRA],[TYPE,WEARABLE]],[/droid.+; (glass) \d/i],[MODEL,[VENDOR,GOOGLE],[TYPE,XR]],[/(pico) (4|neo3(?: link|pro)?)/i],[VENDOR,MODEL,[TYPE,XR]],[/(quest( \d| pro)?s?).+vr/i],[MODEL,[VENDOR,FACEBOOK],[TYPE,XR]],[/mobile vr; rv.+firefox/i],[[TYPE,XR]],[/(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i],[VENDOR,[TYPE,EMBEDDED]],[/(aeobc)\b/i],[MODEL,[VENDOR,AMAZON],[TYPE,EMBEDDED]],[/(homepod).+mac os/i],[MODEL,[VENDOR,APPLE],[TYPE,EMBEDDED]],[/windows iot/i],[[TYPE,EMBEDDED]],[/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+?(mobile|vr|\d) safari/i],[MODEL,[TYPE,strMapper,{mobile:"Mobile",xr:"VR","*":TABLET}]],[/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i],[[TYPE,TABLET]],[/(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i],[[TYPE,MOBILE]],[/droid .+?; ([\w\. -]+)( bui|\))/i],[MODEL,[VENDOR,"Generic"]]],engine:[[/windows.+ edge\/([\w\.]+)/i],[VERSION,[NAME,EDGE+"HTML"]],[/(arkweb)\/([\w\.]+)/i],[NAME,VERSION],[/webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i],[VERSION,[NAME,"Blink"]],[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i,/ekioh(flow)\/([\w\.]+)/i,/(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i,/(icab)[\/ ]([23]\.[\d\.]+)/i,/\b(libweb)/i],[NAME,VERSION],[/ladybird\//i],[[NAME,"LibWeb"]],[/rv\:([\w\.]{1,9})\b.+(gecko)/i],[VERSION,NAME]],os:[[/(windows nt) (6\.[23]); arm/i],[[NAME,/N/,"R"],[VERSION,strMapper,windowsVersionMap]],[/(windows (?:phone|mobile|iot))(?: os)?[\/ ]?([\d\.]*( se)?)/i,/(windows)[\/ ](1[01]|2000|3\.1|7|8(\.1)?|9[58]|me|server 20\d\d( r2)?|vista|xp)/i],[NAME,VERSION],[/windows nt ?([\d\.\)]*)(?!.+xbox)/i,/\bwin(?=3| ?9|n)(?:nt| 9x )?([\d\.;]*)/i],[[VERSION,/(;|\))/g,"",strMapper,windowsVersionMap],[NAME,WINDOWS]],[/(windows ce)\/?([\d\.]*)/i],[NAME,VERSION],[/[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i,/(?:ios;fbsv\/|iphone.+ios[\/ ])([\d\.]+)/i,/cfnetwork\/.+darwin/i],[[VERSION,/_/g,"."],[NAME,"iOS"]],[/(mac os x) ?([\w\. ]*)/i,/(macintosh|mac_powerpc\b)(?!.+(haiku|morphos))/i],[[NAME,"macOS"],[VERSION,/_/g,"."]],[/android ([\d\.]+).*crkey/i],[VERSION,[NAME,CHROMECAST+" Android"]],[/fuchsia.*crkey\/([\d\.]+)/i],[VERSION,[NAME,CHROMECAST+" Fuchsia"]],[/crkey\/([\d\.]+).*devicetype\/smartspeaker/i],[VERSION,[NAME,CHROMECAST+" SmartSpeaker"]],[/linux.*crkey\/([\d\.]+)/i],[VERSION,[NAME,CHROMECAST+" Linux"]],[/crkey\/([\d\.]+)/i],[VERSION,[NAME,CHROMECAST]],[/droid ([\w\.]+)\b.+(android[- ]x86)/i],[VERSION,NAME],[/(ubuntu) ([\w\.]+) like android/i],[[NAME,/(.+)/,"$1 Touch"],VERSION],[/(harmonyos)[\/ ]?([\d\.]*)/i,/(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen)\w*[-\/\.; ]?([\d\.]*)/i],[NAME,VERSION],[/\(bb(10);/i],[VERSION,[NAME,BLACKBERRY]],[/(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\/ ]?([\w\.]*)/i],[VERSION,[NAME,"Symbian"]],[/mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i],[VERSION,[NAME,FIREFOX+" OS"]],[/\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i,/webos(?:[ \/]?|\.tv-20(?=2[2-9]))(\d[\d\.]*)/i],[VERSION,[NAME,"webOS"]],[/web0s;.+?(?:chr[o0]me|safari)\/(\d+)/i],[[VERSION,strMapper,{25:"120",24:"108",23:"94",22:"87",6:"79",5:"68",4:"53",3:"38",2:"538",1:"537","*":"TV"}],[NAME,"webOS"]],[/watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i],[VERSION,[NAME,"watchOS"]],[/(cros) [\w]+(?:\)| ([\w\.]+)\b)/i],[[NAME,"Chrome OS"],VERSION],[/panasonic;(viera)/i,/(netrange)mmh/i,/(nettv)\/(\d+\.[\w\.]+)/i,/(nintendo|playstation) (\w+)/i,/(xbox); +xbox ([^\);]+)/i,/(pico) .+os([\w\.]+)/i,/\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i,/linux.+(mint)[\/\(\) ]?([\w\.]*)/i,/(mageia|vectorlinux|fuchsia|arcaos|arch(?= ?linux))[;l ]([\d\.]*)/i,/([kxln]?ubuntu|debian|suse|opensuse|gentoo|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire|knoppix)(?: gnu[\/ ]linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,/((?:open)?solaris)[-\/ ]?([\w\.]*)/i,/\b(aix)[; ]([1-9\.]{0,4})/i,/(hurd|linux|morphos)(?: (?:arm|x86|ppc)\w*| ?)([\w\.]*)/i,/(gnu) ?([\w\.]*)/i,/\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i,/(haiku) ?(r\d)?/i],[NAME,VERSION],[/(sunos) ?([\d\.]*)/i],[[NAME,"Solaris"],VERSION],[/\b(beos|os\/2|amigaos|openvms|hp-ux|serenityos)/i,/(unix) ?([\w\.]*)/i],[NAME,VERSION]]},defaultProps=function(){var props={init:{},isIgnore:{},isIgnoreRgx:{},toString:{}};return setProps.call(props.init,[[UA_BROWSER,[NAME,VERSION,MAJOR,TYPE]],[UA_CPU,[ARCHITECTURE]],[UA_DEVICE,[TYPE,MODEL,VENDOR]],[UA_ENGINE,[NAME,VERSION]],[UA_OS,[NAME,VERSION]]]),setProps.call(props.isIgnore,[[UA_BROWSER,[VERSION,MAJOR]],[UA_ENGINE,[VERSION]],[UA_OS,[VERSION]]]),setProps.call(props.isIgnoreRgx,[[UA_BROWSER,/ ?browser$/i],[UA_OS,/ ?os$/i]]),setProps.call(props.toString,[[UA_BROWSER,[NAME,VERSION]],[UA_CPU,[ARCHITECTURE]],[UA_DEVICE,[VENDOR,MODEL]],[UA_ENGINE,[NAME,VERSION]],[UA_OS,[NAME,VERSION]]]),props}(),createIData=function(item,itemType){var init_props=defaultProps.init[itemType],is_ignoreProps=defaultProps.isIgnore[itemType]||0,is_ignoreRgx=defaultProps.isIgnoreRgx[itemType]||0,toString_props=defaultProps.toString[itemType]||0;function IData(){setProps.call(this,init_props)}return IData.prototype.getItem=function(){return item},IData.prototype.withClientHints=function(){return NAVIGATOR_UADATA?NAVIGATOR_UADATA.getHighEntropyValues(CH_ALL_VALUES).then(function(res){return item.setCH(new UACHData(res,!1)).parseCH().get()}):item.parseCH().get()},IData.prototype.withFeatureCheck=function(){return item.detectFeature().get()},itemType!=UA_RESULT&&(IData.prototype.is=function(strToCheck){var is=!1;for(var i2 in this)if(this.hasOwnProperty(i2)&&!has(is_ignoreProps,i2)&&lowerize(is_ignoreRgx?strip(is_ignoreRgx,this[i2]):this[i2])==lowerize(is_ignoreRgx?strip(is_ignoreRgx,strToCheck):strToCheck)){if(is=!0,strToCheck!=UNDEF_TYPE)break}else if(strToCheck==UNDEF_TYPE&&is){is=!is;break}return is},IData.prototype.toString=function(){var str=EMPTY;for(var i2 in toString_props)typeof this[toString_props[i2]]!==UNDEF_TYPE&&(str+=(str?" ":EMPTY)+this[toString_props[i2]]);return str||UNDEF_TYPE}),NAVIGATOR_UADATA||(IData.prototype.then=function(cb){var that=this,IDataResolve=function(){for(var prop in that)that.hasOwnProperty(prop)&&(this[prop]=that[prop])};IDataResolve.prototype={is:IData.prototype.is,toString:IData.prototype.toString};var resolveData=new IDataResolve;return cb(resolveData),resolveData}),new IData};function UACHData(uach,isHttpUACH){if(uach=uach||{},setProps.call(this,CH_ALL_VALUES),isHttpUACH)setProps.call(this,[[BRANDS,itemListToArray(uach[CH_HEADER])],[FULLVERLIST,itemListToArray(uach[CH_HEADER_FULL_VER_LIST])],[MOBILE,/\?1/.test(uach[CH_HEADER_MOBILE])],[MODEL,stripQuotes(uach[CH_HEADER_MODEL])],[PLATFORM,stripQuotes(uach[CH_HEADER_PLATFORM])],[PLATFORMVER,stripQuotes(uach[CH_HEADER_PLATFORM_VER])],[ARCHITECTURE,stripQuotes(uach[CH_HEADER_ARCH])],[FORMFACTORS,itemListToArray(uach[CH_HEADER_FORM_FACTORS])],[BITNESS,stripQuotes(uach[CH_HEADER_BITNESS])]]);else for(var prop in uach)this.hasOwnProperty(prop)&&typeof uach[prop]!==UNDEF_TYPE&&(this[prop]=uach[prop])}function UAItem(itemType,ua,rgxMap,uaCH){return this.get=function(prop){return prop?this.data.hasOwnProperty(prop)?this.data[prop]:void 0:this.data},this.set=function(prop,val){return this.data[prop]=val,this},this.setCH=function(ch){return this.uaCH=ch,this},this.detectFeature=function(){if(NAVIGATOR&&NAVIGATOR.userAgent==this.ua)switch(this.itemType){case UA_BROWSER:NAVIGATOR.brave&&typeof NAVIGATOR.brave.isBrave==FUNC_TYPE&&this.set(NAME,"Brave");break;case UA_DEVICE:!this.get(TYPE)&&NAVIGATOR_UADATA&&NAVIGATOR_UADATA[MOBILE]&&this.set(TYPE,MOBILE),this.get(MODEL)=="Macintosh"&&NAVIGATOR&&typeof NAVIGATOR.standalone!==UNDEF_TYPE&&NAVIGATOR.maxTouchPoints&&NAVIGATOR.maxTouchPoints>2&&this.set(MODEL,"iPad").set(TYPE,TABLET);break;case UA_OS:!this.get(NAME)&&NAVIGATOR_UADATA&&NAVIGATOR_UADATA[PLATFORM]&&this.set(NAME,NAVIGATOR_UADATA[PLATFORM]);break;case UA_RESULT:var data=this.data,detect=function(itemType2){return data[itemType2].getItem().detectFeature().get()};this.set(UA_BROWSER,detect(UA_BROWSER)).set(UA_CPU,detect(UA_CPU)).set(UA_DEVICE,detect(UA_DEVICE)).set(UA_ENGINE,detect(UA_ENGINE)).set(UA_OS,detect(UA_OS))}return this},this.parseUA=function(){return this.itemType!=UA_RESULT&&rgxMapper.call(this.data,this.ua,this.rgxMap),this.itemType==UA_BROWSER&&this.set(MAJOR,majorize(this.get(VERSION))),this},this.parseCH=function(){var uaCH2=this.uaCH,rgxMap2=this.rgxMap;switch(this.itemType){case UA_BROWSER:case UA_ENGINE:var brands=uaCH2[FULLVERLIST]||uaCH2[BRANDS],prevName;if(brands)for(var i2 in brands){var brandName=brands[i2].brand||brands[i2],brandVersion=brands[i2].version;this.itemType==UA_BROWSER&&!/not.a.brand/i.test(brandName)&&(!prevName||/Chrom/.test(prevName)&&brandName!=CHROMIUM||prevName==EDGE&&/WebView2/.test(brandName))&&(brandName=strMapper(brandName,browserHintsMap),prevName=this.get(NAME),prevName&&!/Chrom/.test(prevName)&&/Chrom/.test(brandName)||this.set(NAME,brandName).set(VERSION,brandVersion).set(MAJOR,majorize(brandVersion)),prevName=brandName),this.itemType==UA_ENGINE&&brandName==CHROMIUM&&this.set(VERSION,brandVersion)}break;case UA_CPU:var archName=uaCH2[ARCHITECTURE];archName&&(archName&&uaCH2[BITNESS]=="64"&&(archName+="64"),rgxMapper.call(this.data,archName+";",rgxMap2));break;case UA_DEVICE:if(uaCH2[MOBILE]&&this.set(TYPE,MOBILE),uaCH2[MODEL]&&(this.set(MODEL,uaCH2[MODEL]),!this.get(TYPE)||!this.get(VENDOR))){var reParse={};rgxMapper.call(reParse,"droid 9; "+uaCH2[MODEL]+")",rgxMap2),!this.get(TYPE)&&reParse.type&&this.set(TYPE,reParse.type),!this.get(VENDOR)&&reParse.vendor&&this.set(VENDOR,reParse.vendor)}if(uaCH2[FORMFACTORS]){var ff;if(typeof uaCH2[FORMFACTORS]!="string")for(var idx=0;!ff&&idx<uaCH2[FORMFACTORS].length;)ff=strMapper(uaCH2[FORMFACTORS][idx++],formFactorsMap);else ff=strMapper(uaCH2[FORMFACTORS],formFactorsMap);this.set(TYPE,ff)}break;case UA_OS:var osName=uaCH2[PLATFORM];if(osName){var osVersion=uaCH2[PLATFORMVER];osName==WINDOWS&&(osVersion=parseInt(majorize(osVersion),10)>=13?"11":"10"),this.set(NAME,osName).set(VERSION,osVersion)}this.get(NAME)==WINDOWS&&uaCH2[MODEL]=="Xbox"&&this.set(NAME,"Xbox").set(VERSION,void 0);break;case UA_RESULT:var data=this.data,parse=function(itemType2){return data[itemType2].getItem().setCH(uaCH2).parseCH().get()};this.set(UA_BROWSER,parse(UA_BROWSER)).set(UA_CPU,parse(UA_CPU)).set(UA_DEVICE,parse(UA_DEVICE)).set(UA_ENGINE,parse(UA_ENGINE)).set(UA_OS,parse(UA_OS))}return this},setProps.call(this,[["itemType",itemType],["ua",ua],["uaCH",uaCH],["rgxMap",rgxMap],["data",createIData(this,itemType)]]),this}function UAParser(ua,extensions,headers){if(typeof ua===OBJ_TYPE?(isExtensions(ua,!0)?(typeof extensions===OBJ_TYPE&&(headers=extensions),extensions=ua):(headers=ua,extensions=void 0),ua=void 0):typeof ua===STR_TYPE&&!isExtensions(extensions,!0)&&(headers=extensions,extensions=void 0),headers&&typeof headers.append===FUNC_TYPE){var kv={};headers.forEach(function(v,k){kv[k]=v}),headers=kv}if(!(this instanceof UAParser))return new UAParser(ua,extensions,headers).getResult();var userAgent=typeof ua===STR_TYPE?ua:headers&&headers[USER_AGENT]?headers[USER_AGENT]:NAVIGATOR&&NAVIGATOR.userAgent?NAVIGATOR.userAgent:EMPTY,httpUACH=new UACHData(headers,!0),regexMap=extensions?extend(defaultRegexes,extensions):defaultRegexes,createItemFunc=function(itemType){return itemType==UA_RESULT?function(){return new UAItem(itemType,userAgent,regexMap,httpUACH).set("ua",userAgent).set(UA_BROWSER,this.getBrowser()).set(UA_CPU,this.getCPU()).set(UA_DEVICE,this.getDevice()).set(UA_ENGINE,this.getEngine()).set(UA_OS,this.getOS()).get()}:function(){return new UAItem(itemType,userAgent,regexMap[itemType],httpUACH).parseUA().get()}};return setProps.call(this,[["getBrowser",createItemFunc(UA_BROWSER)],["getCPU",createItemFunc(UA_CPU)],["getDevice",createItemFunc(UA_DEVICE)],["getEngine",createItemFunc(UA_ENGINE)],["getOS",createItemFunc(UA_OS)],["getResult",createItemFunc(UA_RESULT)],["getUA",function(){return userAgent}],["setUA",function(ua2){return isString(ua2)&&(userAgent=ua2.length>UA_MAX_LENGTH?trim(ua2,UA_MAX_LENGTH):ua2),this}]]).setUA(userAgent),this}UAParser.VERSION=LIBVERSION,UAParser.BROWSER=enumerize([NAME,VERSION,MAJOR,TYPE]),UAParser.CPU=enumerize([ARCHITECTURE]),UAParser.DEVICE=enumerize([MODEL,VENDOR,TYPE,CONSOLE,MOBILE,SMARTTV,TABLET,WEARABLE,EMBEDDED]),UAParser.ENGINE=UAParser.OS=enumerize([NAME,VERSION]);class Recorder{constructor(window2,publicToken,userSettings={}){this.window=window2,this.publicToken=publicToken;const defaultSettings={maskingLevel:"all",consoleRecording:{enabled:!1},networkRecording:{enabled:!1,maxRequestBodySize:10*1024,maxResponseBodySize:50*1024,excludeDomains:[],captureHeaders:!0,captureRequestBodies:!0,captureResponseBodies:!0,excludeHeaders:[]}};this.recorderSettings={...defaultSettings,...userSettings,consoleRecording:{...defaultSettings.consoleRecording,...userSettings.consoleRecording||{}},networkRecording:{...defaultSettings.networkRecording,...userSettings.networkRecording||{}}},this.sessionRecorder=new SessionRecorder(this.recorderSettings),this.eventRecorder=new EventRecorder(window2,this.recorderSettings),this.errorRecorder=new ErrorRecorder(window2,this.recorderSettings.consoleRecording),this.networkRecorder=new NetworkRecorder(window2,this.recorderSettings.networkRecording),post("public/captured-sessions",{publicToken},{withCredentials:!1}).then(response=>{const id=response.data;this.capturedSessionId=id,this.sessionRecorder.setCapturedSessionId(id),this.eventRecorder.setCapturedSessionId(id),this.errorRecorder.setCapturedSessionId(id),this.networkRecorder.setCapturedSessionId(id),this.schedulePing();const capturedUserMetadata=this.collectCapturedUserMetadata();post(`public/captured-sessions/${this.capturedSessionId}/captured-session/metadata`,capturedUserMetadata,{withCredentials:!1}),this.sendUserIdentification(this.capturedSessionId,this.userIdentity)}).catch(error=>{console.error(error),this.sessionRecorder.stop(),this.eventRecorder.stop(),this.errorRecorder.stop(),this.networkRecorder.stop()})}sessionRecorder;eventRecorder;errorRecorder;networkRecorder;recorderSettings;capturedSessionId=null;pingIntervalMs=2e4;pingTimeout=null;userIdentity=null;schedulePing(){this.pingTimeout&&clearTimeout(this.pingTimeout),this.pingTimeout=setTimeout(this.ping,this.pingIntervalMs)}ping=async()=>{await put(`public/captured-sessions/${this.capturedSessionId}/ping`,{},{withCredentials:!1}),this.schedulePing()};start(){this.sessionRecorder.start(),this.eventRecorder.start(),this.errorRecorder.start(),this.networkRecorder.start()}stop(){this.sessionRecorder.stop(),this.eventRecorder.stop(),this.errorRecorder.stop(),this.networkRecorder.stop()}identify(userId){if(!userId||userId.trim()===""){console.error("Recorder.identify: userId must be a non-empty string");return}this.userIdentity={userId:userId.trim()},this.sendUserIdentification(this.capturedSessionId,this.userIdentity)}clearUserIdentity(){this.userIdentity=null}async sendUserIdentification(capturedSessionId,userIdentity){if(!(!capturedSessionId||!userIdentity))try{const response=await patch(`public/captured-sessions/${capturedSessionId}/identify`,userIdentity.userId,{withCredentials:!1});response.status>=400&&console.error(`Failed to identify user: HTTP ${response.status}`,response.data)}catch(error){console.error("Error sending user identification:",error)}}collectCapturedUserMetadata=()=>{const ua=new UAParser,browserName=ua.getBrowser().name,browserVersion=ua.getBrowser().version,osName=ua.getOS().name,osVersion=ua.getOS().version,deviceType=ua.getDevice().type??"desktop",browserLanguage=navigator.language,browserTimeZone=Intl.DateTimeFormat().resolvedOptions().timeZone,referringUrl=document.referrer||void 0;let referringDomain;try{referringDomain=referringUrl?new URL(referringUrl).hostname:void 0}catch{}const viewportWidth=window.innerWidth||document.documentElement.clientWidth,viewportHeight=window.innerHeight||document.documentElement.clientHeight,url=new URL(window.location.href),host=window.location.hostname,utmSource=url.searchParams.get("utm_source")||url.searchParams.get("source")||url.searchParams.get("ref")||void 0,utmMedium=url.searchParams.get("utm_medium")||url.searchParams.get("medium")||void 0,utmCampaign=url.searchParams.get("utm_campaign")||url.searchParams.get("campaign")||void 0,utmContent=url.searchParams.get("utm_content")||url.searchParams.get("content")||void 0,utmTerm=url.searchParams.get("utm_term")||url.searchParams.get("term")||void 0;return{browserName,browserVersion,osName,osVersion,deviceType,browserLanguage,browserTimeZone,referringUrl,referringDomain,viewportWidth,viewportHeight,host,utmSource,utmMedium,utmCampaign,utmContent,utmTerm}}}return exports.NetworkRecorder=NetworkRecorder,exports.Recorder=Recorder,Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),exports}({});
12
12
  //# sourceMappingURL=recorder.iife.js.map