@mearl/native-host 2.9.6 â 2.10.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/dist/index.js +343 -48
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -425,7 +425,7 @@ setprop persist.wy.pm_lock.trigger {timestamp}`,MOBILE_COMMAND_TEMPLATES={resolu
|
|
|
425
425
|
`),timestamp=Math.floor(Date.now()/1e3).toString(),command=replaceTemplatePlaceholders(template,{package_list:packageList,timestamp}),description=`Uninstall blacklist configuration (${packageNames.length} packages)`;return await this.executeCommand(command,description)}catch(error48){return{success:!1,requestId:"",errorMessage:`Failed to set uninstall blacklist: ${error48 instanceof Error?error48.message:String(error48)}`}}}async executeCommand(command,description){try{log(`Executing ${description}`);let result=await this.session.command.executeCommand(command,1e4);if(result&&result.success)return log(`â
${description} completed successfully`),result.output&&log(`Command output: ${result.output}`),{success:!0,requestId:result.requestId||"",errorMessage:""};{let errorMessage2=result?.errorMessage||`Failed to execute ${description}`;return logError(`Failed to execute ${description}: ${errorMessage2}`),{success:!1,requestId:result?.requestId||"",errorMessage:errorMessage2}}}catch(error48){let errorMsg=`Failed to execute ${description}: ${error48 instanceof Error?error48.message:String(error48)}`;return logError(errorMsg),{success:!1,requestId:"",errorMessage:errorMsg}}}};__name(_Mobile,"Mobile");Mobile=_Mobile;init_esm_shims();init_esm_shims();_Oss=class{constructor(session){this.session=session}sanitizeError(error48){return error48&&String(error48).replace(/Bearer\s+[^\s]+/g,"Bearer [REDACTED]")}async envInit(accessKeyId,accessKeySecret,securityToken,endpoint,region){try{let args={access_key_id:accessKeyId,access_key_secret:accessKeySecret,security_token:securityToken,endpoint:endpoint||"",region:region||""},result=await this.session.callMcpTool("oss_env_init",args,!1);if(result.success)if(result.data){let clientConfigRaw=result.data;return typeof clientConfigRaw=="string"&&clientConfigRaw.toLowerCase().includes("failed")?{requestId:result.requestId,success:!1,clientConfig:"",errorMessage:`OSS environment initialization failed: ${clientConfigRaw}`}:{requestId:result.requestId,success:!0,clientConfig:clientConfigRaw,errorMessage:""}}else return{requestId:result.requestId,success:!1,clientConfig:"",errorMessage:"Failed to initialize OSS environment"};else return{requestId:result.requestId,success:!1,clientConfig:"",errorMessage:result.errorMessage||"Failed to initialize OSS environment"}}catch(error48){return{requestId:"",success:!1,clientConfig:"",errorMessage:`Failed to initialize OSS environment: ${error48}`}}}async upload(bucket,object2,path52){try{let args={bucket,object:object2,path:path52},result=await this.session.callMcpTool("oss_upload",args,!1);return{requestId:result.requestId,success:result.success,content:result.data,errorMessage:result.errorMessage}}catch(error48){return{requestId:"",success:!1,content:"",errorMessage:`Failed to upload file: ${error48}`}}}async uploadAnonymous(url2,path52){try{let args={url:url2,path:path52},result=await this.session.callMcpTool("oss_upload_annon",args,!1);return{requestId:result.requestId,success:result.success,content:result.data,errorMessage:result.errorMessage}}catch(error48){return{requestId:"",success:!1,content:"",errorMessage:`Failed to upload file anonymously: ${error48}`}}}async download(bucket,object2,path52){try{let args={bucket,object:object2,path:path52},result=await this.session.callMcpTool("oss_download",args,!1);return{requestId:result.requestId,success:result.success,content:result.data,errorMessage:result.errorMessage}}catch(error48){return{requestId:"",success:!1,content:"",errorMessage:`Failed to download file: ${error48}`}}}async downloadAnonymous(url2,path52){try{let args={url:url2,path:path52},result=await this.session.callMcpTool("oss_download_annon",args,!1);return{requestId:result.requestId,success:result.success,content:result.data,errorMessage:result.errorMessage}}catch(error48){return{requestId:"",success:!1,content:"",errorMessage:`Failed to download file anonymously: ${error48}`}}}};__name(_Oss,"Oss");Oss=_Oss;init_esm_shims();init_esm_shims();PTY_TARGET="PTY_SERVER",DEFAULT_ENVS={TERM:"xterm-256color",LANG:"en_US.UTF-8"},MAX_TERMINAL_SIZE=500,_PtyError=class extends(Error.default||Error){constructor(message="PTY operation error"){super(message),this.name="PtyError"}};__name(_PtyError,"PtyError");PtyError=_PtyError,_PtyNotConnectedError=class extends(PtyError.default||PtyError){constructor(message="PTY handle is not connected"){super(message),this.name="PtyNotConnectedError"}};__name(_PtyNotConnectedError,"PtyNotConnectedError");PtyNotConnectedError=_PtyNotConnectedError,_PtyHandle=class{constructor(ptySessionId,ptyModule,onData){this._connected=!0,this._exitCode=void 0,this._errorMsg=void 0,this._ptySessionId=ptySessionId,this._ptyModule=ptyModule,this._onData=onData}get ptySessionId(){return this._ptySessionId}get isConnected(){return this._connected}get exitCode(){return this._exitCode}async sendInput(data){if(!this._connected)throw new PtyNotConnectedError;let text,encoding;try{text=new TextDecoder("utf-8",{fatal:!0}).decode(data),encoding="utf8"}catch{text=Buffer.from(data).toString("base64"),encoding="base64"}await(await this._ptyModule.getWsClient()).sendMessage(PTY_TARGET,{method:"pty.input",params:{ptySessionId:this._ptySessionId,encoding,data:text}})}async resize(cols,rows){if(!this._connected)throw new PtyNotConnectedError;if(cols<1||cols>MAX_TERMINAL_SIZE||rows<1||rows>MAX_TERMINAL_SIZE)throw new PtyError(`Invalid terminal size: cols=${cols}, rows=${rows} (must be 1-${MAX_TERMINAL_SIZE})`);await(await this._ptyModule.getWsClient()).sendMessage(PTY_TARGET,{method:"pty.resize",params:{ptySessionId:this._ptySessionId,cols,rows}})}async kill(){if(!this._connected)throw new PtyNotConnectedError;await(await this._ptyModule.getWsClient()).call(PTY_TARGET,{method:"pty.kill",params:{ptySessionId:this._ptySessionId}})}async wait(timeoutMs){let deadline=timeoutMs?Date.now()+timeoutMs:void 0;for(;this._exitCode===void 0&&this._errorMsg===void 0;){if(deadline!==void 0&&Date.now()>=deadline)throw new PtyError(`PTY wait timed out after ${timeoutMs}ms`);await new Promise(r=>setTimeout(r,100))}if(this._errorMsg!==void 0)throw new PtyError(this._errorMsg);return this._exitCode}disconnect(){this._connected&&(this._connected=!1,this._ptyModule.unregisterHandle(this._ptySessionId))}_handleOutput(dataBytes){if(this._onData)try{this._onData(dataBytes)}catch(e){console.error("on_data callback raised an exception",e)}}_handleExit(exitCode){this._exitCode=exitCode,this._connected=!1}_handleError(errorMsg){this._errorMsg=errorMsg,this._connected=!1}};__name(_PtyHandle,"PtyHandle");PtyHandle=_PtyHandle,_Pty=class{constructor(session){this.wsClient=null,this.handles=new Map,this.callbackRegistered=!1,this.session=session}async getWsClient(){return this.wsClient||(this.wsClient=await this.session.getWsClient()),this.wsClient}async ensureCallback(){if(this.callbackRegistered)return;let wsClient=await this.getWsClient();await wsClient.connect(),wsClient.registerCallback(PTY_TARGET,payload=>{this.pushCallback(payload)}),this.callbackRegistered=!0}pushCallback(payload){let data=payload.data??{},eventType=data.eventType??"",ptySessionId=data.ptySessionId??"";if(eventType==="pty.output"){let handle=this.handles.get(ptySessionId);if(!handle)return;let encoding=data.encoding??"utf8",raw=data.data??"",dataBytes;encoding==="base64"?dataBytes=Buffer.from(raw,"base64"):dataBytes=typeof raw=="string"?new TextEncoder().encode(raw):new Uint8Array(raw),handle._handleOutput(dataBytes)}else if(eventType==="pty.exit"){let handle=this.handles.get(ptySessionId);if(!handle)return;let exitCode=typeof data.exitCode=="number"?data.exitCode:-1;handle._handleExit(exitCode)}else if(eventType==="pty.error"){let handle=this.handles.get(ptySessionId);if(!handle)return;let errorMsg=typeof data.error=="string"?data.error:"Unknown PTY error";handle._handleError(errorMsg)}}unregisterHandle(ptySessionId){this.handles.delete(ptySessionId)}async create(options={}){let cols=options.cols??80,rows=options.rows??24;if(cols<1||cols>MAX_TERMINAL_SIZE||rows<1||rows>MAX_TERMINAL_SIZE)throw new PtyError(`Invalid terminal size: cols=${cols}, rows=${rows} (must be 1-${MAX_TERMINAL_SIZE})`);await this.ensureCallback();let wsClient=await this.getWsClient(),params={cols,rows};options.cwd!==void 0&&(params.cwd=options.cwd);let mergedEnvs={...DEFAULT_ENVS,...options.envs??{}};params.envs=mergedEnvs,options.shell!==void 0&&(params.shell=options.shell);let timeoutMs=options.timeoutMs??3e4,response=await wsClient.call(PTY_TARGET,{method:"pty.create",params},timeoutMs),ptySessionId=(response.result??{}).ptySessionId;if(!ptySessionId)throw new PtyError(`pty.create did not return ptySessionId: ${JSON.stringify(response)}`);let handle=new PtyHandle(ptySessionId,this,options.onData);return this.handles.set(ptySessionId,handle),handle}async list(){await this.ensureCallback();let ptySessionIds=((await(await this.getWsClient()).call(PTY_TARGET,{method:"pty.list",params:{}})).result??{}).ptySessionIds??[],sessions=[];for(let sid of ptySessionIds){let handle=this.handles.get(sid),status="running",exitCode;handle&&handle.exitCode!==void 0&&(status="exited",exitCode=handle.exitCode),sessions.push({ptySessionId:sid,cols:0,rows:0,status,exitCode})}return sessions}async connect(ptySessionId,onData){await this.ensureCallback();let returnedId=((await(await this.getWsClient()).call(PTY_TARGET,{method:"pty.connect",params:{ptySessionId}})).result??{}).ptySessionId||ptySessionId,handle=new PtyHandle(returnedId,this,onData);return this.handles.set(returnedId,handle),handle}async kill(ptySessionId){await this.ensureCallback(),await(await this.getWsClient()).call(PTY_TARGET,{method:"pty.kill",params:{ptySessionId}});let handle=this.handles.get(ptySessionId);handle&&(handle._connected=!1,this.handles.delete(ptySessionId))}};__name(_Pty,"Pty");Pty=_Pty;__name(fetchCompat,"fetchCompat");_SessionInfoClass=class{constructor(sessionId="",resourceUrl="",appId="",authCode="",connectionProperties="",resourceId="",resourceType="",ticket=""){this.sessionId=sessionId,this.resourceUrl=resourceUrl,this.appId=appId,this.authCode=authCode,this.connectionProperties=connectionProperties,this.resourceId=resourceId,this.resourceType=resourceType,this.ticket=ticket}};__name(_SessionInfoClass,"SessionInfoClass");SessionInfoClass=_SessionInfoClass,_Session=class{constructor(agentBay,sessionId){this.resourceUrl="",this.appInstanceId="",this.vpcIp="",this.vpcId="",this.token="",this.linkUrl="",this.wsUrl="",this._wsClient=null,this.mcpTools=[],this.agentBay=agentBay,this.sessionId=sessionId,this.fileSystem=new FileSystem(this),this.command=new Command(this),this.env=new Env(this),this.code=new Code(this),this.oss=new Oss(this),this.computer=new Computer(this),this.mobile=new Mobile(this),this.agent=new Agent(this),this.browser=new Browser(this),this.git=new Git(this),this.context=newContextManager(this),this.pty=new Pty(this)}async getWsClient(){if(!this.wsUrl)throw new Error("Missing wsUrl on session; streaming is not available");if(!this.token)throw new Error("Missing token on session; streaming is not available");return this._wsClient||(this._wsClient=new WsClient(this.wsUrl,this.token)),await this._wsClient.connect(),this._wsClient}get fs(){return this.fileSystem}get filesystem(){return this.fileSystem}get files(){return this.fileSystem}getAgentBay(){return this.agentBay}getAPIKey(){return this.agentBay.getAPIKey()}getToken(){return this.token}getLinkUrl(){return this.linkUrl}getClient(){return this.agentBay.getClient()}getSessionId(){return this.sessionId}async getStatus(){try{logAPICall("GetSessionDetail",{sessionId:this.sessionId});let request=new GetSessionDetailRequest({authorization:`Bearer ${this.getAPIKey()}`,sessionId:this.sessionId}),response=await this.getClient().getSessionDetail(request),body=response.body,requestId=extractRequestId(response)||body?.requestId||"";if(setRequestId(requestId),body?.success===!1&&body.code)return logAPIResponseWithDetails("GetSessionDetail",requestId,!1,{},`[${body.code}] ${body.message||"Unknown error"}`),logDebug("Full GetSessionDetail response:",JSON.stringify(body,null,2)),{requestId,httpStatusCode:body.httpStatusCode||0,code:body.code,success:!1,status:"",errorMessage:`[${body.code}] ${body.message||"Unknown error"}`};let result={requestId,httpStatusCode:body?.httpStatusCode||0,code:body?.code||"",success:body?.success||!1,status:body?.data?.status||"",errorMessage:""};return logAPIResponseWithDetails("GetSessionDetail",requestId,!0,{status:result.status}),result}catch(error48){let errorStr=String(error48);return(error48?.data?.Code||error48?.code||"")==="InvalidMcpSession.NotFound"||errorStr.includes("NotFound")?(logInfoWithColor(`Session not found: ${this.sessionId}`),logDebug(`GetSessionDetail error details: ${errorStr}`),{requestId:"",httpStatusCode:400,code:"InvalidMcpSession.NotFound",success:!1,status:"",errorMessage:`Session ${this.sessionId} not found`}):(logError("Error calling GetSessionDetail:",error48),{requestId:"",httpStatusCode:0,code:"",success:!1,status:"",errorMessage:`Failed to get session detail ${this.sessionId}: ${error48}`})}}async keepAlive(){try{logAPICall("RefreshSessionIdleTime",{sessionId:this.sessionId});let request=new RefreshSessionIdleTimeRequest({authorization:`Bearer ${this.getAPIKey()}`,sessionId:this.sessionId}),response=await this.getClient().refreshSessionIdleTime(request),requestId=extractRequestId(response)||response?.body?.requestId||"",body=response?.body;if(body?.success===!1&&body.code){let errorMessage2=`[${body.code}] ${body.message||"Unknown error"}`;return logAPIResponseWithDetails("RefreshSessionIdleTime",requestId,!1,{},JSON.stringify(body,null,2)),{requestId,success:!1,errorMessage:errorMessage2}}return logAPIResponseWithDetails("RefreshSessionIdleTime",requestId,!0,{session_id:this.sessionId}),{requestId,success:!0}}catch(error48){return logError("Error calling RefreshSessionIdleTime:",error48),{requestId:"",success:!1,errorMessage:`Failed to keep session alive ${this.sessionId}: ${error48}`}}}async keepAliveAsync(){return await this.keepAlive()}async delete(syncContext=!1){try{if(this._wsClient){try{await this._wsClient.close()}catch{}this._wsClient=null}if(syncContext){logDebug("Triggering context synchronization before session deletion...");let syncStartTime=Date.now();try{let syncResult=await this.context.sync();logInfo("đ Synced all contexts");let syncDuration=Date.now()-syncStartTime;syncResult.success?logInfo(`Context sync completed in ${syncDuration}ms`):logInfo(`Context sync completed with failures after ${syncDuration}ms`)}catch(error48){let syncDuration=Date.now()-syncStartTime;logError(`Failed to trigger context sync after ${syncDuration}ms:`,error48)}}let request=new DeleteSessionAsyncRequest({authorization:`Bearer ${this.getAPIKey()}`,sessionId:this.sessionId}),response=await this.getClient().deleteSessionAsync(request);logDebug(`Response from delete_session_async: ${JSON.stringify(response)}`);let requestId=extractRequestId(response)||"",responseBody=response.body;if(!(responseBody?.success!==!1)){let errorMessage2=`[${responseBody?.code||"Unknown"}] ${responseBody?.message||"Failed to delete session"}`;return logAPIResponseWithDetails("DeleteSessionAsync",requestId,!1,{},JSON.stringify(responseBody,null,2)),{requestId,success:!1,errorMessage:errorMessage2}}logInfo(`đ Waiting for session ${this.sessionId} to be deleted...`);let pollTimeout=3e5,pollInterval=1e3,pollStartTime=Date.now();for(;;){if(Date.now()-pollStartTime>=pollTimeout){let errorMessage2=`Timeout waiting for session deletion after ${pollTimeout}ms`;return logWarn(`âąī¸ ${errorMessage2}`),{requestId,success:!1,errorMessage:errorMessage2}}let sessionResult=await this.getStatus();if(sessionResult.success){if(sessionResult.status){let status=sessionResult.status;if(logDebug(`đ Session status: ${status}`),status==="FINISH"){logInfo(`â
Session ${this.sessionId} successfully deleted`);break}}}else{let errorCode=sessionResult.code||"",errorMessage2=sessionResult.errorMessage||"",httpStatusCode=sessionResult.httpStatusCode||0;if(errorCode==="InvalidMcpSession.NotFound"||httpStatusCode===400&&(errorMessage2.toLowerCase().includes("not found")||errorMessage2.includes("NotFound")||errorCode.toLowerCase().includes("not found"))||errorMessage2.toLowerCase().includes("not found")){logInfo(`â
Session ${this.sessionId} successfully deleted (NotFound)`);break}else logDebug(`â ī¸ Get session error (will retry): ${errorMessage2}`)}await new Promise(resolve22=>setTimeout(resolve22,pollInterval))}return logAPIResponseWithDetails("DeleteSessionAsync",requestId,!0,{sessionId:this.sessionId}),{requestId,success:!0}}catch(error48){return logError("Error calling delete_session_async:",error48),{requestId:"",success:!1,errorMessage:`Failed to delete session ${this.sessionId}: ${error48}`}}}validateLabels(labels){if(!labels||typeof labels!="object")return{requestId:"",success:!1,errorMessage:"Labels cannot be null, undefined, or invalid type. Please provide a valid labels object."};if(Array.isArray(labels))return{requestId:"",success:!1,errorMessage:"Labels cannot be an array. Please provide a valid labels object."};if(labels instanceof Date||labels instanceof RegExp||labels instanceof Error||labels instanceof Map||labels instanceof Set||labels instanceof WeakMap||labels instanceof WeakSet||labels instanceof Promise)return{requestId:"",success:!1,errorMessage:"Labels must be a plain object. Built-in object types are not allowed."};if(Object.keys(labels).length===0)return{requestId:"",success:!1,errorMessage:"Labels cannot be empty. Please provide at least one label."};for(let[key,value]of Object.entries(labels)){if(!key||key.trim()==="")return{requestId:"",success:!1,errorMessage:"Label keys cannot be empty Please provide valid keys."};if(!value||value.trim()==="")return{requestId:"",success:!1,errorMessage:"Label values cannot be empty Please provide valid values."}}return null}async setLabels(labels){try{let validationResult=this.validateLabels(labels);if(validationResult!==null)return validationResult;let labelsJSON=JSON.stringify(labels),request=new SetLabelRequest({authorization:`Bearer ${this.getAPIKey()}`,sessionId:this.sessionId,labels:labelsJSON}),response=await this.getClient().setLabel(request);return{requestId:extractRequestId(response)||"",success:!0}}catch(error48){throw logError("Error calling set_label:",error48),new Error(`Failed to set labels for session ${this.sessionId}: ${error48}`)}}async getLabels(){try{let request=new GetLabelRequest({authorization:`Bearer ${this.getAPIKey()}`,sessionId:this.sessionId}),response=await this.getClient().getLabel(request),requestId=extractRequestId(response)||"",labelsJSON=response?.body?.data?.labels,labels={};return labelsJSON&&(labels=JSON.parse(labelsJSON)),{requestId,success:!0,data:labels}}catch(error48){throw logError("Error calling get_label:",error48),new Error(`Failed to get labels for session ${this.sessionId}: ${error48}`)}}async info(){try{let request=new GetMcpResourceRequest({authorization:`Bearer ${this.getAPIKey()}`,sessionId:this.sessionId});logAPICall("GetMcpResource"),logDebug(`Request: SessionId=${this.sessionId}`);let response=await this.getClient().getMcpResource(request),requestId=extractRequestId(response)||"";if(response?.body?.success===!1&&response.body?.code){let errorMessage2=`[${response.body.code}] ${response.body.message||"Unknown error"}`,fullResponse2=response.body?JSON.stringify(response.body,null,2):"";return logAPIResponseWithDetails("GetMcpResource",requestId,!1,void 0,fullResponse2),{requestId,success:!1,errorMessage:errorMessage2}}let responseBody=response.body,data=responseBody?.data,sessionInfo=new SessionInfoClass;if(data?.sessionId&&(sessionInfo.sessionId=data.sessionId),data?.resourceUrl&&(sessionInfo.resourceUrl=data.resourceUrl),data?.desktopInfo){let desktopInfo=data.desktopInfo;desktopInfo.appId&&(sessionInfo.appId=desktopInfo.appId),desktopInfo.authCode&&(sessionInfo.authCode=desktopInfo.authCode),desktopInfo.connectionProperties&&(sessionInfo.connectionProperties=desktopInfo.connectionProperties),desktopInfo.resourceId&&(sessionInfo.resourceId=desktopInfo.resourceId),desktopInfo.resourceType&&(sessionInfo.resourceType=desktopInfo.resourceType),desktopInfo.ticket&&(sessionInfo.ticket=desktopInfo.ticket)}let keyFields={session_id:this.sessionId};sessionInfo.resourceUrl&&(keyFields.resource_url=sessionInfo.resourceUrl),sessionInfo.appId&&(keyFields.app_id=sessionInfo.appId);let fullResponse=responseBody?JSON.stringify(responseBody,null,2):"";return logAPIResponseWithDetails("GetMcpResource",requestId,!0,keyFields,fullResponse),{requestId,success:!0,data:sessionInfo}}catch(error48){let errorStr=String(error48);if((error48?.data?.Code||error48?.code||"")==="InvalidMcpSession.NotFound"||errorStr.includes("NotFound"))return logInfoWithColor(`Session not found: ${this.sessionId}`),logDebug(`GetMcpResource error details: ${errorStr}`),{requestId:"",success:!1,errorMessage:`Session ${this.sessionId} not found`};throw logError(`â Failed to get session info for session ${this.sessionId}`,error48),new Error(`Failed to get session info for session ${this.sessionId}: ${error48}`)}}async getLink(protocolType,port,options){try{let requestParams=`SessionId=${this.getSessionId()}, ProtocolType=${protocolType||"default"}, Port=${port||"default"}`;options&&(requestParams+=", Options=provided"),logAPICall("GetLink",requestParams);let request=new GetLinkRequest({authorization:`Bearer ${this.getAPIKey()}`,sessionId:this.getSessionId(),protocolType,port,option:options}),response=await this.agentBay.getClient().getLink(request),requestId=extractRequestId(response)||"",responseBody=response.body;if(typeof responseBody!="object")throw new Error("Invalid response format: expected a dictionary from response body");let data=responseBody.data||{};if(logDebug(`Data: ${JSON.stringify(data)}`),typeof data!="object")try{data=typeof data=="string"?JSON.parse(data):{}}catch{data={}}let url2=data.Url||data.url,keyFields={};return url2&&(keyFields.url=url2),logAPIResponseWithDetails("GetLink",requestId,!0,keyFields),{requestId,success:!0,data:url2}}catch(error48){throw error48 instanceof Error&&error48.message.includes("Invalid response format")?error48:new Error(`Failed to get link: ${error48}`)}}async getLinkAsync(protocolType,port,options){try{let requestParams=`SessionId=${this.getSessionId()}, ProtocolType=${protocolType||"default"}, Port=${port||"default"}`;options&&(requestParams+=", Options=provided"),logAPICall("GetLink",requestParams);let request=new GetLinkRequest({authorization:`Bearer ${this.getAPIKey()}`,sessionId:this.getSessionId(),protocolType,port,option:options}),response=await this.agentBay.getClient().getLink(request),requestId=extractRequestId(response)||"",responseBody=response?.body;if(typeof responseBody!="object")throw new Error("Invalid response format: expected a dictionary from response body");let data=responseBody?.data||{};if(logDebug(`Data: ${JSON.stringify(data)}`),typeof data!="object")try{data=typeof data=="string"?JSON.parse(data):{}}catch{data={}}let url2=data.Url||data.url,keyFields={};return url2&&(keyFields.url=url2),logAPIResponseWithDetails("GetLink",requestId,!0,keyFields),{requestId,success:!0,data:url2}}catch(error48){throw error48 instanceof Error&&error48.message.includes("Invalid response format")?error48:new Error(`Failed to get link asynchronously: ${error48}`)}}async listMcpTools(imageId){imageId||(imageId=this.imageId||"linux_latest");let request=new ListMcpToolsRequest({authorization:`Bearer ${this.getAPIKey()}`,imageId});logAPICall("ListMcpTools"),logDebug(`Request: ImageId=${imageId}`);let response=await this.getClient().listMcpTools(request),requestId=extractRequestId(response)||"";if(response?.body?.success===!1&&response.body?.code){let errorMessage2=`[${response.body.code}] ${response.body.message||"Unknown error"}`,fullResponse2=response.body?JSON.stringify(response.body,null,2):"";return logAPIResponseWithDetails("ListMcpTools",requestId,!1,void 0,fullResponse2),{requestId,success:!1,tools:[],errorMessage:errorMessage2}}let tools=[];if(response&&response.body&&response.body.data)try{let toolsData=JSON.parse(response.body.data);for(let toolData of toolsData){let tool={name:toolData.name||"",description:toolData.description||"",inputSchema:toolData.inputSchema||{},server:toolData.server||"",tool:toolData.tool||""};tools.push(tool)}}catch(error48){logError(`Error unmarshaling tools data: ${error48}`)}let keyFields={image_id:imageId,tool_count:tools.length},fullResponse=response.body?JSON.stringify(response.body,null,2):"";return logAPIResponseWithDetails("ListMcpTools",requestId,!0,keyFields,fullResponse),{requestId,success:!0,tools}}getMcpServerForTool(toolName){for(let tool of this.mcpTools||[])if(tool&&tool.name===toolName)return tool.server||null;return null}async callMcpTool(toolName,args,autoGenSession=!1){try{if(toolName==="press_keys"&&args&&Array.isArray(args.keys)){let{normalizeKeys:normalizeKeys2}=await Promise.resolve().then(()=>(init_key_normalizer_HEE7M4FS(),key_normalizer_HEE7M4FS_exports));args={...args},args.keys=normalizeKeys2(args.keys),logDebug(`Normalized press_keys arguments: ${JSON.stringify(args)}`)}let serverName=this.getMcpServerForTool(toolName)||"",argsJSON=JSON.stringify(args);if(this.getLinkUrl()&&this.getToken()&&serverName)return await this.callMcpToolLinkUrl(toolName,args,serverName);let callToolRequest=new CallMcpToolRequest({authorization:`Bearer ${this.getAPIKey()}`,sessionId:this.getSessionId(),name:toolName,args:argsJSON,autoGenSession,server:serverName}),response=await this.getClient().callMcpTool(callToolRequest);if(!response.body?.data)return{success:!1,data:"",errorMessage:"Invalid response data format",requestId:extractRequestId(response)||""};if(response.body.success===!1&&response.body.code)return{success:!1,data:"",errorMessage:`[${response.body.code}] ${response.body.message||"Unknown error"}`,requestId:extractRequestId(response)||""};let data=response.body.data,reqId=extractRequestId(response)||"";if(reqId&&setRequestId(reqId),toolName==="run_code"){let dataStr="";data&&Array.isArray(data.content)&&data.content.length>0&&data.content[0].text?dataStr=data.content[0].text:dataStr=typeof response.body.data=="string"?response.body.data:JSON.stringify(response.body.data),logCodeExecutionOutput(reqId,dataStr);let isError=data.isError===!0;return{success:!isError,data:dataStr,errorMessage:isError?dataStr:"",requestId:reqId}}if(data.isError)return{success:!1,data:"",errorMessage:(data.content||[]).map(item=>item.text||"Unknown error").join("; "),requestId:reqId};let content=data.content||[],textContent="";if(content.length>0){let c0=content[0]||{};typeof c0.text=="string"&&c0.text?textContent=c0.text:typeof c0.blob=="string"&&c0.blob?textContent=c0.blob:typeof c0.data=="string"&&c0.data&&(textContent=c0.data)}return{success:!0,data:textContent||JSON.stringify(data),errorMessage:"",requestId:reqId}}catch(error48){return{success:!1,data:"",errorMessage:error48 instanceof Error?error48.message:String(error48),requestId:""}}}async callMcpToolLinkUrl(toolName,args,serverName){if(!serverName)return{success:!1,data:"",errorMessage:`Server name is required for LinkUrl tool call: ${toolName}`,requestId:""};let linkUrl=this.getLinkUrl(),token=this.getToken();if(!linkUrl||!token)return{success:!1,data:"",errorMessage:"LinkUrl/token not available",requestId:""};let requestId=`link-${Date.now()}-${Math.floor(Math.random()*1e9).toString().padStart(9,"0")}`;logAPICall("CallMcpTool(LinkUrl)",`Tool=${toolName}, ArgsLength=${JSON.stringify(args).length}, RequestId=${requestId}`);let url2=`${linkUrl.replace(/\/+$/,"")}/callTool`,resp=await fetchCompat(url2,{method:"POST",headers:{"Content-Type":"application/json","X-Access-Token":token},body:JSON.stringify({args,server:serverName,requestId,tool:toolName,token})},9e5);if(!resp.ok){let bodyText=await resp.text().catch(()=>"");return logAPIResponseWithDetails("CallMcpTool(LinkUrl) Response",requestId,!1,{http_status:resp.status,tool_name:toolName},bodyText),{success:!1,data:"",errorMessage:`HTTP request failed with code: ${resp.status}`,requestId}}let dataField=(await resp.json())?.data,parsedData=dataField;typeof dataField=="string"&&(parsedData=JSON.parse(dataField));let resultField=parsedData?.result,isError=resultField?.isError===!0,first=(Array.isArray(resultField?.content)?resultField.content:[])[0]??{},textContent=typeof first=="string"?first:first.text??first.blob??first.data??"";if(logAPIResponseWithDetails("CallMcpTool(LinkUrl) Response",requestId,!isError,{tool_name:toolName,server:serverName,is_error:isError,data_len:String(textContent??"").length},isError?String(textContent??""):""),toolName==="run_code"){let dataStr=typeof textContent=="string"?textContent:JSON.stringify(textContent);return logCodeExecutionOutput(requestId,dataStr),{success:!isError,data:dataStr,errorMessage:isError?dataStr:"",requestId}}return{success:!isError,data:String(textContent??""),errorMessage:isError?String(textContent??""):"",requestId}}async getMetrics(){let toolResult=await this.callMcpTool("get_metrics",{},!1),requestId=toolResult.requestId||"";if(!toolResult.success)return{requestId,success:!1,data:void 0,raw:void 0,errorMessage:toolResult.errorMessage||""};try{let raw=typeof toolResult.data=="string"?JSON.parse(toolResult.data):toolResult.data;if(!raw||typeof raw!="object"||Array.isArray(raw))throw new Error("get_metrics returned non-object JSON");let metrics={cpuCount:Number(raw.cpu_count??0),cpuUsedPct:Number(raw.cpu_used_pct??0),diskTotal:Number(raw.disk_total??0),diskUsed:Number(raw.disk_used??0),memTotal:Number(raw.mem_total??0),memUsed:Number(raw.mem_used??0),rxRateKbytePerS:Number(raw.rx_rate_kbyte_per_s??raw.rx_rate_kbps??raw.rx_rate_KBps??0),txRateKbytePerS:Number(raw.tx_rate_kbyte_per_s??raw.tx_rate_kbps??raw.tx_rate_KBps??0),rxUsedKbyte:Number(raw.rx_used_kbyte??raw.rx_used_kb??raw.rx_used_KB??0),txUsedKbyte:Number(raw.tx_used_kbyte??raw.tx_used_kb??raw.tx_used_KB??0),timestamp:String(raw.timestamp??"")};return{requestId,success:!0,data:metrics,raw,errorMessage:""}}catch(err){return{requestId,success:!1,data:void 0,raw:void 0,errorMessage:`Failed to parse get_metrics response: ${err?.message||String(err)}`}}}async betaPauseAsync(timeout=600,pollInterval=2){try{let request=new PauseSessionAsyncRequest({authorization:`Bearer ${this.getAPIKey()}`,sessionId:this.sessionId});logAPICall("PauseSessionAsync",`SessionId=${this.sessionId}`);let response=await this.getClient().pauseSessionAsync(request),requestId=extractRequestId(response)||"";setRequestId(requestId);let responseMap=response.to_map?response.to_map():response;if(!responseMap)return{requestId:requestId||"",success:!1,errorMessage:"Invalid response format"};let body=responseMap.body;if(!body)return{requestId:requestId||"",success:!1,errorMessage:"Invalid response body"};let success2=body.success!==!1,code=body.code||"",message=body.message||"",httpStatusCode=body.httpStatusCode||0;if(!success2){let errorMessage2=`[${code}] ${message}`||"Unknown error";return logError("PauseSessionAsync",errorMessage2),{requestId:requestId||"",success:!1,errorMessage:errorMessage2,code,message,httpStatusCode}}logInfo("PauseSessionAsync",`Session ${this.sessionId} pause initiated successfully`);let startTime=Date.now(),maxAttempts=Math.floor(timeout/pollInterval),attempt=0;for(;attempt<maxAttempts;){let getResult=await this.agentBay._getSession(this.sessionId);if(!getResult.success)return logError(`Failed to get session status: ${getResult.errorMessage}`),{requestId:getResult.requestId||"",success:!1,errorMessage:`Failed to get session status: ${getResult.errorMessage}`};if(getResult.data){let status=getResult.data.status||"UNKNOWN";if(logDebug(`Session status: ${status} (attempt ${attempt+1}/${maxAttempts})`),status==="PAUSED"){let elapsed2=Date.now()-startTime;return logInfo(`Session paused successfully in ${elapsed2}ms`),{requestId:getResult.requestId||"",success:!0,status}}else if(status!=="PAUSING"){let elapsed2=Date.now()-startTime,errorMessage2=`Session pause failed: unexpected state '${status}' after ${elapsed2}ms`;return logError(errorMessage2),{requestId:getResult.requestId||"",success:!1,errorMessage:errorMessage2,status}}}attempt++,attempt<maxAttempts&&await new Promise(resolve22=>setTimeout(resolve22,pollInterval*1e3))}let errorMsg=`Session pause timed out after ${Date.now()-startTime}ms`;return logError(errorMsg),{requestId:"",success:!1,errorMessage:errorMsg}}catch(error48){return logError("PauseSessionAsync",error48),{requestId:"",success:!1,errorMessage:`Unexpected error pausing session: ${error48}`}}}async betaResumeAsync(timeout=600,pollInterval=2){try{let request=new ResumeSessionAsyncRequest({authorization:`Bearer ${this.getAPIKey()}`,sessionId:this.sessionId});logAPICall("ResumeSessionAsync",`SessionId=${this.sessionId}`);let response=await this.getClient().resumeSessionAsync(request),requestId=extractRequestId(response)||"";setRequestId(requestId);let responseMap=response.to_map?response.to_map():response;if(!responseMap)return{requestId:requestId||"",success:!1,errorMessage:"Invalid response format"};let body=responseMap.body;if(!body)return{requestId:requestId||"",success:!1,errorMessage:"Invalid response body"};let success2=body.success!==!1,code=body.code||"",message=body.message||"",httpStatusCode=body.httpStatusCode||0;if(!success2){let errorMessage2=`[${code}] ${message}`||"Unknown error";return logError("ResumeSessionAsync",errorMessage2),{requestId:requestId||"",success:!1,errorMessage:errorMessage2,code,message,httpStatusCode}}logInfo("ResumeSessionAsync",`Session ${this.sessionId} resume initiated successfully`);let startTime=Date.now(),maxAttempts=Math.floor(timeout/pollInterval),attempt=0;for(;attempt<maxAttempts;){let getResult=await this.agentBay._getSession(this.sessionId);if(!getResult.success)return logError(`Failed to get session status: ${getResult.errorMessage}`),{requestId:getResult.requestId||"",success:!1,errorMessage:`Failed to get session status: ${getResult.errorMessage}`};if(getResult.data){let status=getResult.data.status||"UNKNOWN";if(logDebug(`Session status: ${status} (attempt ${attempt+1}/${maxAttempts})`),status==="RUNNING"){let elapsed2=Date.now()-startTime;return logInfo(`Session resumed successfully in ${elapsed2}ms`),{requestId:getResult.requestId||"",success:!0,status}}else if(status!=="RESUMING"){let elapsed2=Date.now()-startTime,errorMessage2=`Session resume failed: unexpected state '${status}' after ${elapsed2}ms`;return logError(errorMessage2),{requestId:getResult.requestId||"",success:!1,errorMessage:errorMessage2,status}}}attempt++,attempt<maxAttempts&&await new Promise(resolve22=>setTimeout(resolve22,pollInterval*1e3))}let errorMsg=`Session resume timed out after ${Date.now()-startTime}ms`;return logError(errorMsg),{requestId:"",success:!1,errorMessage:errorMsg}}catch(error48){return logError("ResumeSessionAsync",error48),{requestId:"",success:!1,errorMessage:`Unexpected error resuming session: ${error48}`}}}};__name(_Session,"Session");Session=_Session;init_esm_shims();BROWSER_FINGERPRINT_PERSIST_PATH2="/tmp/browser_fingerprint",_BrowserContext=class{constructor(contextId,autoUpload=!0,extensionOption,fingerprintContext,syncMode="standard"){this.contextId=contextId,this.autoUpload=autoUpload,this.syncMode=syncMode,this.extensionOption=extensionOption,this.fingerprintContext=fingerprintContext,fingerprintContext?(this.fingerprintContextId=fingerprintContext.fingerprintContextId,this.fingerprintContextSync=this._createFingerprintContextSync()):(this.fingerprintContextId=void 0,this.fingerprintContextSync=void 0),extensionOption?(this.extensionContextId=extensionOption.contextId,this.extensionIds=extensionOption.extensionIds,this.extensionContextSyncs=this._createExtensionContextSyncs()):(this.extensionContextId=void 0,this.extensionIds=[],this.extensionContextSyncs=void 0)}_createExtensionContextSyncs(){if(!this.extensionIds||this.extensionIds.length===0||!this.extensionContextId)return[];let whiteLists=this.extensionIds.map(extId=>({path:extId,excludePaths:[]})),syncPolicy={uploadPolicy:{...newUploadPolicy(),autoUpload:!1},extractPolicy:{...newExtractPolicy(),extract:!0,deleteSrcFile:!0},deletePolicy:{...newDeletePolicy(),syncLocalFile:!1},recyclePolicy:newRecyclePolicy(),bwList:{whiteLists},downloadPolicy:{autoDownload:!0,downloadStrategy:"DownloadAsync"}};return[new ContextSync(this.extensionContextId,"/tmp/extensions/",syncPolicy)]}_createFingerprintContextSync(){if(!this.fingerprintContextId||!this.fingerprintContextId.trim())return;let syncPolicy={uploadPolicy:{...newUploadPolicy(),autoUpload:!1},extractPolicy:{...newExtractPolicy(),extract:!0,deleteSrcFile:!0},deletePolicy:{...newDeletePolicy(),syncLocalFile:!1},recyclePolicy:newRecyclePolicy(),bwList:{whiteLists:[]}};return new ContextSync(this.fingerprintContextId,BROWSER_FINGERPRINT_PERSIST_PATH2,syncPolicy)}getExtensionContextSyncs(){return this.extensionContextSyncs||[]}getFingerprintContextSync(){return this.fingerprintContextSync}};__name(_BrowserContext,"BrowserContext");BrowserContext=_BrowserContext,_CreateSessionParams=class{constructor(params){this.labels=params?.labels||{},this.imageId=params?.imageId;let idle=params?.idleReleaseTimeout;if(idle==null)this.idleReleaseTimeout=0;else{if(typeof idle!="number"||!Number.isInteger(idle)||idle<=0)throw new Error("idleReleaseTimeout must be a positive integer (seconds)");this.idleReleaseTimeout=idle}if(this.lifecyclePolicy=params?.lifecyclePolicy||void 0,this.lifecyclePolicy&&this.idleReleaseTimeout>0)throw new Error("lifecyclePolicy cannot be used together with deprecated idleReleaseTimeout (seconds); use lifecyclePolicy only");this.isVpc=params?.isVpc||!1,this.mcpPolicyId=params?.mcpPolicyId?params.mcpPolicyId:"",this.policyId=params?.policyId?params.policyId:"",this.betaNetworkId=params?.betaNetworkId,this.enableBrowserReplay=params?.enableBrowserReplay,this.extraConfigs=params?.extraConfigs,this.framework=params?.framework||"";let allContextSyncs=params?.contextSync?[...params.contextSync]:[];params?.browserContext&¶ms.browserContext.extensionContextSyncs&&(allContextSyncs=[...allContextSyncs,...params.browserContext.extensionContextSyncs],log(`Added ${params.browserContext.extensionContextSyncs.length} extension context sync(s) from BrowserContext`)),params?.browserContext&¶ms.browserContext.fingerprintContextSync&&(allContextSyncs=[...allContextSyncs,params.browserContext.fingerprintContextSync],log("Added fingerprint context sync from BrowserContext")),this.contextSync=allContextSyncs,this.betaContextMount=params?.betaContextMount?[...params.betaContextMount]:[],this.browserContext=params?.browserContext,this.loadSkills=params?.loadSkills,this.skillNames=params?.skillNames}};__name(_CreateSessionParams,"CreateSessionParams");CreateSessionParams=_CreateSessionParams;init_esm_shims();_LifecyclePolicy=class{constructor(options){let opts=options||{};if(opts.manualRelease){if(opts.idleReleaseTimeout!==void 0&&opts.idleReleaseTimeout!==null)throw new Error("idleReleaseTimeout cannot be set when manualRelease=true. In manual release mode, the session is only released via delete().");if(opts.maxRuntime!==void 0&&opts.maxRuntime!==null)throw new Error("maxRuntime cannot be set when manualRelease=true. In manual release mode, the session is only released via delete().");this.idleReleaseTimeout=0,this.maxRuntime=0,this.manualRelease=!0;return}let idle=opts.idleReleaseTimeout!==void 0&&opts.idleReleaseTimeout!==null?opts.idleReleaseTimeout:5,max=opts.maxRuntime!==void 0&&opts.maxRuntime!==null?opts.maxRuntime:30;if(typeof idle!="number"||!Number.isInteger(idle)||idle<=0)throw new Error("idleReleaseTimeout must be a positive integer (minutes)");if(typeof max!="number"||!Number.isInteger(max)||max<=0)throw new Error("maxRuntime must be a positive integer (minutes)");this.idleReleaseTimeout=idle,this.maxRuntime=max,this.manualRelease=!1}};__name(_LifecyclePolicy,"LifecyclePolicy");LifecyclePolicy=_LifecyclePolicy,BROWSER_DATA_PATH2="/tmp/agentbay_browser",_AgentBay=class{constructor(options={}){if(loadDotEnvWithFallback(options.envFile),this.apiKey=options.apiKey||process.env.AGENTBAY_API_KEY||"",!this.apiKey)throw new AuthenticationError("API key is required. Provide it as a parameter or set the AGENTBAY_API_KEY environment variable.");this.config=loadConfig(options.config,options.envFile);let configData=loadConfig(options.config,options.envFile);this.endpoint=configData.endpoint;let config2=new import_openapi_core.$OpenApiUtil.Config({regionId:"",endpoint:this.endpoint});config2.readTimeout=configData.timeout_ms,config2.connectTimeout=configData.timeout_ms;try{this.client=new Client(config2),this.context=new ContextService(this),this.betaNetwork=new BetaNetworkService(this),this.betaSkills=new BetaSkillsService(this),this.network=this.betaNetwork}catch(error48){throw logError("Failed to constructor:",error48),new AuthenticationError(`Failed to constructor: ${error48}`)}}getRegionId(){return this.config.region_id}async _waitForMobileSimulate(session,mobileSimPath,mobileSimMode){if(log("âŗ Mobile simulate: Waiting for completion"),!session.mobile){logInfo("Mobile module not found in session, skipping mobile simulate");return}if(!session.command){logInfo("Command module not found in session, skipping mobile simulate");return}if(!mobileSimPath){logInfo("Mobile simulate path is empty, skipping mobile simulate");return}try{let startTime=Date.now(),devInfoFilePath=`${mobileSimPath}/dev_info.json`,wyaApplyOption="";!mobileSimMode||mobileSimMode==="PropertiesOnly"?wyaApplyOption="":mobileSimMode==="SensorsOnly"?wyaApplyOption="-sensors":mobileSimMode==="PackagesOnly"?wyaApplyOption="-packages":mobileSimMode==="ServicesOnly"?wyaApplyOption="-services":mobileSimMode==="All"&&(wyaApplyOption="-all");let command=`chmod -R a+rwx ${mobileSimPath}; wya apply ${wyaApplyOption} ${devInfoFilePath}`.trim();logInfo(`âšī¸ âŗ Waiting for mobile simulate completion, command: [${command}]`);let cmdResult=await session.command.executeCommand(command);if(cmdResult.success){let consumeTime=(Date.now()-startTime)/1e3;log(`â
Mobile simulate completed with mode: ${mobileSimMode||"PropertiesOnly"}, duration: ${consumeTime.toFixed(2)} seconds`),cmdResult.output&&log(` Output: ${cmdResult.output.trim()}`)}else logInfo(`Failed to execute mobile simulate command: ${cmdResult.errorMessage}`)}catch(error48){logInfo(`Error executing mobile simulate command: ${error48}`)}}async create(params={}){try{let paramsCopy=this.deepCopyParams(params);if(logDebug(`default context syncs length: ${paramsCopy.contextSync?.length}`),paramsCopy.extraConfigs?.mobile?.simulateConfig){let mobileSimContextId=paramsCopy.extraConfigs.mobile.simulateConfig.simulatedContextId;if(mobileSimContextId){let mobileSimContextSync=new ContextSync(mobileSimContextId,"/data/agentbay_mobile_info");paramsCopy.contextSync||(paramsCopy.contextSync=[]),logInfo(`Adding context sync for mobile simulate: ${JSON.stringify(mobileSimContextSync)}`),paramsCopy.contextSync.push(mobileSimContextSync)}}let request=new CreateMcpSessionRequest({authorization:"Bearer "+this.apiKey});paramsCopy.enableBrowserReplay!==void 0&&(request.enableRecord=paramsCopy.enableBrowserReplay);let framework=paramsCopy?.framework||"",sdkStatsJson=`{"source":"sdk","sdk_language":"typescript","sdk_version":"${VERSION}","is_release":${IS_RELEASE},"framework":"${framework}"}`;if(request.sdkStats=sdkStatsJson,this.config.region_id&&(request.loginRegionId=this.config.region_id),paramsCopy.labels&&(request.labels=JSON.stringify(paramsCopy.labels)),paramsCopy.imageId&&(request.imageId=paramsCopy.imageId),paramsCopy.policyId&&(request.mcpPolicyId=paramsCopy.policyId),paramsCopy.betaNetworkId&&(request.networkId=paramsCopy.betaNetworkId),paramsCopy.lifecyclePolicy){let lp=paramsCopy.lifecyclePolicy;lp.manualRelease?request.manualRelease=!0:(request.timeout=lp.idleReleaseTimeout,request.maxRuntime=lp.maxRuntime)}else paramsCopy.idleReleaseTimeout!==void 0&¶msCopy.idleReleaseTimeout!==null&¶msCopy.idleReleaseTimeout>0&&(request.timeout=paramsCopy.idleReleaseTimeout);let needsContextSync=!1,waitContextIds=new Set,needsMobileSim=!1,mobileSimMode,mobileSimPath;if(paramsCopy.contextSync&¶msCopy.contextSync.length>0){let persistenceDataList=[];for(let contextSync of paramsCopy.contextSync){let persistenceItem=new CreateMcpSessionRequestPersistenceDataList({contextId:contextSync.contextId,path:contextSync.path});contextSync.policy&&(persistenceItem.policy=JSON.stringify(contextSync.policy)),persistenceDataList.push(persistenceItem),contextSync.betaWaitForCompletion!==!1&&waitContextIds.add(contextSync.contextId)}request.persistenceDataList=persistenceDataList,needsContextSync=persistenceDataList.length>0}if(paramsCopy.betaContextMount&¶msCopy.betaContextMount.length>0){request.persistenceDataList||(request.persistenceDataList=[]);for(let mount of paramsCopy.betaContextMount){let persistenceItem=new CreateMcpSessionRequestPersistenceDataList({contextId:mount.contextId,path:mount.path,type:"mount",mountConfig:new CreateMcpSessionRequestPersistenceDataListMountConfig({accessMode:mount.accessMode,storageMode:mount.strategy,sourcePath:mount.sourcePath})});request.persistenceDataList.push(persistenceItem),waitContextIds.add(mount.contextId)}needsContextSync=!0}if(paramsCopy.browserContext){let bc=paramsCopy.browserContext,syncMode=bc.syncMode??"standard",whiteLists;syncMode==="minimal"?whiteLists=[{path:"/Local State",excludePaths:[]},{path:"/Default/Cookies",excludePaths:[]},{path:"/Default/Cookies-journal",excludePaths:[]}]:whiteLists=[{path:"/Local State",excludePaths:[]},{path:"/Default/Cookies",excludePaths:[]},{path:"/Default/Cookies-journal",excludePaths:[]},{path:"/Default/Local Storage",excludePaths:[]},{path:"/Default/IndexedDB",excludePaths:[]},{path:"/Default/Session Storage",excludePaths:[]},{path:"/Default/Login Data",excludePaths:[]},{path:"/Default/Login Data-journal",excludePaths:[]},{path:"/Default/Login Data For Account",excludePaths:[]},{path:"/Default/Login Data For Account-journal",excludePaths:[]},{path:"/Default/Web Data",excludePaths:[]},{path:"/Default/Web Data-journal",excludePaths:[]},{path:"/Default/Preferences",excludePaths:[]},{path:"/Default/Secure Preferences",excludePaths:[]},{path:"/Default/TransportSecurity",excludePaths:[]},{path:"/Default/Network Persistent State",excludePaths:[]},{path:"/Default/GPUCache",excludePaths:[]},{path:"/Default/Affiliation Database",excludePaths:[]},{path:"/Default/Affiliation Database-journal",excludePaths:[]}];let syncPolicy={uploadPolicy:{autoUpload:bc.autoUpload},downloadPolicy:null,deletePolicy:null,bwList:{whiteLists},recyclePolicy:null},browserContextSync=new CreateMcpSessionRequestPersistenceDataList({contextId:bc.contextId,path:BROWSER_DATA_PATH2,policy:JSON.stringify(syncPolicy)});request.persistenceDataList||(request.persistenceDataList=[]),request.persistenceDataList.push(browserContextSync),needsContextSync=!0,waitContextIds.add(paramsCopy.browserContext.contextId)}paramsCopy.extraConfigs&&(request.extraConfigs=JSON.stringify(paramsCopy.extraConfigs),paramsCopy.extraConfigs.mobile?.simulateConfig?.simulate&&(mobileSimPath=paramsCopy.extraConfigs.mobile.simulateConfig.simulatePath,mobileSimPath?(needsMobileSim=!0,mobileSimMode=paramsCopy.extraConfigs.mobile.simulateConfig.simulateMode):logInfo("mobile_sim_path is not set now, skip mobile simulate operation"))),paramsCopy.loadSkills&&(request.loadSkill=!0,paramsCopy.skillNames&¶msCopy.skillNames.length>0&&(request.skills=paramsCopy.skillNames)),logAPICall("CreateMcpSession",{labels:paramsCopy.labels,imageId:paramsCopy.imageId,policyId:paramsCopy.policyId,persistenceDataCount:paramsCopy.contextSync?paramsCopy.contextSync.length:0});let response=await this.client.createMcpSession(request),requestId=extractRequestId(response)||"";setRequestId(requestId);let sessionData=response.body;if(!sessionData||typeof sessionData!="object")return logAPIResponseWithDetails("CreateMcpSession",requestId,!1,{},"Invalid response format: expected a dictionary"),logDebug("Full response:",JSON.stringify(sessionData,null,2)),{requestId,success:!1,errorMessage:"Invalid response format: expected a dictionary"};if(sessionData.success===!1&&sessionData.code){let errorMessage2=`[${sessionData.code}] ${sessionData.message||"Unknown error"}`;return logAPIResponseWithDetails("CreateMcpSession",requestId,!1,{},errorMessage2),logDebug("Full response:",JSON.stringify(sessionData,null,2)),{requestId,success:!1,errorMessage:errorMessage2}}let data=sessionData.data;if(!data||typeof data!="object")return logAPIResponseWithDetails("CreateMcpSession",requestId,!1,{},"Invalid response format: 'data' field is not a dictionary"),logDebug("Full response:",JSON.stringify(sessionData,null,2)),{requestId,success:!1,errorMessage:"Invalid response format: 'data' field is not a dictionary"};if(data.success===!1){let errorMessage2=data.errMsg||"Session creation failed";return logAPIResponseWithDetails("CreateMcpSession",requestId,!1,{},errorMessage2),logDebug("Full response:",JSON.stringify(sessionData,null,2)),{requestId,success:!1,errorMessage:errorMessage2}}let sessionId=data.sessionId;if(!sessionId)return logAPIResponseWithDetails("CreateMcpSession",requestId,!1,{},"SessionId not found in response"),logDebug("Full response:",JSON.stringify(sessionData,null,2)),{requestId,success:!1,errorMessage:"SessionId not found in response"};let resourceUrl=data.resourceUrl||"";logAPIResponseWithDetails("CreateMcpSession",requestId,!0,{sessionId,resourceUrl});let session=new Session(this,sessionId);if(session.appInstanceId=data.appInstanceId||"",session.resourceUrl=resourceUrl,session.vpcIp=data.vpcIp||"",session.vpcId=data.vpcId||"",session.token=data.token||"",session.linkUrl=data.linkUrl||"",session.wsUrl=data.wsUrl||"",session.mcpTools=this.parseToolListToMcpTools(data.toolList),session.enableBrowserReplay=paramsCopy.enableBrowserReplay,session.imageId=paramsCopy.imageId,paramsCopy.extraConfigs&¶msCopy.extraConfigs.mobile){log("Applying mobile configuration...");try{let configResult=await session.mobile.configure(paramsCopy.extraConfigs.mobile);configResult.success?log("Mobile configuration applied successfully"):logError(`Warning: Failed to apply mobile configuration: ${configResult.errorMessage}`)}catch(error48){logError(`Warning: Failed to apply mobile configuration: ${error48}`)}}if(needsContextSync&&waitContextIds.size>0){logDebug("Waiting for context synchronization to complete...");let initialInterval=500,maxInterval=5e3,backoffFactor=1.1,maxRetries=50,currentInterval=initialInterval;for(let retry=0;retry<maxRetries;retry++)try{let infoResult=await session.context.info(),hasFailure=!1,statusByContextId=new Map;for(let item of infoResult.contextStatusData)waitContextIds.has(item.contextId)&&(statusByContextId.set(item.contextId,item.status),logDebug(`Context ${item.contextId} status: ${item.status}, path: ${item.path}`),item.status==="Failed"&&(hasFailure=!0,logError(`Context synchronization failed for ${item.contextId}: ${item.errorMessage}`)));let allCompleted=!0;for(let ctxId of waitContextIds){let st=statusByContextId.get(ctxId);if(!st||st!=="Success"&&st!=="Failed"){allCompleted=!1;break}}if(allCompleted){hasFailure?logDebug("Context synchronization completed with failures"):logDebug("Context synchronization completed successfully");break}logDebug(`Waiting for context synchronization, attempt ${retry+1}/${maxRetries}, next interval: ${(currentInterval/1e3).toFixed(2)}s`),await new Promise(resolve22=>setTimeout(resolve22,currentInterval)),currentInterval=Math.min(currentInterval*backoffFactor,maxInterval)}catch(error48){logError(`Error checking context status on attempt ${retry+1}: ${error48}`),await new Promise(resolve22=>setTimeout(resolve22,currentInterval)),currentInterval=Math.min(currentInterval*backoffFactor,maxInterval)}}return needsMobileSim&&mobileSimPath&&await this._waitForMobileSimulate(session,mobileSimPath,mobileSimMode),{requestId,success:!0,session}}catch(error48){return logError("Error calling create_mcp_session:",error48),{requestId:"",success:!1,errorMessage:`Failed to create session: ${error48}`}}}async list(labels={},page,limit=10,status,imageId){try{if(status!==void 0){let validStatuses=["RUNNING","PAUSING","PAUSED","RESUMING","DELETING","DELETED"];if(!validStatuses.includes(status))return{requestId:"",success:!1,errorMessage:`Invalid status '${status}'. Must be one of: ${validStatuses.join(", ")}`,sessionIds:[],nextToken:"",maxResults:limit,totalCount:0}}if(page!==void 0&&page<1)return{requestId:"",success:!1,errorMessage:`Cannot reach page ${page}: Page number must be >= 1`,sessionIds:[],nextToken:"",maxResults:limit,totalCount:0};let nextToken="";if(page!==void 0&&page>1){let currentPage=1;for(;currentPage<page;){let request2=new ListSessionRequest({authorization:`Bearer ${this.apiKey}`,labels:JSON.stringify(labels),maxResults:limit});nextToken&&(request2.nextToken=nextToken),status&&(request2.status=status),imageId&&(request2.imageId=imageId);let response2=await this.client.listSession(request2),requestId2=extractRequestId(response2)||"";if(!response2.body?.success){let code=response2.body?.code||"Unknown",message=response2.body?.message||"Unknown error";return{requestId:requestId2,success:!1,errorMessage:`[${code}] ${message}`,sessionIds:[],nextToken:"",maxResults:limit,totalCount:0}}if(nextToken=response2.body.nextToken||"",!nextToken)return{requestId:requestId2,success:!1,errorMessage:`Cannot reach page ${page}: No more pages available`,sessionIds:[],nextToken:"",maxResults:limit,totalCount:response2.body.totalCount||0};currentPage+=1}}let request=new ListSessionRequest({authorization:`Bearer ${this.apiKey}`,labels:JSON.stringify(labels),maxResults:limit});nextToken&&(request.nextToken=nextToken),status&&(request.status=status),imageId&&(request.imageId=imageId),logAPICall("ListSession",{labels,maxResults:limit,nextToken:nextToken||void 0,status:status||void 0});let response=await this.client.listSession(request),requestId=extractRequestId(response)||"";if(setRequestId(requestId),!response.body?.success){let code=response.body?.code||"Unknown",message=response.body?.message||"Unknown error";return logAPIResponseWithDetails("ListSession",requestId,!1,{},`[${code}] ${message}`),logDebug("Full ListSession response:",JSON.stringify(response.body,null,2)),{requestId,success:!1,errorMessage:`[${code}] ${message}`,sessionIds:[],nextToken:"",maxResults:limit,totalCount:0}}let sessionIds=[];if(response.body.data){for(let sessionData of response.body.data)if(sessionData.sessionId){let sessionInfo={sessionId:sessionData.sessionId,sessionStatus:sessionData.sessionStatus||"UNKNOWN"};sessionData.appInstanceId&&(sessionInfo.appInstanceId=sessionData.appInstanceId),sessionData.imageId&&(sessionInfo.imageId=sessionData.imageId),sessionIds.push(sessionInfo)}}return logAPIResponseWithDetails("ListSession",requestId,!0,{sessionCount:sessionIds.length,totalCount:response.body.totalCount||0,maxResults:response.body.maxResults||limit}),{requestId,success:!0,sessionIds,nextToken:response.body.nextToken||"",maxResults:response.body.maxResults||limit,totalCount:response.body.totalCount||0}}catch(error48){return logError("Error calling list_session:",error48),{requestId:"",success:!1,errorMessage:`Failed to list sessions: ${error48}`,sessionIds:[]}}}async delete(session,syncContext=!1){try{logAPICall("DeleteSession",{sessionId:session.sessionId});let deleteResult=await session.delete(syncContext);return logAPIResponseWithDetails("DeleteSession",deleteResult.requestId,deleteResult.success,{sessionId:session.sessionId}),deleteResult}catch(error48){return logError("Error deleting session:",error48),{requestId:"",success:!1,errorMessage:`Failed to delete session ${session.sessionId}: ${error48}`}}}async _getSession(sessionId){try{logAPICall("GetSession",{sessionId});let request=new GetSessionRequest({authorization:`Bearer ${this.apiKey}`,sessionId}),response=await this.client.getSession(request),requestId=extractRequestId(response)||"",body=response.body;if(setRequestId(requestId),body?.success===!1&&body.code)return logAPIResponseWithDetails("GetSession",requestId,!1,{},`[${body.code}] ${body.message||"Unknown error"}`),logDebug("Full GetSession response:",JSON.stringify(body,null,2)),{requestId,httpStatusCode:body.httpStatusCode||0,code:body.code,success:!1,errorMessage:`[${body.code}] ${body.message||"Unknown error"}`};let result={requestId,httpStatusCode:body?.httpStatusCode||0,code:body?.code||"",success:body?.success||!1,errorMessage:""};if(body?.data){let contextsList=body.data.contexts||[],contexts=[];if(Array.isArray(contextsList))for(let ctx of contextsList)ctx&&typeof ctx=="object"&&ctx.name&&ctx.id&&contexts.push({name:ctx.name,id:ctx.id});let wsUrl=body.data.wsUrl||"",data={appInstanceId:body.data.appInstanceId||"",resourceId:body.data.resourceId||"",sessionId:body.data.sessionId||"",success:body.data.success||!1,httpPort:body.data.httpPort||"",networkInterfaceIp:body.data.networkInterfaceIp||"",token:body.data.token||"",linkUrl:body.data.linkUrl||"",wsUrl,vpcResource:body.data.vpcResource||!1,vpcIp:body.data.vpcIp||"",vpcId:body.data.vpcId||"",resourceUrl:body.data.resourceUrl||"",status:body.data.status||"",toolList:body.data.toolList||"",contexts:contexts.length>0?contexts:void 0};result.data=data,logAPIResponseWithDetails("GetSession",requestId,!0,{sessionId:data.sessionId,resourceId:data.resourceId,httpPort:data.httpPort})}return result}catch(error48){let errorStr=String(error48);return(error48?.data?.Code||error48?.code||"")==="InvalidMcpSession.NotFound"||errorStr.includes("NotFound")?(logInfo(`Session not found: ${sessionId}`),logDebug(`GetSession error details: ${errorStr}`),{requestId:"",httpStatusCode:400,code:"InvalidMcpSession.NotFound",success:!1,errorMessage:`Session ${sessionId} not found`}):(logError("Error calling GetSession:",error48),{requestId:"",httpStatusCode:0,code:"",success:!1,errorMessage:`Failed to get session ${sessionId}: ${error48}`})}}async get(sessionId){if(!sessionId||typeof sessionId=="string"&&!sessionId.trim())return{requestId:"",success:!1,errorMessage:"session_id is required"};let getResult=await this._getSession(sessionId);if(!getResult.success){let errorMsg=getResult.errorMessage||"Unknown error";return{requestId:getResult.requestId,success:!1,errorMessage:`Failed to get session ${sessionId}: ${errorMsg}`}}let session=new Session(this,sessionId);return getResult.data&&(session.appInstanceId=getResult.data.appInstanceId||"",session.resourceUrl=getResult.data.resourceUrl,session.vpcIp=getResult.data.vpcIp||"",session.vpcId=getResult.data.vpcId||"",session.token=getResult.data.token||"",session.linkUrl=getResult.data.linkUrl||"",session.wsUrl=getResult.data.wsUrl||"",session.mcpTools=this.parseToolListToMcpTools(getResult.data.toolList)),{requestId:getResult.requestId,success:!0,session}}getClient(){return this.client}getAPIKey(){return this.apiKey}async betaPauseAsync(session,timeout=600,pollInterval=2){try{return await session.betaPauseAsync(timeout,pollInterval)}catch(error48){return logError("Error calling pause session async:",error48),{requestId:"",success:!1,errorMessage:`Failed to pause session ${session.sessionId}: ${error48}`}}}async betaResumeAsync(session,timeout=600,pollInterval=2){try{return await session.betaResumeAsync(timeout,pollInterval)}catch(error48){return logError("Error calling resume session async:",error48),{requestId:"",success:!1,errorMessage:`Failed to resume session ${session.sessionId}: ${error48}`}}}parseToolListToMcpTools(toolList){if(!toolList)return[];let items=toolList;if(typeof toolList=="string")try{items=JSON.parse(toolList)}catch(error48){return logDebug(`Failed to parse ToolList JSON: ${error48}`),[]}if(!Array.isArray(items))return[];let tools=[];for(let item of items){if(!item||typeof item!="object")continue;let name=item.name||item.Name||"",server=item.server||item.serverName||item.Server||"",description=item.description||item.Description||"",inputSchema=item.inputSchema||item.input_schema||{},tool=item.tool||item.Tool||"";tools.push({name,server,description,inputSchema,tool})}return tools}deepCopyParams(params){let result;if(params instanceof CreateSessionParams)result={labels:params.labels,imageId:params.imageId,idleReleaseTimeout:params.idleReleaseTimeout,lifecyclePolicy:params.lifecyclePolicy,contextSync:params.contextSync,browserContext:params.browserContext,isVpc:params.isVpc,mcpPolicyId:params.mcpPolicyId,policyId:params.policyId,betaNetworkId:params.betaNetworkId,enableBrowserReplay:params.enableBrowserReplay,extraConfigs:params.extraConfigs,framework:params.framework,loadSkills:params.loadSkills,skillNames:params.skillNames};else{result=JSON.parse(JSON.stringify(params));let allContextSyncs=params?.contextSync?[...params.contextSync]:[];if(result.browserContext&&result.browserContext.extensionContextSyncs&&(result.contextSync=[...allContextSyncs,...result.browserContext.extensionContextSyncs]),params?.browserContext&¶ms.browserContext.fingerprintContextSync&&(result.contextSync=[...result.contextSync||[],params.browserContext.fingerprintContextSync],log("Added fingerprint context sync from BrowserContext")),result.contextSync&&Array.isArray(result.contextSync)&&(result.contextSync=result.contextSync.map(cs=>new ContextSync(cs.contextId,cs.path,cs.policy,cs.betaWaitForCompletion))),result.browserContext){let bc=result.browserContext;result.browserContext=new BrowserContext(bc.contextId,bc.autoUpload,bc.extensionOption,bc.fingerprintContext,bc.syncMode)}}return result}};__name(_AgentBay,"AgentBay");AgentBay=_AgentBay;init_esm_shims();init_esm_shims();EXTENSIONS_BASE_PATH="/tmp/extensions",_Extension=class{constructor(id,name,createdAt){this.id=id,this.name=name,this.createdAt=createdAt}};__name(_Extension,"Extension");Extension=_Extension,_ExtensionOption=class{constructor(contextId,extensionIds){if(!contextId||!contextId.trim())throw new Error("contextId cannot be empty");if(!extensionIds||extensionIds.length===0)throw new Error("extensionIds cannot be empty");this.contextId=contextId,this.extensionIds=extensionIds}toString(){return`ExtensionOption(contextId='${this.contextId}', extensionIds=${JSON.stringify(this.extensionIds)})`}toDisplayString(){return`Extension Config: ${this.extensionIds.length} extension(s) in context '${this.contextId}'`}validate(){try{if(!this.contextId||!this.contextId.trim()||!this.extensionIds||this.extensionIds.length===0)return!1;for(let extId of this.extensionIds)if(typeof extId!="string"||!extId.trim())return!1;return!0}catch{return!1}}};__name(_ExtensionOption,"ExtensionOption");ExtensionOption=_ExtensionOption,_ExtensionsService=class{constructor(agentBay,contextId=""){if(this._initializationPromise=null,!agentBay)throw new AgentBayError("AgentBay instance is required");if(!agentBay.context)throw new AgentBayError("AgentBay instance must have a context service");this.agentBay=agentBay,this.contextService=agentBay.context,this.autoCreated=!0,(!contextId||contextId.trim()==="")&&(contextId=`extensions-${Math.floor(Date.now()/1e3)}`,logDebug(`Generated default context name: ${contextId}`)),this.contextName=contextId,this._initializationPromise=this._initializeContext()}async _initializeContext(){try{let contextResult=await this.contextService.get(this.contextName,!0);if(!contextResult.success||!contextResult.context)throw new AgentBayError(`Failed to create extension repository context: ${this.contextName}`);this.extensionContext=contextResult.context,this.contextId=this.extensionContext.id}catch(error48){throw new AgentBayError(`Failed to initialize ExtensionsService: ${error48 instanceof Error?error48.message:String(error48)}`)}}async _ensureInitialized(){this._initializationPromise&&(await this._initializationPromise,this._initializationPromise=null)}async _uploadToCloud(localPath,remotePath){try{let urlResult=await this.contextService.getFileUploadUrl(this.contextId,remotePath);if(!urlResult.success||!urlResult.url)throw new AgentBayError(`Failed to get upload URL: ${urlResult.url||"No URL returned"}`);let preSignedUrl=urlResult.url,fileBuffer=await fs42.promises.readFile(localPath),response=await node_fetch_default(preSignedUrl,{method:"PUT",body:fileBuffer});if(!response.ok)throw new AgentBayError(`HTTP error uploading file: ${response.status} ${response.statusText}`)}catch(error48){if(error48 instanceof AgentBayError)throw error48;if(error48 instanceof Error&&"code"in error48){let errorCode=error48.code;throw errorCode==="ENOENT"?new AgentBayError(`File not found: ${localPath}`):errorCode==="EACCES"?new AgentBayError(`Permission denied accessing file: ${localPath}`):new AgentBayError(`File system error: ${error48.message}`)}throw error48 instanceof TypeError&&error48.message.includes("fetch")?new AgentBayError(`Network error during file upload: ${error48.message}`):new AgentBayError(`An error occurred while uploading the file: ${error48 instanceof Error?error48.message:String(error48)}`)}}async list(){await this._ensureInitialized();try{let fileListResult=await this.contextService.listFiles(this.contextId,EXTENSIONS_BASE_PATH,1,100);if(!fileListResult.success)throw new AgentBayError("Failed to list extensions: Context file listing failed.");let extensions=[];for(let fileEntry of fileListResult.entries){let extensionId=fileEntry.fileName||fileEntry.filePath;extensions.push(new Extension(extensionId,fileEntry.fileName||extensionId,fileEntry.gmtCreate))}return extensions}catch(error48){throw error48 instanceof AgentBayError?error48:new AgentBayError(`An error occurred while listing browser extensions: ${error48 instanceof Error?error48.message:String(error48)}`)}}async create(localPath){if(await this._ensureInitialized(),!fs42.existsSync(localPath))throw new Error(`The specified local file was not found: ${localPath}`);let fileExtension=path42.extname(localPath).toLowerCase();if(fileExtension!==".zip")throw new Error(`Unsupported plugin format '${fileExtension}'. Only ZIP format (.zip) is supported.`);let extensionId=`ext_${crypto3.randomBytes(16).toString("hex")}${fileExtension}`,extensionName=path42.basename(localPath),remotePath=`${EXTENSIONS_BASE_PATH}/${extensionId}`;return await this._uploadToCloud(localPath,remotePath),new Extension(extensionId,extensionName)}async update(extensionId,newLocalPath){if(await this._ensureInitialized(),!fs42.existsSync(newLocalPath))throw new Error(`The specified new local file was not found: ${newLocalPath}`);if(!(await this.list()).some(ext=>ext.id===extensionId))throw new Error(`Browser extension with ID '${extensionId}' not found in the context. Cannot update.`);let remotePath=`${EXTENSIONS_BASE_PATH}/${extensionId}`;return await this._uploadToCloud(newLocalPath,remotePath),new Extension(extensionId,path42.basename(newLocalPath))}async _getExtensionInfo(extensionId){await this._ensureInitialized();try{return(await this.list()).find(ext=>ext.id===extensionId)}catch(error48){logError(`An error occurred while getting extension info for '${extensionId}':`,error48);return}}async cleanup(){if(await this._ensureInitialized(),!this.autoCreated)return!0;try{return await this.contextService.delete(this.extensionContext)?(logInfo(`Extension context deleted: ${this.contextName} (ID: ${this.contextId})`),!0):(logError(`Warning: Failed to delete extension context: ${this.contextName}`,new Error("Delete operation returned false")),!1)}catch(error48){return logError("Warning: Failed to delete extension context:",error48),!1}}async delete(extensionId){await this._ensureInitialized();let remotePath=`${EXTENSIONS_BASE_PATH}/${extensionId}`;try{return(await this.contextService.deleteFile(this.contextId,remotePath)).success}catch(error48){return logError(`An error occurred while deleting browser extension '${extensionId}':`,error48),!1}}createExtensionOption(extensionIds){if(!this.contextId)throw new Error("Service not initialized. Please call an async method first or ensure context is created.");return new ExtensionOption(this.contextId,extensionIds)}};__name(_ExtensionsService,"ExtensionsService");init_esm_shims();init_esm_shims();MobileSimulateMode=(MobileSimulateMode2=>(MobileSimulateMode2.PropertiesOnly="PropertiesOnly",MobileSimulateMode2.SensorsOnly="SensorsOnly",MobileSimulateMode2.PackagesOnly="PackagesOnly",MobileSimulateMode2.ServicesOnly="ServicesOnly",MobileSimulateMode2.All="All",MobileSimulateMode2))(MobileSimulateMode||{});__name(extraConfigsToJSON,"extraConfigsToJSON");__name(extraConfigsFromJSON,"extraConfigsFromJSON");__name(validateAppManagerRule,"validateAppManagerRule");__name(validateMobileSimulateConfig,"validateMobileSimulateConfig");__name(validateMobileExtraConfig,"validateMobileExtraConfig");__name(validateExtraConfigs,"validateExtraConfigs");MOBILE_INFO_DEFAULT_PATH="/data/agentbay_mobile_info",MOBILE_INFO_SUB_PATH="/agentbay_mobile_info",MOBILE_INFO_FILE_NAME="dev_info.json",_MobileSimulateService=class{constructor(agentBay){if(this.simulateEnable=!1,this.simulateMode="PropertiesOnly",this.useInternalContext=!0,!agentBay)throw new Error("agentBay is required");if(!agentBay.context)throw new Error("agentBay.context is required");this.agentBay=agentBay,this.contextService=agentBay.context}setSimulateEnable(enable){this.simulateEnable=enable}getSimulateEnable(){return this.simulateEnable}setSimulateMode(mode){this.simulateMode=mode}getSimulateMode(){return this.simulateMode}setSimulateContextId(contextId){this.contextId=contextId,logInfo(`set simulate context id = ${contextId}`),this.updateContext(!0,contextId,void 0)}getSimulateContextId(){return this.contextId}getSimulateConfig(){let simulatedContextId=this.useInternalContext?this.contextId:void 0;return{simulate:this.simulateEnable,simulatePath:this.mobileDevInfoPath,simulateMode:this.simulateMode,simulatedContextId}}async hasMobileInfo(contextSync){if(!contextSync)throw new Error("contextSync is required");if(!contextSync.contextId)throw new Error("contextSync.contextId is required");if(!contextSync.path)throw new Error("contextSync.path is required");let mobileDevInfoPath=contextSync.path+MOBILE_INFO_SUB_PATH+"/";logDebug(`hasMobileInfo: context_id = ${contextSync.contextId}, mobile_dev_info_path = ${mobileDevInfoPath}`);let res=await this.contextService.listFiles(contextSync.contextId,mobileDevInfoPath,1,50),foundDevInfo=!1;if(res.success){for(let entry of res.entries)if(entry.fileName===MOBILE_INFO_FILE_NAME){foundDevInfo=!0;break}}else return logError(`failed to list files: ${res.errorMessage}`),!1;return foundDevInfo?(logInfo("mobile dev info already exists"),this.updateContext(!1,contextSync.contextId,contextSync),!0):(logInfo("mobile dev info does not exist"),!1)}async uploadMobileInfo(mobileDevInfoContent,contextSync){if(!mobileDevInfoContent)throw new Error("mobileDevInfoContent is required");try{JSON.parse(mobileDevInfoContent)}catch{throw new Error("mobileDevInfoContent is not a valid JSON string")}if(contextSync){if(!contextSync.contextId)throw new Error("contextSync.contextId is required");this.updateContext(!1,contextSync.contextId,contextSync)}else{let createdContext=await this.createContextForSimulate();if(!createdContext)return logError("Failed to create context for simulate"),{success:!1,errorMessage:"Failed to create context for simulate"};this.updateContext(!0,createdContext.id,void 0)}let uploadPath=`${this.mobileDevInfoPath}/${MOBILE_INFO_FILE_NAME}`,uploadUrlResult=await this.contextService.getFileUploadUrl(this.contextId,uploadPath);if(!uploadUrlResult.success)return logError(`Failed to get file upload URL: ${uploadUrlResult.errorMessage}`),{success:!1,errorMessage:uploadUrlResult.errorMessage};logDebug(`upload_url = ${uploadUrlResult.url}`);try{let uint8Array=new TextEncoder().encode(mobileDevInfoContent),response=await node_fetch_default(uploadUrlResult.url,{method:"PUT",body:uint8Array});if(!response.ok)throw new Error(`Upload failed with status ${response.status}: ${response.statusText}`)}catch(error48){let errorMsg=`An error occurred while uploading the file: ${error48 instanceof Error?error48.message:String(error48)}`;return logError(errorMsg),{success:!1,errorMessage:errorMsg}}return logInfo("mobile dev info uploaded successfully"),{success:!0,mobileSimulateContextId:this.contextId}}updateContext(isInternal,contextId,contextSync){if(!isInternal){if(!contextSync)throw new Error("contextSync is required for external context");contextSync.policy?.bwList?.whiteLists&&(contextSync.policy.bwList.whiteLists.some(whiteList=>whiteList.path===MOBILE_INFO_SUB_PATH)||(contextSync.policy.bwList.whiteLists.push({path:MOBILE_INFO_SUB_PATH,excludePaths:[]}),logInfo(`added mobile_dev_info_path to context_sync.policy.bw_list.white_lists: ${MOBILE_INFO_SUB_PATH}`)))}this.useInternalContext=isInternal,this.contextId=contextId,this.contextSync=contextSync,isInternal?this.mobileDevInfoPath=MOBILE_INFO_DEFAULT_PATH:this.mobileDevInfoPath=contextSync.path+MOBILE_INFO_SUB_PATH,logInfo(`updated context, is_internal = ${isInternal}, context_id = ${this.contextId}, mobile_dev_info_path = ${this.mobileDevInfoPath}`)}async createContextForSimulate(){let contextName=`mobile_sim_${Array.from({length:16},()=>Math.floor(Math.random()*256).toString(16).padStart(2,"0")).join("")}_${Math.floor(Date.now()/1e3)}`,contextResult=await this.contextService.get(contextName,!0);if(!contextResult.success||!contextResult.context)return logError(`Failed to create mobile simulate context: ${contextResult.errorMessage}`),null;let context=contextResult.context;return logInfo(`created mobile simulate context, context_id = ${context.id}, context_name = ${context.name}`),context}};__name(_MobileSimulateService,"MobileSimulateService");init_esm_shims();init_esm_shims();__name(createListSessionParams,"createListSessionParams");init_esm_shims();init_esm_shims();_LocalMCPClient=class{constructor(server,command,args,env=null){this.session=null,this.workerThread=null,this.toolCallQueue=[],this.isConnected=!1,this.connectPromise=null,this.server=server,this.command=command,this.args=args,this.env=env}get connected(){return this.isConnected&&this.workerThread!==null}async connect(){if(!this.connected)return this.connectPromise?this.connectPromise:(this.connectPromise=this._doConnect(),this.connectPromise)}async _doConnect(){return new Promise((resolve22,reject)=>{logInfo("[LocalMCPClient] Starting connection to MCP server"),logInfo(`[LocalMCPClient] command = ${this.command}, args = ${this.args.join(" ")}`);let envToUse=this.env!==null?this.env:process.env,childProcess=spawn4(this.command,this.args,{stdio:["pipe","pipe","pipe"],env:envToUse});this.workerThread=childProcess;let initResolved=!1,initTimeout=setTimeout(()=>{initResolved||(initResolved=!0,this.isConnected=!0,this.connectPromise=null,logInfo("[LocalMCPClient] MCP client connection timeout - marking as connected (server may still be initializing)"),resolve22())},15e3),buffer="";childProcess.stdout?.on("data",data=>{buffer+=data.toString();try{let lines=buffer.split(`
|
|
426
426
|
`);buffer=lines.pop()||"";for(let line of lines)if(line.trim()){let parsed=JSON.parse(line.trim());(parsed.result||parsed.method==="notifications/initialized"||parsed.id&&parsed.id==="init")&&(initResolved||(clearTimeout(initTimeout),initResolved=!0,this.isConnected=!0,this.connectPromise=null,logInfo("[LocalMCPClient] MCP client session initialized (received response from server)"),resolve22())),this.handleMessage(line.trim())}}catch{}}),childProcess.stderr?.on("data",data=>{let stderrText=data.toString();logDebug(`[LocalMCPClient] stderr: ${stderrText}`),(stderrText.includes("started")||stderrText.includes("initialized")||stderrText.includes("ready"))&&setTimeout(()=>{initResolved||(clearTimeout(initTimeout),initResolved=!0,this.isConnected=!0,this.connectPromise=null,logInfo("[LocalMCPClient] MCP client session initialized (detected from stderr logs)"),resolve22())},2e3)}),childProcess.on("exit",code=>{logInfo(`[LocalMCPClient] Process exited with code ${code}`),clearTimeout(initTimeout),this.isConnected=!1,this.workerThread=null,this.connectPromise=null,initResolved||(initResolved=!0,reject(new Error(`MCP server process exited with code ${code} before initialization completed`)))}),childProcess.on("error",error48=>{clearTimeout(initTimeout),this.connectPromise=null,logError(`[LocalMCPClient] Failed to spawn MCP server: ${error48}`),initResolved||(initResolved=!0,reject(error48))});let initRequest={jsonrpc:"2.0",id:"init",method:"initialize",params:{protocolVersion:"2024-11-05",capabilities:{},clientInfo:{name:"LocalPageAgent",version:"1.0.0"}}};setTimeout(()=>{childProcess.stdin&&!childProcess.stdin.destroyed&&(childProcess.stdin.write(JSON.stringify(initRequest)+`
|
|
427
427
|
`),logInfo("[LocalMCPClient] Sent initialization request to MCP server"))},1e3)})}handleMessage(message){try{let parsed=JSON.parse(message);if(parsed.result&&this.toolCallQueue.length>0){let queued=this.toolCallQueue.shift();if(queued){let responseData=parsed.result;if(parsed.result&&parsed.result.content&&Array.isArray(parsed.result.content)&&parsed.result.content.length>0){let contentItem=parsed.result.content[0];contentItem&&contentItem.text!==void 0&&(responseData=contentItem.text)}else typeof parsed.result=="string"?responseData=parsed.result:responseData=typeof parsed.result=="string"?parsed.result:JSON.stringify(parsed.result);let response={requestId:parsed.id||`local_request_${randomUUID5()}`,success:!parsed.error,data:typeof responseData=="string"?responseData:JSON.stringify(responseData),errorMessage:parsed.error?.message};queued.resolve(response)}}}catch(e){logDebug(`[LocalMCPClient] Failed to parse message: ${e}, message: ${message.substring(0,200)}`)}}async callTool(toolName,arguments_){if(!this.connected)throw new RuntimeError("MCP client is not connected. Call connect() and ensure it completes before calling callTool.");return new Promise((resolve22,reject)=>{logInfo(`[LocalMCPClient] Call tool ${toolName} with arguments ${JSON.stringify(arguments_)}`),this.toolCallQueue.push({toolName,arguments:arguments_,resolve:resolve22,reject});let request={jsonrpc:"2.0",id:randomUUID5(),method:"tools/call",params:{name:toolName,arguments:arguments_}};this.workerThread?.stdin?.write(JSON.stringify(request)+`
|
|
428
|
-
`),setTimeout(()=>{reject(new Error(`Tool call timeout: ${toolName}`))},18e4)})}};__name(_LocalMCPClient,"LocalMCPClient");LocalMCPClient=_LocalMCPClient,_RuntimeError=class extends(Error.default||Error){constructor(message){super(message),this.name="RuntimeError"}};__name(_RuntimeError,"RuntimeError");RuntimeError=_RuntimeError,_LocalPageAgent=class extends(BrowserOperator.default||BrowserOperator){constructor(session,browser){super(session,browser),this.mcpClient=null;let mcpScript=process.env.PAGE_TASK_MCP_SERVER_SCRIPT||"";if(mcpScript){let env={...process.env};this.mcpClient=new LocalMCPClient("PageUseAgent","python",[mcpScript],env)}else this.mcpClient=null,logWarn("PAGE_TASK_MCP_SERVER_SCRIPT not set. MCP client will not be initialized.")}async initialize(){this.mcpClient&&await this.mcpClient.connect()}async _callMcpToolAsync(name,args){if(!this.mcpClient)throw new RuntimeError("mcp_client is not set on LocalPageAgent.");return this.mcpClient.connected||await this.mcpClient.connect(),await this.mcpClient.callTool(name,args)}};__name(_LocalPageAgent,"LocalPageAgent");LocalPageAgent=_LocalPageAgent,_LocalBrowser=class _LocalBrowser2 extends(Browser.default||Browser){constructor(session){let tempSession=session||_LocalBrowser2._createMinimalMockSession();super(tempSession),this._cdpPort=9222,this._browser=null,this._workerThread=null,this._playwrightInteractiveLoopAbortSignal=null,this._playwrightInteractiveLoopAbortController=null,this.contexts=[],this.agent=new LocalPageAgent(tempSession,this),this._playwrightInteractiveLoopAbortController=new AbortController,this._playwrightInteractiveLoopAbortSignal=this._playwrightInteractiveLoopAbortController.signal,!session&&tempSession.__isMock&&(tempSession.callMcpTool=async(name,args)=>await this.agent._callMcpToolAsync(name,args))}static _createMinimalMockSession(){return{sessionId:"local_session",__isMock:!0,callMcpTool:__name(async(_name,_args)=>{throw new Error("Mock session not yet initialized - this should not be called")},"callMcpTool")}}async initialize(options){return this._workerThread?!0:new Promise(async resolve22=>{logInfo("[LocalBrowser] Start launching local browser");try{let tmpDir=process.platform==="win32"&&process.env.TEMP||"/tmp",chromeCdpPortsPath=join32(tmpDir,"chrome_cdp_ports.json"),cdpPortsData={chrome:String(this._cdpPort),router:String(this._cdpPort),local:String(this._cdpPort)};await writeFile(chromeCdpPortsPath,JSON.stringify(cdpPortsData,null,2));let cwd=process.cwd(),userDataDir=join32(cwd,"tmp",`browser_user_data_${process.pid}_${randomUUID5()}`),headless=(process.env.HEADLESS||"false").toLowerCase()==="true",browser=await(await Promise.resolve().then(()=>(init_playwright(),playwright_exports))).chromium.launchPersistentContext(userDataDir,{headless,viewport:{width:1280,height:1200},args:[`--remote-debugging-port=${this._cdpPort}`]});this._browser=browser,logInfo("[LocalBrowser] Local browser launched successfully"),this.agent.initialize().catch(err=>{logWarn(`[LocalBrowser] Failed to initialize agent: ${err}`)}),resolve22(!0),await this._playwrightInteractiveLoop(this._playwrightInteractiveLoopAbortSignal??void 0),logInfo("[LocalBrowser] Local browser interactive loop completed")}catch(error48){logError(`[LocalBrowser] Failed to connect to browser: ${error48}`),resolve22(!1)}})}isInitialized(){return this._browser!==null}async getEndpointUrl(){return`http://localhost:${this._cdpPort}`}async _playwrightInteractiveLoop(shutdownSignal){for(;!shutdownSignal?.aborted;)await new Promise(resolve22=>setTimeout(resolve22,3e3))}abortPlaywrightInteractiveLoop(){this._playwrightInteractiveLoopAbortController?.abort()}};__name(_LocalBrowser,"LocalBrowser");LocalBrowser=_LocalBrowser,_LocalSession=class extends(Session.default||Session){constructor(){let mockAgentBay={apiKey:process.env.AGENTBAY_API_KEY||"",apiKeyConfigured:!!process.env.AGENTBAY_API_KEY,client:{apiBaseUrl:"",getSessionStatus:__name(request=>({toMap:__name(()=>({success:!0,data:{status:"running"}}),"toMap")}),"getSessionStatus"),callMcpTool:__name((name,args,kwargs)=>({requestId:"mock_request_id",success:!1,data:null,errorMessage:"Mock mode: Cannot execute tool calls without proper API connection"}),"callMcpTool")}};super(mockAgentBay,"local_session"),this.browser=new LocalBrowser(this)}async callMcpTool(toolName,args,autoGenSession=!1){let result=await this.browser.operator._callMcpToolAsync(toolName,args);return{success:result.success,data:result.data,errorMessage:result.errorMessage||"",requestId:result.requestId}}async delete(syncContext=!1){return this.browser.abortPlaywrightInteractiveLoop(),{success:!0,requestId:`local_delete_${this.sessionId}`,errorMessage:void 0}}};__name(_LocalSession,"LocalSession")}});var agentbay_sdk_exports={};__export(agentbay_sdk_exports,{AgentBay:()=>AgentBay,GetCdpLinkRequest:()=>GetCdpLinkRequest,LifecyclePolicy:()=>LifecyclePolicy});var init_agentbay_sdk=__esm({"src/agentbay-sdk.ts"(){"use strict";init_dist();setupLogger({level:"ERROR",enableConsole:!1})}});var require_wrappy=__commonJS({"../../node_modules/.pnpm/wrappy@1.0.2/node_modules/wrappy/wrappy.js"(exports,module){module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!="function")throw new TypeError("need wrapper function");return Object.keys(fn).forEach(function(k){wrapper[k]=fn[k]}),wrapper;function wrapper(){for(var args=new Array(arguments.length),i=0;i<args.length;i++)args[i]=arguments[i];var ret=fn.apply(this,args),cb2=args[args.length-1];return typeof ret=="function"&&ret!==cb2&&Object.keys(cb2).forEach(function(k){ret[k]=cb2[k]}),ret}}}});var require_once=__commonJS({"../../node_modules/.pnpm/once@1.4.0/node_modules/once/once.js"(exports,module){var wrappy=require_wrappy();module.exports=wrappy(once);module.exports.strict=wrappy(onceStrict);once.proto=once(function(){Object.defineProperty(Function.prototype,"once",{value:function(){return once(this)},configurable:!0}),Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return onceStrict(this)},configurable:!0})});function once(fn){var f=function(){return f.called?f.value:(f.called=!0,f.value=fn.apply(this,arguments))};return f.called=!1,f}function onceStrict(fn){var f=function(){if(f.called)throw new Error(f.onceError);return f.called=!0,f.value=fn.apply(this,arguments)},name=fn.name||"Function wrapped with `once`";return f.onceError=name+" shouldn't be called more than once",f.called=!1,f}}});var require_end_of_stream=__commonJS({"../../node_modules/.pnpm/end-of-stream@1.4.5/node_modules/end-of-stream/index.js"(exports,module){var once=require_once(),noop=function(){},qnt=global.Bare?queueMicrotask:process.nextTick.bind(process),isRequest=function(stream){return stream.setHeader&&typeof stream.abort=="function"},isChildProcess=function(stream){return stream.stdio&&Array.isArray(stream.stdio)&&stream.stdio.length===3},eos=function(stream,opts,callback){if(typeof opts=="function")return eos(stream,null,opts);opts||(opts={}),callback=once(callback||noop);var ws=stream._writableState,rs=stream._readableState,readable=opts.readable||opts.readable!==!1&&stream.readable,writable=opts.writable||opts.writable!==!1&&stream.writable,cancelled=!1,onlegacyfinish=function(){stream.writable||onfinish()},onfinish=function(){writable=!1,readable||callback.call(stream)},onend=function(){readable=!1,writable||callback.call(stream)},onexit=function(exitCode){callback.call(stream,exitCode?new Error("exited with error code: "+exitCode):null)},onerror=function(err){callback.call(stream,err)},onclose=function(){qnt(onclosenexttick)},onclosenexttick=function(){if(!cancelled){if(readable&&!(rs&&rs.ended&&!rs.destroyed))return callback.call(stream,new Error("premature close"));if(writable&&!(ws&&ws.ended&&!ws.destroyed))return callback.call(stream,new Error("premature close"))}},onrequest=function(){stream.req.on("finish",onfinish)};return isRequest(stream)?(stream.on("complete",onfinish),stream.on("abort",onclose),stream.req?onrequest():stream.on("request",onrequest)):writable&&!ws&&(stream.on("end",onlegacyfinish),stream.on("close",onlegacyfinish)),isChildProcess(stream)&&stream.on("exit",onexit),stream.on("end",onend),stream.on("finish",onfinish),opts.error!==!1&&stream.on("error",onerror),stream.on("close",onclose),function(){cancelled=!0,stream.removeListener("complete",onfinish),stream.removeListener("abort",onclose),stream.removeListener("request",onrequest),stream.req&&stream.req.removeListener("finish",onfinish),stream.removeListener("end",onlegacyfinish),stream.removeListener("close",onlegacyfinish),stream.removeListener("finish",onfinish),stream.removeListener("exit",onexit),stream.removeListener("end",onend),stream.removeListener("error",onerror),stream.removeListener("close",onclose)}};module.exports=eos}});var require_pump=__commonJS({"../../node_modules/.pnpm/pump@3.0.4/node_modules/pump/index.js"(exports,module){var once=require_once(),eos=require_end_of_stream(),fs21;try{fs21=__require("fs")}catch{}var noop=function(){},ancient=typeof process>"u"?!1:/^v?\.0/.test(process.version),isFn=function(fn){return typeof fn=="function"},isFS=function(stream){return!ancient||!fs21?!1:(stream instanceof(fs21.ReadStream||noop)||stream instanceof(fs21.WriteStream||noop))&&isFn(stream.close)},isRequest=function(stream){return stream.setHeader&&isFn(stream.abort)},destroyer=function(stream,reading,writing,callback){callback=once(callback);var closed=!1;stream.on("close",function(){closed=!0}),eos(stream,{readable:reading,writable:writing},function(err){if(err)return callback(err);closed=!0,callback()});var destroyed=!1;return function(err){if(!closed&&!destroyed){if(destroyed=!0,isFS(stream))return stream.close(noop);if(isRequest(stream))return stream.abort();if(isFn(stream.destroy))return stream.destroy();callback(err||new Error("stream was destroyed"))}}},call=function(fn){fn()},pipe2=function(from,to){return from.pipe(to)},pump=function(){var streams=Array.prototype.slice.call(arguments),callback=isFn(streams[streams.length-1]||noop)&&streams.pop()||noop;if(Array.isArray(streams[0])&&(streams=streams[0]),streams.length<2)throw new Error("pump requires two streams per minimum");var error48,destroys=streams.map(function(stream,i){var reading=i<streams.length-1,writing=i>0;return destroyer(stream,reading,writing,function(err){error48||(error48=err),err&&destroys.forEach(call),!reading&&(destroys.forEach(call),callback(error48))})});return streams.reduce(pipe2)};module.exports=pump}});var require_buffer_stream=__commonJS({"../../node_modules/.pnpm/get-stream@5.2.0/node_modules/get-stream/buffer-stream.js"(exports,module){"use strict";var{PassThrough:PassThroughStream}=__require("stream");module.exports=options=>{options={...options};let{array:array2}=options,{encoding}=options,isBuffer=encoding==="buffer",objectMode=!1;array2?objectMode=!(encoding||isBuffer):encoding=encoding||"utf8",isBuffer&&(encoding=null);let stream=new PassThroughStream({objectMode});encoding&&stream.setEncoding(encoding);let length=0,chunks=[];return stream.on("data",chunk=>{chunks.push(chunk),objectMode?length=chunks.length:length+=chunk.length}),stream.getBufferedValue=()=>array2?chunks:isBuffer?Buffer.concat(chunks,length):chunks.join(""),stream.getBufferedLength=()=>length,stream}}});var require_get_stream=__commonJS({"../../node_modules/.pnpm/get-stream@5.2.0/node_modules/get-stream/index.js"(exports,module){"use strict";var{constants:BufferConstants}=__require("buffer"),pump=require_pump(),bufferStream=require_buffer_stream(),MaxBufferError=class extends Error{constructor(){super("maxBuffer exceeded"),this.name="MaxBufferError"}};async function getStream(inputStream,options){if(!inputStream)return Promise.reject(new Error("Expected a stream"));options={maxBuffer:1/0,...options};let{maxBuffer}=options,stream;return await new Promise((resolve3,reject)=>{let rejectPromise=error48=>{error48&&stream.getBufferedLength()<=BufferConstants.MAX_LENGTH&&(error48.bufferedData=stream.getBufferedValue()),reject(error48)};stream=pump(inputStream,bufferStream(options),error48=>{if(error48){rejectPromise(error48);return}resolve3()}),stream.on("data",()=>{stream.getBufferedLength()>maxBuffer&&rejectPromise(new MaxBufferError)})}),stream.getBufferedValue()}module.exports=getStream;module.exports.default=getStream;module.exports.buffer=(stream,options)=>getStream(stream,{...options,encoding:"buffer"});module.exports.array=(stream,options)=>getStream(stream,{...options,array:!0});module.exports.MaxBufferError=MaxBufferError}});var require_pend=__commonJS({"../../node_modules/.pnpm/pend@1.2.0/node_modules/pend/index.js"(exports,module){module.exports=Pend;function Pend(){this.pending=0,this.max=1/0,this.listeners=[],this.waiting=[],this.error=null}Pend.prototype.go=function(fn){this.pending<this.max?pendGo(this,fn):this.waiting.push(fn)};Pend.prototype.wait=function(cb){this.pending===0?cb(this.error):this.listeners.push(cb)};Pend.prototype.hold=function(){return pendHold(this)};function pendHold(self2){self2.pending+=1;var called=!1;return onCb;function onCb(err){if(called)throw new Error("callback called twice");if(called=!0,self2.error=self2.error||err,self2.pending-=1,self2.waiting.length>0&&self2.pending<self2.max)pendGo(self2,self2.waiting.shift());else if(self2.pending===0){var listeners=self2.listeners;self2.listeners=[],listeners.forEach(cbListener)}}function cbListener(listener){listener(self2.error)}}function pendGo(self2,fn){fn(pendHold(self2))}}});var require_fd_slicer=__commonJS({"../../node_modules/.pnpm/fd-slicer@1.1.0/node_modules/fd-slicer/index.js"(exports){var fs21=__require("fs"),util2=__require("util"),stream=__require("stream"),Readable2=stream.Readable,Writable2=stream.Writable,PassThrough=stream.PassThrough,Pend=require_pend(),EventEmitter=__require("events").EventEmitter;exports.createFromBuffer=createFromBuffer;exports.createFromFd=createFromFd;exports.BufferSlicer=BufferSlicer;exports.FdSlicer=FdSlicer;util2.inherits(FdSlicer,EventEmitter);function FdSlicer(fd,options){options=options||{},EventEmitter.call(this),this.fd=fd,this.pend=new Pend,this.pend.max=1,this.refCount=0,this.autoClose=!!options.autoClose}FdSlicer.prototype.read=function(buffer,offset,length,position,callback){var self2=this;self2.pend.go(function(cb){fs21.read(self2.fd,buffer,offset,length,position,function(err,bytesRead,buffer2){cb(),callback(err,bytesRead,buffer2)})})};FdSlicer.prototype.write=function(buffer,offset,length,position,callback){var self2=this;self2.pend.go(function(cb){fs21.write(self2.fd,buffer,offset,length,position,function(err,written,buffer2){cb(),callback(err,written,buffer2)})})};FdSlicer.prototype.createReadStream=function(options){return new ReadStream(this,options)};FdSlicer.prototype.createWriteStream=function(options){return new WriteStream(this,options)};FdSlicer.prototype.ref=function(){this.refCount+=1};FdSlicer.prototype.unref=function(){var self2=this;if(self2.refCount-=1,self2.refCount>0)return;if(self2.refCount<0)throw new Error("invalid unref");self2.autoClose&&fs21.close(self2.fd,onCloseDone);function onCloseDone(err){err?self2.emit("error",err):self2.emit("close")}};util2.inherits(ReadStream,Readable2);function ReadStream(context,options){options=options||{},Readable2.call(this,options),this.context=context,this.context.ref(),this.start=options.start||0,this.endOffset=options.end,this.pos=this.start,this.destroyed=!1}ReadStream.prototype._read=function(n){var self2=this;if(!self2.destroyed){var toRead=Math.min(self2._readableState.highWaterMark,n);if(self2.endOffset!=null&&(toRead=Math.min(toRead,self2.endOffset-self2.pos)),toRead<=0){self2.destroyed=!0,self2.push(null),self2.context.unref();return}self2.context.pend.go(function(cb){if(self2.destroyed)return cb();var buffer=new Buffer(toRead);fs21.read(self2.context.fd,buffer,0,toRead,self2.pos,function(err,bytesRead){err?self2.destroy(err):bytesRead===0?(self2.destroyed=!0,self2.push(null),self2.context.unref()):(self2.pos+=bytesRead,self2.push(buffer.slice(0,bytesRead))),cb()})})}};ReadStream.prototype.destroy=function(err){this.destroyed||(err=err||new Error("stream destroyed"),this.destroyed=!0,this.emit("error",err),this.context.unref())};util2.inherits(WriteStream,Writable2);function WriteStream(context,options){options=options||{},Writable2.call(this,options),this.context=context,this.context.ref(),this.start=options.start||0,this.endOffset=options.end==null?1/0:+options.end,this.bytesWritten=0,this.pos=this.start,this.destroyed=!1,this.on("finish",this.destroy.bind(this))}WriteStream.prototype._write=function(buffer,encoding,callback){var self2=this;if(!self2.destroyed){if(self2.pos+buffer.length>self2.endOffset){var err=new Error("maximum file length exceeded");err.code="ETOOBIG",self2.destroy(),callback(err);return}self2.context.pend.go(function(cb){if(self2.destroyed)return cb();fs21.write(self2.context.fd,buffer,0,buffer.length,self2.pos,function(err2,bytes){err2?(self2.destroy(),cb(),callback(err2)):(self2.bytesWritten+=bytes,self2.pos+=bytes,self2.emit("progress"),cb(),callback())})})}};WriteStream.prototype.destroy=function(){this.destroyed||(this.destroyed=!0,this.context.unref())};util2.inherits(BufferSlicer,EventEmitter);function BufferSlicer(buffer,options){EventEmitter.call(this),options=options||{},this.refCount=0,this.buffer=buffer,this.maxChunkSize=options.maxChunkSize||Number.MAX_SAFE_INTEGER}BufferSlicer.prototype.read=function(buffer,offset,length,position,callback){var end=position+length,delta=end-this.buffer.length,written=delta>0?delta:length;this.buffer.copy(buffer,offset,position,end),setImmediate(function(){callback(null,written)})};BufferSlicer.prototype.write=function(buffer,offset,length,position,callback){buffer.copy(this.buffer,position,offset,offset+length),setImmediate(function(){callback(null,length,buffer)})};BufferSlicer.prototype.createReadStream=function(options){options=options||{};var readStream=new PassThrough(options);readStream.destroyed=!1,readStream.start=options.start||0,readStream.endOffset=options.end,readStream.pos=readStream.endOffset||this.buffer.length;for(var entireSlice=this.buffer.slice(readStream.start,readStream.pos),offset=0;;){var nextOffset=offset+this.maxChunkSize;if(nextOffset>=entireSlice.length){offset<entireSlice.length&&readStream.write(entireSlice.slice(offset,entireSlice.length));break}readStream.write(entireSlice.slice(offset,nextOffset)),offset=nextOffset}return readStream.end(),readStream.destroy=function(){readStream.destroyed=!0},readStream};BufferSlicer.prototype.createWriteStream=function(options){var bufferSlicer=this;options=options||{};var writeStream=new Writable2(options);return writeStream.start=options.start||0,writeStream.endOffset=options.end==null?this.buffer.length:+options.end,writeStream.bytesWritten=0,writeStream.pos=writeStream.start,writeStream.destroyed=!1,writeStream._write=function(buffer,encoding,callback){if(!writeStream.destroyed){var end=writeStream.pos+buffer.length;if(end>writeStream.endOffset){var err=new Error("maximum file length exceeded");err.code="ETOOBIG",writeStream.destroyed=!0,callback(err);return}buffer.copy(bufferSlicer.buffer,writeStream.pos,0,buffer.length),writeStream.bytesWritten+=buffer.length,writeStream.pos=end,writeStream.emit("progress"),callback()}},writeStream.destroy=function(){writeStream.destroyed=!0},writeStream};BufferSlicer.prototype.ref=function(){this.refCount+=1};BufferSlicer.prototype.unref=function(){if(this.refCount-=1,this.refCount<0)throw new Error("invalid unref")};function createFromBuffer(buffer,options){return new BufferSlicer(buffer,options)}function createFromFd(fd,options){return new FdSlicer(fd,options)}}});var require_buffer_crc32=__commonJS({"../../node_modules/.pnpm/buffer-crc32@0.2.13/node_modules/buffer-crc32/index.js"(exports,module){var Buffer2=__require("buffer").Buffer,CRC_TABLE=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];typeof Int32Array<"u"&&(CRC_TABLE=new Int32Array(CRC_TABLE));function ensureBuffer(input){if(Buffer2.isBuffer(input))return input;var hasNewBufferAPI=typeof Buffer2.alloc=="function"&&typeof Buffer2.from=="function";if(typeof input=="number")return hasNewBufferAPI?Buffer2.alloc(input):new Buffer2(input);if(typeof input=="string")return hasNewBufferAPI?Buffer2.from(input):new Buffer2(input);throw new Error("input must be buffer, number, or string, received "+typeof input)}function bufferizeInt(num){var tmp=ensureBuffer(4);return tmp.writeInt32BE(num,0),tmp}function _crc32(buf,previous){buf=ensureBuffer(buf),Buffer2.isBuffer(previous)&&(previous=previous.readUInt32BE(0));for(var crc=~~previous^-1,n=0;n<buf.length;n++)crc=CRC_TABLE[(crc^buf[n])&255]^crc>>>8;return crc^-1}function crc32(){return bufferizeInt(_crc32.apply(null,arguments))}crc32.signed=function(){return _crc32.apply(null,arguments)};crc32.unsigned=function(){return _crc32.apply(null,arguments)>>>0};module.exports=crc32}});var require_yauzl=__commonJS({"../../node_modules/.pnpm/yauzl@2.10.0/node_modules/yauzl/index.js"(exports){var fs21=__require("fs"),zlib=__require("zlib"),fd_slicer=require_fd_slicer(),crc32=require_buffer_crc32(),util2=__require("util"),EventEmitter=__require("events").EventEmitter,Transform=__require("stream").Transform,PassThrough=__require("stream").PassThrough,Writable2=__require("stream").Writable;exports.open=open2;exports.fromFd=fromFd;exports.fromBuffer=fromBuffer;exports.fromRandomAccessReader=fromRandomAccessReader;exports.dosDateTimeToDate=dosDateTimeToDate;exports.validateFileName=validateFileName;exports.ZipFile=ZipFile;exports.Entry=Entry;exports.RandomAccessReader=RandomAccessReader;function open2(path23,options,callback){typeof options=="function"&&(callback=options,options=null),options==null&&(options={}),options.autoClose==null&&(options.autoClose=!0),options.lazyEntries==null&&(options.lazyEntries=!1),options.decodeStrings==null&&(options.decodeStrings=!0),options.validateEntrySizes==null&&(options.validateEntrySizes=!0),options.strictFileNames==null&&(options.strictFileNames=!1),callback==null&&(callback=defaultCallback),fs21.open(path23,"r",function(err,fd){if(err)return callback(err);fromFd(fd,options,function(err2,zipfile){err2&&fs21.close(fd,defaultCallback),callback(err2,zipfile)})})}function fromFd(fd,options,callback){typeof options=="function"&&(callback=options,options=null),options==null&&(options={}),options.autoClose==null&&(options.autoClose=!1),options.lazyEntries==null&&(options.lazyEntries=!1),options.decodeStrings==null&&(options.decodeStrings=!0),options.validateEntrySizes==null&&(options.validateEntrySizes=!0),options.strictFileNames==null&&(options.strictFileNames=!1),callback==null&&(callback=defaultCallback),fs21.fstat(fd,function(err,stats){if(err)return callback(err);var reader=fd_slicer.createFromFd(fd,{autoClose:!0});fromRandomAccessReader(reader,stats.size,options,callback)})}function fromBuffer(buffer,options,callback){typeof options=="function"&&(callback=options,options=null),options==null&&(options={}),options.autoClose=!1,options.lazyEntries==null&&(options.lazyEntries=!1),options.decodeStrings==null&&(options.decodeStrings=!0),options.validateEntrySizes==null&&(options.validateEntrySizes=!0),options.strictFileNames==null&&(options.strictFileNames=!1);var reader=fd_slicer.createFromBuffer(buffer,{maxChunkSize:65536});fromRandomAccessReader(reader,buffer.length,options,callback)}function fromRandomAccessReader(reader,totalSize,options,callback){typeof options=="function"&&(callback=options,options=null),options==null&&(options={}),options.autoClose==null&&(options.autoClose=!0),options.lazyEntries==null&&(options.lazyEntries=!1),options.decodeStrings==null&&(options.decodeStrings=!0);var decodeStrings=!!options.decodeStrings;if(options.validateEntrySizes==null&&(options.validateEntrySizes=!0),options.strictFileNames==null&&(options.strictFileNames=!1),callback==null&&(callback=defaultCallback),typeof totalSize!="number")throw new Error("expected totalSize parameter to be a number");if(totalSize>Number.MAX_SAFE_INTEGER)throw new Error("zip file too large. only file sizes up to 2^52 are supported due to JavaScript's Number type being an IEEE 754 double.");reader.ref();var eocdrWithoutCommentSize=22,maxCommentSize=65535,bufferSize=Math.min(eocdrWithoutCommentSize+maxCommentSize,totalSize),buffer=newBuffer(bufferSize),bufferReadStart=totalSize-buffer.length;readAndAssertNoEof(reader,buffer,0,bufferSize,bufferReadStart,function(err){if(err)return callback(err);for(var i=bufferSize-eocdrWithoutCommentSize;i>=0;i-=1)if(buffer.readUInt32LE(i)===101010256){var eocdrBuffer=buffer.slice(i),diskNumber=eocdrBuffer.readUInt16LE(4);if(diskNumber!==0)return callback(new Error("multi-disk zip files are not supported: found disk number: "+diskNumber));var entryCount=eocdrBuffer.readUInt16LE(10),centralDirectoryOffset=eocdrBuffer.readUInt32LE(16),commentLength=eocdrBuffer.readUInt16LE(20),expectedCommentLength=eocdrBuffer.length-eocdrWithoutCommentSize;if(commentLength!==expectedCommentLength)return callback(new Error("invalid comment length. expected: "+expectedCommentLength+". found: "+commentLength));var comment=decodeStrings?decodeBuffer(eocdrBuffer,22,eocdrBuffer.length,!1):eocdrBuffer.slice(22);if(!(entryCount===65535||centralDirectoryOffset===4294967295))return callback(null,new ZipFile(reader,centralDirectoryOffset,totalSize,entryCount,comment,options.autoClose,options.lazyEntries,decodeStrings,options.validateEntrySizes,options.strictFileNames));var zip64EocdlBuffer=newBuffer(20),zip64EocdlOffset=bufferReadStart+i-zip64EocdlBuffer.length;readAndAssertNoEof(reader,zip64EocdlBuffer,0,zip64EocdlBuffer.length,zip64EocdlOffset,function(err2){if(err2)return callback(err2);if(zip64EocdlBuffer.readUInt32LE(0)!==117853008)return callback(new Error("invalid zip64 end of central directory locator signature"));var zip64EocdrOffset=readUInt64LE(zip64EocdlBuffer,8),zip64EocdrBuffer=newBuffer(56);readAndAssertNoEof(reader,zip64EocdrBuffer,0,zip64EocdrBuffer.length,zip64EocdrOffset,function(err3){return err3?callback(err3):zip64EocdrBuffer.readUInt32LE(0)!==101075792?callback(new Error("invalid zip64 end of central directory record signature")):(entryCount=readUInt64LE(zip64EocdrBuffer,32),centralDirectoryOffset=readUInt64LE(zip64EocdrBuffer,48),callback(null,new ZipFile(reader,centralDirectoryOffset,totalSize,entryCount,comment,options.autoClose,options.lazyEntries,decodeStrings,options.validateEntrySizes,options.strictFileNames)))})});return}callback(new Error("end of central directory record signature not found"))})}util2.inherits(ZipFile,EventEmitter);function ZipFile(reader,centralDirectoryOffset,fileSize,entryCount,comment,autoClose,lazyEntries,decodeStrings,validateEntrySizes,strictFileNames){var self2=this;EventEmitter.call(self2),self2.reader=reader,self2.reader.on("error",function(err){emitError(self2,err)}),self2.reader.once("close",function(){self2.emit("close")}),self2.readEntryCursor=centralDirectoryOffset,self2.fileSize=fileSize,self2.entryCount=entryCount,self2.comment=comment,self2.entriesRead=0,self2.autoClose=!!autoClose,self2.lazyEntries=!!lazyEntries,self2.decodeStrings=!!decodeStrings,self2.validateEntrySizes=!!validateEntrySizes,self2.strictFileNames=!!strictFileNames,self2.isOpen=!0,self2.emittedError=!1,self2.lazyEntries||self2._readEntry()}ZipFile.prototype.close=function(){this.isOpen&&(this.isOpen=!1,this.reader.unref())};function emitErrorAndAutoClose(self2,err){self2.autoClose&&self2.close(),emitError(self2,err)}function emitError(self2,err){self2.emittedError||(self2.emittedError=!0,self2.emit("error",err))}ZipFile.prototype.readEntry=function(){if(!this.lazyEntries)throw new Error("readEntry() called without lazyEntries:true");this._readEntry()};ZipFile.prototype._readEntry=function(){var self2=this;if(self2.entryCount===self2.entriesRead){setImmediate(function(){self2.autoClose&&self2.close(),!self2.emittedError&&self2.emit("end")});return}if(!self2.emittedError){var buffer=newBuffer(46);readAndAssertNoEof(self2.reader,buffer,0,buffer.length,self2.readEntryCursor,function(err){if(err)return emitErrorAndAutoClose(self2,err);if(!self2.emittedError){var entry=new Entry,signature=buffer.readUInt32LE(0);if(signature!==33639248)return emitErrorAndAutoClose(self2,new Error("invalid central directory file header signature: 0x"+signature.toString(16)));if(entry.versionMadeBy=buffer.readUInt16LE(4),entry.versionNeededToExtract=buffer.readUInt16LE(6),entry.generalPurposeBitFlag=buffer.readUInt16LE(8),entry.compressionMethod=buffer.readUInt16LE(10),entry.lastModFileTime=buffer.readUInt16LE(12),entry.lastModFileDate=buffer.readUInt16LE(14),entry.crc32=buffer.readUInt32LE(16),entry.compressedSize=buffer.readUInt32LE(20),entry.uncompressedSize=buffer.readUInt32LE(24),entry.fileNameLength=buffer.readUInt16LE(28),entry.extraFieldLength=buffer.readUInt16LE(30),entry.fileCommentLength=buffer.readUInt16LE(32),entry.internalFileAttributes=buffer.readUInt16LE(36),entry.externalFileAttributes=buffer.readUInt32LE(38),entry.relativeOffsetOfLocalHeader=buffer.readUInt32LE(42),entry.generalPurposeBitFlag&64)return emitErrorAndAutoClose(self2,new Error("strong encryption is not supported"));self2.readEntryCursor+=46,buffer=newBuffer(entry.fileNameLength+entry.extraFieldLength+entry.fileCommentLength),readAndAssertNoEof(self2.reader,buffer,0,buffer.length,self2.readEntryCursor,function(err2){if(err2)return emitErrorAndAutoClose(self2,err2);if(!self2.emittedError){var isUtf8=(entry.generalPurposeBitFlag&2048)!==0;entry.fileName=self2.decodeStrings?decodeBuffer(buffer,0,entry.fileNameLength,isUtf8):buffer.slice(0,entry.fileNameLength);var fileCommentStart=entry.fileNameLength+entry.extraFieldLength,extraFieldBuffer=buffer.slice(entry.fileNameLength,fileCommentStart);entry.extraFields=[];for(var i=0;i<extraFieldBuffer.length-3;){var headerId=extraFieldBuffer.readUInt16LE(i+0),dataSize=extraFieldBuffer.readUInt16LE(i+2),dataStart=i+4,dataEnd=dataStart+dataSize;if(dataEnd>extraFieldBuffer.length)return emitErrorAndAutoClose(self2,new Error("extra field length exceeds extra field buffer size"));var dataBuffer=newBuffer(dataSize);extraFieldBuffer.copy(dataBuffer,0,dataStart,dataEnd),entry.extraFields.push({id:headerId,data:dataBuffer}),i=dataEnd}if(entry.fileComment=self2.decodeStrings?decodeBuffer(buffer,fileCommentStart,fileCommentStart+entry.fileCommentLength,isUtf8):buffer.slice(fileCommentStart,fileCommentStart+entry.fileCommentLength),entry.comment=entry.fileComment,self2.readEntryCursor+=buffer.length,self2.entriesRead+=1,entry.uncompressedSize===4294967295||entry.compressedSize===4294967295||entry.relativeOffsetOfLocalHeader===4294967295){for(var zip64EiefBuffer=null,i=0;i<entry.extraFields.length;i++){var extraField=entry.extraFields[i];if(extraField.id===1){zip64EiefBuffer=extraField.data;break}}if(zip64EiefBuffer==null)return emitErrorAndAutoClose(self2,new Error("expected zip64 extended information extra field"));var index=0;if(entry.uncompressedSize===4294967295){if(index+8>zip64EiefBuffer.length)return emitErrorAndAutoClose(self2,new Error("zip64 extended information extra field does not include uncompressed size"));entry.uncompressedSize=readUInt64LE(zip64EiefBuffer,index),index+=8}if(entry.compressedSize===4294967295){if(index+8>zip64EiefBuffer.length)return emitErrorAndAutoClose(self2,new Error("zip64 extended information extra field does not include compressed size"));entry.compressedSize=readUInt64LE(zip64EiefBuffer,index),index+=8}if(entry.relativeOffsetOfLocalHeader===4294967295){if(index+8>zip64EiefBuffer.length)return emitErrorAndAutoClose(self2,new Error("zip64 extended information extra field does not include relative header offset"));entry.relativeOffsetOfLocalHeader=readUInt64LE(zip64EiefBuffer,index),index+=8}}if(self2.decodeStrings)for(var i=0;i<entry.extraFields.length;i++){var extraField=entry.extraFields[i];if(extraField.id===28789){if(extraField.data.length<6||extraField.data.readUInt8(0)!==1)continue;var oldNameCrc32=extraField.data.readUInt32LE(1);if(crc32.unsigned(buffer.slice(0,entry.fileNameLength))!==oldNameCrc32)continue;entry.fileName=decodeBuffer(extraField.data,5,extraField.data.length,!0);break}}if(self2.validateEntrySizes&&entry.compressionMethod===0){var expectedCompressedSize=entry.uncompressedSize;if(entry.isEncrypted()&&(expectedCompressedSize+=12),entry.compressedSize!==expectedCompressedSize){var msg="compressed/uncompressed size mismatch for stored file: "+entry.compressedSize+" != "+entry.uncompressedSize;return emitErrorAndAutoClose(self2,new Error(msg))}}if(self2.decodeStrings){self2.strictFileNames||(entry.fileName=entry.fileName.replace(/\\/g,"/"));var errorMessage2=validateFileName(entry.fileName,self2.validateFileNameOptions);if(errorMessage2!=null)return emitErrorAndAutoClose(self2,new Error(errorMessage2))}self2.emit("entry",entry),self2.lazyEntries||self2._readEntry()}})}})}};ZipFile.prototype.openReadStream=function(entry,options,callback){var self2=this,relativeStart=0,relativeEnd=entry.compressedSize;if(callback==null)callback=options,options={};else{if(options.decrypt!=null){if(!entry.isEncrypted())throw new Error("options.decrypt can only be specified for encrypted entries");if(options.decrypt!==!1)throw new Error("invalid options.decrypt value: "+options.decrypt);if(entry.isCompressed()&&options.decompress!==!1)throw new Error("entry is encrypted and compressed, and options.decompress !== false")}if(options.decompress!=null){if(!entry.isCompressed())throw new Error("options.decompress can only be specified for compressed entries");if(!(options.decompress===!1||options.decompress===!0))throw new Error("invalid options.decompress value: "+options.decompress)}if(options.start!=null||options.end!=null){if(entry.isCompressed()&&options.decompress!==!1)throw new Error("start/end range not allowed for compressed entry without options.decompress === false");if(entry.isEncrypted()&&options.decrypt!==!1)throw new Error("start/end range not allowed for encrypted entry without options.decrypt === false")}if(options.start!=null){if(relativeStart=options.start,relativeStart<0)throw new Error("options.start < 0");if(relativeStart>entry.compressedSize)throw new Error("options.start > entry.compressedSize")}if(options.end!=null){if(relativeEnd=options.end,relativeEnd<0)throw new Error("options.end < 0");if(relativeEnd>entry.compressedSize)throw new Error("options.end > entry.compressedSize");if(relativeEnd<relativeStart)throw new Error("options.end < options.start")}}if(!self2.isOpen)return callback(new Error("closed"));if(entry.isEncrypted()&&options.decrypt!==!1)return callback(new Error("entry is encrypted, and options.decrypt !== false"));self2.reader.ref();var buffer=newBuffer(30);readAndAssertNoEof(self2.reader,buffer,0,buffer.length,entry.relativeOffsetOfLocalHeader,function(err){try{if(err)return callback(err);var signature=buffer.readUInt32LE(0);if(signature!==67324752)return callback(new Error("invalid local file header signature: 0x"+signature.toString(16)));var fileNameLength=buffer.readUInt16LE(26),extraFieldLength=buffer.readUInt16LE(28),localFileHeaderEnd=entry.relativeOffsetOfLocalHeader+buffer.length+fileNameLength+extraFieldLength,decompress;if(entry.compressionMethod===0)decompress=!1;else if(entry.compressionMethod===8)decompress=options.decompress!=null?options.decompress:!0;else return callback(new Error("unsupported compression method: "+entry.compressionMethod));var fileDataStart=localFileHeaderEnd,fileDataEnd=fileDataStart+entry.compressedSize;if(entry.compressedSize!==0&&fileDataEnd>self2.fileSize)return callback(new Error("file data overflows file bounds: "+fileDataStart+" + "+entry.compressedSize+" > "+self2.fileSize));var readStream=self2.reader.createReadStream({start:fileDataStart+relativeStart,end:fileDataStart+relativeEnd}),endpointStream=readStream;if(decompress){var destroyed=!1,inflateFilter=zlib.createInflateRaw();readStream.on("error",function(err2){setImmediate(function(){destroyed||inflateFilter.emit("error",err2)})}),readStream.pipe(inflateFilter),self2.validateEntrySizes?(endpointStream=new AssertByteCountStream(entry.uncompressedSize),inflateFilter.on("error",function(err2){setImmediate(function(){destroyed||endpointStream.emit("error",err2)})}),inflateFilter.pipe(endpointStream)):endpointStream=inflateFilter,endpointStream.destroy=function(){destroyed=!0,inflateFilter!==endpointStream&&inflateFilter.unpipe(endpointStream),readStream.unpipe(inflateFilter),readStream.destroy()}}callback(null,endpointStream)}finally{self2.reader.unref()}})};function Entry(){}Entry.prototype.getLastModDate=function(){return dosDateTimeToDate(this.lastModFileDate,this.lastModFileTime)};Entry.prototype.isEncrypted=function(){return(this.generalPurposeBitFlag&1)!==0};Entry.prototype.isCompressed=function(){return this.compressionMethod===8};function dosDateTimeToDate(date5,time3){var day=date5&31,month=(date5>>5&15)-1,year=(date5>>9&127)+1980,millisecond=0,second=(time3&31)*2,minute=time3>>5&63,hour=time3>>11&31;return new Date(year,month,day,hour,minute,second,millisecond)}function validateFileName(fileName){return fileName.indexOf("\\")!==-1?"invalid characters in fileName: "+fileName:/^[a-zA-Z]:/.test(fileName)||/^\//.test(fileName)?"absolute path: "+fileName:fileName.split("/").indexOf("..")!==-1?"invalid relative path: "+fileName:null}function readAndAssertNoEof(reader,buffer,offset,length,position,callback){if(length===0)return setImmediate(function(){callback(null,newBuffer(0))});reader.read(buffer,offset,length,position,function(err,bytesRead){if(err)return callback(err);if(bytesRead<length)return callback(new Error("unexpected EOF"));callback()})}util2.inherits(AssertByteCountStream,Transform);function AssertByteCountStream(byteCount){Transform.call(this),this.actualByteCount=0,this.expectedByteCount=byteCount}AssertByteCountStream.prototype._transform=function(chunk,encoding,cb){if(this.actualByteCount+=chunk.length,this.actualByteCount>this.expectedByteCount){var msg="too many bytes in the stream. expected "+this.expectedByteCount+". got at least "+this.actualByteCount;return cb(new Error(msg))}cb(null,chunk)};AssertByteCountStream.prototype._flush=function(cb){if(this.actualByteCount<this.expectedByteCount){var msg="not enough bytes in the stream. expected "+this.expectedByteCount+". got only "+this.actualByteCount;return cb(new Error(msg))}cb()};util2.inherits(RandomAccessReader,EventEmitter);function RandomAccessReader(){EventEmitter.call(this),this.refCount=0}RandomAccessReader.prototype.ref=function(){this.refCount+=1};RandomAccessReader.prototype.unref=function(){var self2=this;if(self2.refCount-=1,self2.refCount>0)return;if(self2.refCount<0)throw new Error("invalid unref");self2.close(onCloseDone);function onCloseDone(err){if(err)return self2.emit("error",err);self2.emit("close")}};RandomAccessReader.prototype.createReadStream=function(options){var start=options.start,end=options.end;if(start===end){var emptyStream=new PassThrough;return setImmediate(function(){emptyStream.end()}),emptyStream}var stream=this._readStreamForRange(start,end),destroyed=!1,refUnrefFilter=new RefUnrefFilter(this);stream.on("error",function(err){setImmediate(function(){destroyed||refUnrefFilter.emit("error",err)})}),refUnrefFilter.destroy=function(){stream.unpipe(refUnrefFilter),refUnrefFilter.unref(),stream.destroy()};var byteCounter=new AssertByteCountStream(end-start);return refUnrefFilter.on("error",function(err){setImmediate(function(){destroyed||byteCounter.emit("error",err)})}),byteCounter.destroy=function(){destroyed=!0,refUnrefFilter.unpipe(byteCounter),refUnrefFilter.destroy()},stream.pipe(refUnrefFilter).pipe(byteCounter)};RandomAccessReader.prototype._readStreamForRange=function(start,end){throw new Error("not implemented")};RandomAccessReader.prototype.read=function(buffer,offset,length,position,callback){var readStream=this.createReadStream({start:position,end:position+length}),writeStream=new Writable2,written=0;writeStream._write=function(chunk,encoding,cb){chunk.copy(buffer,offset+written,0,chunk.length),written+=chunk.length,cb()},writeStream.on("finish",callback),readStream.on("error",function(error48){callback(error48)}),readStream.pipe(writeStream)};RandomAccessReader.prototype.close=function(callback){setImmediate(callback)};util2.inherits(RefUnrefFilter,PassThrough);function RefUnrefFilter(context){PassThrough.call(this),this.context=context,this.context.ref(),this.unreffedYet=!1}RefUnrefFilter.prototype._flush=function(cb){this.unref(),cb()};RefUnrefFilter.prototype.unref=function(cb){this.unreffedYet||(this.unreffedYet=!0,this.context.unref())};var cp437="\0âēâģâĨâĻâŖâ âĸââââââĒâĢâŧâēâââŧÂļ§âŦâ¨âââââââ˛âŧ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~âÃÃŧÊÃĸäà ÃĨçÃĒÃĢèïÎÃŦÃÃ
ÃÃĻÃôÃļÃ˛ÃģÚÃŋÃÃÂĸÂŖÂĨâ§ÆÃĄÃÃŗÃēÃąÃÂĒÂēÂŋâÂŦÂŊÂŧÂĄÂĢÂģâââââ¤âĄâĸâââŖââââââââ´âŦâââŧâââââŠâĻâ ââŦâ§â¨â¤âĨâââââĢâĒâââââââÎąÃÎĪÎŖĪÂĩĪÎĻÎΊδâĪÎĩâŠâĄÂąâĨâ¤â âĄÃˇâ°â¡ââŋ²â  ";function decodeBuffer(buffer,start,end,isUtf8){if(isUtf8)return buffer.toString("utf8",start,end);for(var result="",i=start;i<end;i++)result+=cp437[buffer[i]];return result}function readUInt64LE(buffer,offset){var lower32=buffer.readUInt32LE(offset),upper32=buffer.readUInt32LE(offset+4);return upper32*4294967296+lower32}var newBuffer;typeof Buffer.allocUnsafe=="function"?newBuffer=function(len){return Buffer.allocUnsafe(len)}:newBuffer=function(len){return new Buffer(len)};function defaultCallback(err){if(err)throw err}}});var require_extract_zip=__commonJS({"../../node_modules/.pnpm/extract-zip@2.0.1/node_modules/extract-zip/index.js"(exports,module){var debug=require_src()("extract-zip"),{createWriteStream,promises:fs21}=__require("fs"),getStream=require_get_stream(),path23=__require("path"),{promisify}=__require("util"),stream=__require("stream"),yauzl=require_yauzl(),openZip=promisify(yauzl.open),pipeline=promisify(stream.pipeline),Extractor=class{constructor(zipPath,opts){this.zipPath=zipPath,this.opts=opts}async extract(){return debug("opening",this.zipPath,"with opts",this.opts),this.zipfile=await openZip(this.zipPath,{lazyEntries:!0}),this.canceled=!1,new Promise((resolve3,reject)=>{this.zipfile.on("error",err=>{this.canceled=!0,reject(err)}),this.zipfile.readEntry(),this.zipfile.on("close",()=>{this.canceled||(debug("zip extraction complete"),resolve3())}),this.zipfile.on("entry",async entry=>{if(this.canceled){debug("skipping entry",entry.fileName,{cancelled:this.canceled});return}if(debug("zipfile entry",entry.fileName),entry.fileName.startsWith("__MACOSX/")){this.zipfile.readEntry();return}let destDir=path23.dirname(path23.join(this.opts.dir,entry.fileName));try{await fs21.mkdir(destDir,{recursive:!0});let canonicalDestDir=await fs21.realpath(destDir);if(path23.relative(this.opts.dir,canonicalDestDir).split(path23.sep).includes(".."))throw new Error(`Out of bound path "${canonicalDestDir}" found while processing file ${entry.fileName}`);await this.extractEntry(entry),debug("finished processing",entry.fileName),this.zipfile.readEntry()}catch(err){this.canceled=!0,this.zipfile.close(),reject(err)}})})}async extractEntry(entry){if(this.canceled){debug("skipping entry extraction",entry.fileName,{cancelled:this.canceled});return}this.opts.onEntry&&this.opts.onEntry(entry,this.zipfile);let dest=path23.join(this.opts.dir,entry.fileName),mode=entry.externalFileAttributes>>16&65535,IFMT=61440,IFDIR=16384,symlink=(mode&IFMT)===40960,isDir=(mode&IFMT)===IFDIR;!isDir&&entry.fileName.endsWith("/")&&(isDir=!0);let madeBy=entry.versionMadeBy>>8;isDir||(isDir=madeBy===0&&entry.externalFileAttributes===16),debug("extracting entry",{filename:entry.fileName,isDir,isSymlink:symlink});let procMode=this.getExtractedMode(mode,isDir)&511,destDir=isDir?dest:path23.dirname(dest),mkdirOptions={recursive:!0};if(isDir&&(mkdirOptions.mode=procMode),debug("mkdir",{dir:destDir,...mkdirOptions}),await fs21.mkdir(destDir,mkdirOptions),isDir)return;debug("opening read stream",dest);let readStream=await promisify(this.zipfile.openReadStream.bind(this.zipfile))(entry);if(symlink){let link=await getStream(readStream);debug("creating symlink",link,dest),await fs21.symlink(link,dest)}else await pipeline(readStream,createWriteStream(dest,{mode:procMode}))}getExtractedMode(entryMode,isDir){let mode=entryMode;return mode===0&&(isDir?(this.opts.defaultDirMode&&(mode=parseInt(this.opts.defaultDirMode,10)),mode||(mode=493)):(this.opts.defaultFileMode&&(mode=parseInt(this.opts.defaultFileMode,10)),mode||(mode=420))),mode}};module.exports=async function(zipPath,opts){if(debug("creating target directory",opts.dir),!path23.isAbsolute(opts.dir))throw new Error("Target directory is expected to be absolute");return await fs21.mkdir(opts.dir,{recursive:!0}),opts.dir=await fs21.realpath(opts.dir),new Extractor(zipPath,opts).extract()}}});var runtimeArgs_exports={};__export(runtimeArgs_exports,{parseNativeHostRuntimeArgs:()=>parseNativeHostRuntimeArgs,shouldExitWithoutLegacySocket:()=>shouldExitWithoutLegacySocket});function shouldExitWithoutLegacySocket(options,hasLegacySocket){return!hasLegacySocket&&(options.discoverCdp||options.skipBrowserRegistration)}function stripNativeMessagingLaunchArgs(argv){let[origin,parentWindow,...rest]=argv;return/^chrome-extension:\/\/[a-z]{32}\/$/.test(origin??"")?/^--parent-window=\d+$/.test(parentWindow??"")?rest:argv.slice(1):argv}async function parseNativeHostRuntimeArgs(argv,minimumIdleReleaseMinutes){let args=stripNativeMessagingLaunchArgs(argv),options={},readValue=(index,name)=>{let argument=args[index];if(argument===name){let value=args[index+1];if(value===void 0||value.startsWith("-"))throw new Error(`argument missing for option '${name}'`);return{nextIndex:index+1,value}}return argument?.startsWith(`${name}=`)?{nextIndex:index,value:argument.slice(name.length+1)}:null},parseInteger=(value,label,minimum,maximum)=>{let parsed=Number(value);if(!Number.isInteger(parsed)||parsed<minimum||parsed>maximum)throw new Error(`${label} must be an integer from ${minimum} to ${maximum}`);return parsed};for(let index=0;index<args.length;index+=1){let argument=args[index];if(argument==="--daemon"){options.daemon=!0;continue}if(argument==="--discover-cdp"){options.discoverCdp=!0;continue}if(argument==="--skip-browser-registration"){options.skipBrowserRegistration=!0;continue}if(argument==="--version"||argument==="-v"){options.version=!0;continue}if(argument==="--help"||argument==="-h"){options.help=!0;continue}let cdpPort=readValue(index,"--cdp-port");if(cdpPort){options.cdpPort=parseInteger(cdpPort.value,"cdp-port",1,65535),index=cdpPort.nextIndex;continue}let idleRelease=readValue(index,"--agentbay-idle-release-minutes");if(idleRelease){options.agentBayIdleReleaseMinutes=parseInteger(idleRelease.value,"agentbay-idle-release-minutes",minimumIdleReleaseMinutes,Number.MAX_SAFE_INTEGER),index=idleRelease.nextIndex;continue}let stringOptions=[["--cdp-user-data-dir","cdpUserDataDir"],["--agentbay-session-id","agentBaySessionId"],["--browser-id","browserId"],["--browser-name","browserName"]],matchedStringOption=!1;for(let[name,property]of stringOptions){let parsed=readValue(index,name);if(parsed){options[property]=parsed.value,index=parsed.nextIndex,matchedStringOption=!0;break}}if(!matchedStringOption)throw new Error(argument?.startsWith("-")?`unknown option '${argument}'`:`unexpected argument '${argument}'`)}return{...options.agentBayIdleReleaseMinutes!==void 0?{agentBayIdleReleaseMinutes:options.agentBayIdleReleaseMinutes}:{},...options.agentBaySessionId?{agentBaySessionId:options.agentBaySessionId}:{},browserId:options.browserId??"cdp",browserName:options.browserName??"CDP",cdpPort:options.cdpPort??9222,...options.cdpUserDataDir?{cdpUserDataDir:options.cdpUserDataDir}:{},daemon:options.daemon===!0,discoverCdp:options.discoverCdp===!0,help:options.help===!0,skipBrowserRegistration:options.skipBrowserRegistration===!0,version:options.version===!0}}var init_runtimeArgs=__esm({"src/runtimeArgs.ts"(){"use strict"}});import fs18 from"node:fs";import os9 from"node:os";import path19 from"node:path";import{execFileSync}from"node:child_process";function resolveNativeHostDirectory(options={}){let env=options.env??process.env,home=(options.homedir??os9.homedir)();switch(options.platform??process.platform){case"darwin":return path19.join(home,"Library/Application Support/Google/Chrome/NativeMessagingHosts");case"linux":return path19.join(home,".config/google-chrome/NativeMessagingHosts");case"win32":return path19.join(env.PROGRAMDATA||"C:\\ProgramData","Google\\Chrome\\NativeMessagingHosts");default:throw new Error(`Unsupported platform: ${String(options.platform??process.platform)}`)}}function unregisterWindowsNativeHost(hostName){let registryKey=`HKCU\\SOFTWARE\\Google\\Chrome\\NativeMessagingHosts\\${hostName}`;try{execFileSync("reg",["delete",registryKey,"/f"],{stdio:"pipe"})}catch{}}function uninstallNativeHostArtifacts(options={},dependencies={}){let{mode="both",silent=!1}=options;if(mode==="both")return["skills","mcp"].map(integrationMode=>uninstallNativeHostArtifacts({...options,mode:integrationMode},dependencies)).every(Boolean);let writeLine=dependencies.writeLine??(line=>console.error(line)),log3=line=>{silent||writeLine(line)};try{let existsSync11=dependencies.existsSync??fs18.existsSync,platform=dependencies.platform??process.platform,hostDir=dependencies.hostDir??resolveNativeHostDirectory({env:dependencies.env,homedir:dependencies.homedir,platform}),unlinkSync2=dependencies.unlinkSync??fs18.unlinkSync,unregister=dependencies.unregisterWindowsNativeHost??unregisterWindowsNativeHost,hostName=MEARL_NATIVE_HOST_NAMES[mode],launcherExtension=platform==="win32"?"cmd":"sh",artifacts=[path19.join(hostDir,`${hostName}.json`),path19.join(hostDir,`${hostName}-launcher.${launcherExtension}`)];for(let artifact of artifacts)existsSync11(artifact)&&(unlinkSync2(artifact),log3(`â
Removed: ${artifact}`));return platform==="win32"&&unregister(hostName),!0}catch(error48){return log3(`â Uninstall failed: ${error48 instanceof Error?error48.message:String(error48)}`),!1}}var MEARL_NATIVE_HOST_NAMES,init_nativeHost=__esm({"../setup/dist/nativeHost.js"(){"use strict";MEARL_NATIVE_HOST_NAMES={skills:"com.alibaba.mearl.skills",mcp:"com.alibaba.mearl.mcp"}}});var install_exports={};__export(install_exports,{installNativeHost:()=>installNativeHost,parseNativeHostInstallArgs:()=>parseNativeHostInstallArgs,resolveHostDir:()=>resolveHostDir,runCli:()=>runCli,uninstallNativeHost:()=>uninstallNativeHost});import fs19 from"node:fs";import path20 from"node:path";import{execFileSync as execFileSync2}from"node:child_process";import{createRequire as createRequire9}from"node:module";import{fileURLToPath as fileURLToPath4}from"node:url";function resolveHostDir(){return resolveNativeHostDirectory()}function resolveNativeHostPath(){let siblingPath=path20.join(__dirname2,"index.js");if(fs19.existsSync(siblingPath))return siblingPath;try{return createRequire9(import.meta.url).resolve("@mearl/native-host/runtime")}catch{throw new Error("Cannot locate native-host runtime entry point. Ensure @mearl/native-host is installed correctly.")}}function registerWindowsNativeHost(hostName,manifestPath){let regKey=`HKCU\\SOFTWARE\\Google\\Chrome\\NativeMessagingHosts\\${hostName}`;execFileSync2("reg",["add",regKey,"/ve","/t","REG_SZ","/d",manifestPath,"/f"],{stdio:"pipe"})}function createLauncherScript(hostDir,hostPath,hostName){let nodePath=path20.resolve(process.execPath);if(process.platform==="win32"){let launcherPath2=path20.join(hostDir,`${hostName}-launcher.cmd`),content2=`@echo off\r
|
|
428
|
+
`),setTimeout(()=>{reject(new Error(`Tool call timeout: ${toolName}`))},18e4)})}};__name(_LocalMCPClient,"LocalMCPClient");LocalMCPClient=_LocalMCPClient,_RuntimeError=class extends(Error.default||Error){constructor(message){super(message),this.name="RuntimeError"}};__name(_RuntimeError,"RuntimeError");RuntimeError=_RuntimeError,_LocalPageAgent=class extends(BrowserOperator.default||BrowserOperator){constructor(session,browser){super(session,browser),this.mcpClient=null;let mcpScript=process.env.PAGE_TASK_MCP_SERVER_SCRIPT||"";if(mcpScript){let env={...process.env};this.mcpClient=new LocalMCPClient("PageUseAgent","python",[mcpScript],env)}else this.mcpClient=null,logWarn("PAGE_TASK_MCP_SERVER_SCRIPT not set. MCP client will not be initialized.")}async initialize(){this.mcpClient&&await this.mcpClient.connect()}async _callMcpToolAsync(name,args){if(!this.mcpClient)throw new RuntimeError("mcp_client is not set on LocalPageAgent.");return this.mcpClient.connected||await this.mcpClient.connect(),await this.mcpClient.callTool(name,args)}};__name(_LocalPageAgent,"LocalPageAgent");LocalPageAgent=_LocalPageAgent,_LocalBrowser=class _LocalBrowser2 extends(Browser.default||Browser){constructor(session){let tempSession=session||_LocalBrowser2._createMinimalMockSession();super(tempSession),this._cdpPort=9222,this._browser=null,this._workerThread=null,this._playwrightInteractiveLoopAbortSignal=null,this._playwrightInteractiveLoopAbortController=null,this.contexts=[],this.agent=new LocalPageAgent(tempSession,this),this._playwrightInteractiveLoopAbortController=new AbortController,this._playwrightInteractiveLoopAbortSignal=this._playwrightInteractiveLoopAbortController.signal,!session&&tempSession.__isMock&&(tempSession.callMcpTool=async(name,args)=>await this.agent._callMcpToolAsync(name,args))}static _createMinimalMockSession(){return{sessionId:"local_session",__isMock:!0,callMcpTool:__name(async(_name,_args)=>{throw new Error("Mock session not yet initialized - this should not be called")},"callMcpTool")}}async initialize(options){return this._workerThread?!0:new Promise(async resolve22=>{logInfo("[LocalBrowser] Start launching local browser");try{let tmpDir=process.platform==="win32"&&process.env.TEMP||"/tmp",chromeCdpPortsPath=join32(tmpDir,"chrome_cdp_ports.json"),cdpPortsData={chrome:String(this._cdpPort),router:String(this._cdpPort),local:String(this._cdpPort)};await writeFile(chromeCdpPortsPath,JSON.stringify(cdpPortsData,null,2));let cwd=process.cwd(),userDataDir=join32(cwd,"tmp",`browser_user_data_${process.pid}_${randomUUID5()}`),headless=(process.env.HEADLESS||"false").toLowerCase()==="true",browser=await(await Promise.resolve().then(()=>(init_playwright(),playwright_exports))).chromium.launchPersistentContext(userDataDir,{headless,viewport:{width:1280,height:1200},args:[`--remote-debugging-port=${this._cdpPort}`]});this._browser=browser,logInfo("[LocalBrowser] Local browser launched successfully"),this.agent.initialize().catch(err=>{logWarn(`[LocalBrowser] Failed to initialize agent: ${err}`)}),resolve22(!0),await this._playwrightInteractiveLoop(this._playwrightInteractiveLoopAbortSignal??void 0),logInfo("[LocalBrowser] Local browser interactive loop completed")}catch(error48){logError(`[LocalBrowser] Failed to connect to browser: ${error48}`),resolve22(!1)}})}isInitialized(){return this._browser!==null}async getEndpointUrl(){return`http://localhost:${this._cdpPort}`}async _playwrightInteractiveLoop(shutdownSignal){for(;!shutdownSignal?.aborted;)await new Promise(resolve22=>setTimeout(resolve22,3e3))}abortPlaywrightInteractiveLoop(){this._playwrightInteractiveLoopAbortController?.abort()}};__name(_LocalBrowser,"LocalBrowser");LocalBrowser=_LocalBrowser,_LocalSession=class extends(Session.default||Session){constructor(){let mockAgentBay={apiKey:process.env.AGENTBAY_API_KEY||"",apiKeyConfigured:!!process.env.AGENTBAY_API_KEY,client:{apiBaseUrl:"",getSessionStatus:__name(request=>({toMap:__name(()=>({success:!0,data:{status:"running"}}),"toMap")}),"getSessionStatus"),callMcpTool:__name((name,args,kwargs)=>({requestId:"mock_request_id",success:!1,data:null,errorMessage:"Mock mode: Cannot execute tool calls without proper API connection"}),"callMcpTool")}};super(mockAgentBay,"local_session"),this.browser=new LocalBrowser(this)}async callMcpTool(toolName,args,autoGenSession=!1){let result=await this.browser.operator._callMcpToolAsync(toolName,args);return{success:result.success,data:result.data,errorMessage:result.errorMessage||"",requestId:result.requestId}}async delete(syncContext=!1){return this.browser.abortPlaywrightInteractiveLoop(),{success:!0,requestId:`local_delete_${this.sessionId}`,errorMessage:void 0}}};__name(_LocalSession,"LocalSession")}});var agentbay_sdk_exports={};__export(agentbay_sdk_exports,{AgentBay:()=>AgentBay,GetCdpLinkRequest:()=>GetCdpLinkRequest,LifecyclePolicy:()=>LifecyclePolicy});var init_agentbay_sdk=__esm({"src/agentbay-sdk.ts"(){"use strict";init_dist();setupLogger({level:"ERROR",enableConsole:!1})}});var require_wrappy=__commonJS({"../../node_modules/.pnpm/wrappy@1.0.2/node_modules/wrappy/wrappy.js"(exports,module){module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!="function")throw new TypeError("need wrapper function");return Object.keys(fn).forEach(function(k){wrapper[k]=fn[k]}),wrapper;function wrapper(){for(var args=new Array(arguments.length),i=0;i<args.length;i++)args[i]=arguments[i];var ret=fn.apply(this,args),cb2=args[args.length-1];return typeof ret=="function"&&ret!==cb2&&Object.keys(cb2).forEach(function(k){ret[k]=cb2[k]}),ret}}}});var require_once=__commonJS({"../../node_modules/.pnpm/once@1.4.0/node_modules/once/once.js"(exports,module){var wrappy=require_wrappy();module.exports=wrappy(once);module.exports.strict=wrappy(onceStrict);once.proto=once(function(){Object.defineProperty(Function.prototype,"once",{value:function(){return once(this)},configurable:!0}),Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return onceStrict(this)},configurable:!0})});function once(fn){var f=function(){return f.called?f.value:(f.called=!0,f.value=fn.apply(this,arguments))};return f.called=!1,f}function onceStrict(fn){var f=function(){if(f.called)throw new Error(f.onceError);return f.called=!0,f.value=fn.apply(this,arguments)},name=fn.name||"Function wrapped with `once`";return f.onceError=name+" shouldn't be called more than once",f.called=!1,f}}});var require_end_of_stream=__commonJS({"../../node_modules/.pnpm/end-of-stream@1.4.5/node_modules/end-of-stream/index.js"(exports,module){var once=require_once(),noop=function(){},qnt=global.Bare?queueMicrotask:process.nextTick.bind(process),isRequest=function(stream){return stream.setHeader&&typeof stream.abort=="function"},isChildProcess=function(stream){return stream.stdio&&Array.isArray(stream.stdio)&&stream.stdio.length===3},eos=function(stream,opts,callback){if(typeof opts=="function")return eos(stream,null,opts);opts||(opts={}),callback=once(callback||noop);var ws=stream._writableState,rs=stream._readableState,readable=opts.readable||opts.readable!==!1&&stream.readable,writable=opts.writable||opts.writable!==!1&&stream.writable,cancelled=!1,onlegacyfinish=function(){stream.writable||onfinish()},onfinish=function(){writable=!1,readable||callback.call(stream)},onend=function(){readable=!1,writable||callback.call(stream)},onexit=function(exitCode){callback.call(stream,exitCode?new Error("exited with error code: "+exitCode):null)},onerror=function(err){callback.call(stream,err)},onclose=function(){qnt(onclosenexttick)},onclosenexttick=function(){if(!cancelled){if(readable&&!(rs&&rs.ended&&!rs.destroyed))return callback.call(stream,new Error("premature close"));if(writable&&!(ws&&ws.ended&&!ws.destroyed))return callback.call(stream,new Error("premature close"))}},onrequest=function(){stream.req.on("finish",onfinish)};return isRequest(stream)?(stream.on("complete",onfinish),stream.on("abort",onclose),stream.req?onrequest():stream.on("request",onrequest)):writable&&!ws&&(stream.on("end",onlegacyfinish),stream.on("close",onlegacyfinish)),isChildProcess(stream)&&stream.on("exit",onexit),stream.on("end",onend),stream.on("finish",onfinish),opts.error!==!1&&stream.on("error",onerror),stream.on("close",onclose),function(){cancelled=!0,stream.removeListener("complete",onfinish),stream.removeListener("abort",onclose),stream.removeListener("request",onrequest),stream.req&&stream.req.removeListener("finish",onfinish),stream.removeListener("end",onlegacyfinish),stream.removeListener("close",onlegacyfinish),stream.removeListener("finish",onfinish),stream.removeListener("exit",onexit),stream.removeListener("end",onend),stream.removeListener("error",onerror),stream.removeListener("close",onclose)}};module.exports=eos}});var require_pump=__commonJS({"../../node_modules/.pnpm/pump@3.0.4/node_modules/pump/index.js"(exports,module){var once=require_once(),eos=require_end_of_stream(),fs21;try{fs21=__require("fs")}catch{}var noop=function(){},ancient=typeof process>"u"?!1:/^v?\.0/.test(process.version),isFn=function(fn){return typeof fn=="function"},isFS=function(stream){return!ancient||!fs21?!1:(stream instanceof(fs21.ReadStream||noop)||stream instanceof(fs21.WriteStream||noop))&&isFn(stream.close)},isRequest=function(stream){return stream.setHeader&&isFn(stream.abort)},destroyer=function(stream,reading,writing,callback){callback=once(callback);var closed=!1;stream.on("close",function(){closed=!0}),eos(stream,{readable:reading,writable:writing},function(err){if(err)return callback(err);closed=!0,callback()});var destroyed=!1;return function(err){if(!closed&&!destroyed){if(destroyed=!0,isFS(stream))return stream.close(noop);if(isRequest(stream))return stream.abort();if(isFn(stream.destroy))return stream.destroy();callback(err||new Error("stream was destroyed"))}}},call=function(fn){fn()},pipe2=function(from,to){return from.pipe(to)},pump=function(){var streams=Array.prototype.slice.call(arguments),callback=isFn(streams[streams.length-1]||noop)&&streams.pop()||noop;if(Array.isArray(streams[0])&&(streams=streams[0]),streams.length<2)throw new Error("pump requires two streams per minimum");var error48,destroys=streams.map(function(stream,i){var reading=i<streams.length-1,writing=i>0;return destroyer(stream,reading,writing,function(err){error48||(error48=err),err&&destroys.forEach(call),!reading&&(destroys.forEach(call),callback(error48))})});return streams.reduce(pipe2)};module.exports=pump}});var require_buffer_stream=__commonJS({"../../node_modules/.pnpm/get-stream@5.2.0/node_modules/get-stream/buffer-stream.js"(exports,module){"use strict";var{PassThrough:PassThroughStream}=__require("stream");module.exports=options=>{options={...options};let{array:array2}=options,{encoding}=options,isBuffer=encoding==="buffer",objectMode=!1;array2?objectMode=!(encoding||isBuffer):encoding=encoding||"utf8",isBuffer&&(encoding=null);let stream=new PassThroughStream({objectMode});encoding&&stream.setEncoding(encoding);let length=0,chunks=[];return stream.on("data",chunk=>{chunks.push(chunk),objectMode?length=chunks.length:length+=chunk.length}),stream.getBufferedValue=()=>array2?chunks:isBuffer?Buffer.concat(chunks,length):chunks.join(""),stream.getBufferedLength=()=>length,stream}}});var require_get_stream=__commonJS({"../../node_modules/.pnpm/get-stream@5.2.0/node_modules/get-stream/index.js"(exports,module){"use strict";var{constants:BufferConstants}=__require("buffer"),pump=require_pump(),bufferStream=require_buffer_stream(),MaxBufferError=class extends Error{constructor(){super("maxBuffer exceeded"),this.name="MaxBufferError"}};async function getStream(inputStream,options){if(!inputStream)return Promise.reject(new Error("Expected a stream"));options={maxBuffer:1/0,...options};let{maxBuffer}=options,stream;return await new Promise((resolve3,reject)=>{let rejectPromise=error48=>{error48&&stream.getBufferedLength()<=BufferConstants.MAX_LENGTH&&(error48.bufferedData=stream.getBufferedValue()),reject(error48)};stream=pump(inputStream,bufferStream(options),error48=>{if(error48){rejectPromise(error48);return}resolve3()}),stream.on("data",()=>{stream.getBufferedLength()>maxBuffer&&rejectPromise(new MaxBufferError)})}),stream.getBufferedValue()}module.exports=getStream;module.exports.default=getStream;module.exports.buffer=(stream,options)=>getStream(stream,{...options,encoding:"buffer"});module.exports.array=(stream,options)=>getStream(stream,{...options,array:!0});module.exports.MaxBufferError=MaxBufferError}});var require_pend=__commonJS({"../../node_modules/.pnpm/pend@1.2.0/node_modules/pend/index.js"(exports,module){module.exports=Pend;function Pend(){this.pending=0,this.max=1/0,this.listeners=[],this.waiting=[],this.error=null}Pend.prototype.go=function(fn){this.pending<this.max?pendGo(this,fn):this.waiting.push(fn)};Pend.prototype.wait=function(cb){this.pending===0?cb(this.error):this.listeners.push(cb)};Pend.prototype.hold=function(){return pendHold(this)};function pendHold(self2){self2.pending+=1;var called=!1;return onCb;function onCb(err){if(called)throw new Error("callback called twice");if(called=!0,self2.error=self2.error||err,self2.pending-=1,self2.waiting.length>0&&self2.pending<self2.max)pendGo(self2,self2.waiting.shift());else if(self2.pending===0){var listeners=self2.listeners;self2.listeners=[],listeners.forEach(cbListener)}}function cbListener(listener){listener(self2.error)}}function pendGo(self2,fn){fn(pendHold(self2))}}});var require_fd_slicer=__commonJS({"../../node_modules/.pnpm/fd-slicer@1.1.0/node_modules/fd-slicer/index.js"(exports){var fs21=__require("fs"),util2=__require("util"),stream=__require("stream"),Readable2=stream.Readable,Writable2=stream.Writable,PassThrough=stream.PassThrough,Pend=require_pend(),EventEmitter=__require("events").EventEmitter;exports.createFromBuffer=createFromBuffer;exports.createFromFd=createFromFd;exports.BufferSlicer=BufferSlicer;exports.FdSlicer=FdSlicer;util2.inherits(FdSlicer,EventEmitter);function FdSlicer(fd,options){options=options||{},EventEmitter.call(this),this.fd=fd,this.pend=new Pend,this.pend.max=1,this.refCount=0,this.autoClose=!!options.autoClose}FdSlicer.prototype.read=function(buffer,offset,length,position,callback){var self2=this;self2.pend.go(function(cb){fs21.read(self2.fd,buffer,offset,length,position,function(err,bytesRead,buffer2){cb(),callback(err,bytesRead,buffer2)})})};FdSlicer.prototype.write=function(buffer,offset,length,position,callback){var self2=this;self2.pend.go(function(cb){fs21.write(self2.fd,buffer,offset,length,position,function(err,written,buffer2){cb(),callback(err,written,buffer2)})})};FdSlicer.prototype.createReadStream=function(options){return new ReadStream(this,options)};FdSlicer.prototype.createWriteStream=function(options){return new WriteStream(this,options)};FdSlicer.prototype.ref=function(){this.refCount+=1};FdSlicer.prototype.unref=function(){var self2=this;if(self2.refCount-=1,self2.refCount>0)return;if(self2.refCount<0)throw new Error("invalid unref");self2.autoClose&&fs21.close(self2.fd,onCloseDone);function onCloseDone(err){err?self2.emit("error",err):self2.emit("close")}};util2.inherits(ReadStream,Readable2);function ReadStream(context,options){options=options||{},Readable2.call(this,options),this.context=context,this.context.ref(),this.start=options.start||0,this.endOffset=options.end,this.pos=this.start,this.destroyed=!1}ReadStream.prototype._read=function(n){var self2=this;if(!self2.destroyed){var toRead=Math.min(self2._readableState.highWaterMark,n);if(self2.endOffset!=null&&(toRead=Math.min(toRead,self2.endOffset-self2.pos)),toRead<=0){self2.destroyed=!0,self2.push(null),self2.context.unref();return}self2.context.pend.go(function(cb){if(self2.destroyed)return cb();var buffer=new Buffer(toRead);fs21.read(self2.context.fd,buffer,0,toRead,self2.pos,function(err,bytesRead){err?self2.destroy(err):bytesRead===0?(self2.destroyed=!0,self2.push(null),self2.context.unref()):(self2.pos+=bytesRead,self2.push(buffer.slice(0,bytesRead))),cb()})})}};ReadStream.prototype.destroy=function(err){this.destroyed||(err=err||new Error("stream destroyed"),this.destroyed=!0,this.emit("error",err),this.context.unref())};util2.inherits(WriteStream,Writable2);function WriteStream(context,options){options=options||{},Writable2.call(this,options),this.context=context,this.context.ref(),this.start=options.start||0,this.endOffset=options.end==null?1/0:+options.end,this.bytesWritten=0,this.pos=this.start,this.destroyed=!1,this.on("finish",this.destroy.bind(this))}WriteStream.prototype._write=function(buffer,encoding,callback){var self2=this;if(!self2.destroyed){if(self2.pos+buffer.length>self2.endOffset){var err=new Error("maximum file length exceeded");err.code="ETOOBIG",self2.destroy(),callback(err);return}self2.context.pend.go(function(cb){if(self2.destroyed)return cb();fs21.write(self2.context.fd,buffer,0,buffer.length,self2.pos,function(err2,bytes){err2?(self2.destroy(),cb(),callback(err2)):(self2.bytesWritten+=bytes,self2.pos+=bytes,self2.emit("progress"),cb(),callback())})})}};WriteStream.prototype.destroy=function(){this.destroyed||(this.destroyed=!0,this.context.unref())};util2.inherits(BufferSlicer,EventEmitter);function BufferSlicer(buffer,options){EventEmitter.call(this),options=options||{},this.refCount=0,this.buffer=buffer,this.maxChunkSize=options.maxChunkSize||Number.MAX_SAFE_INTEGER}BufferSlicer.prototype.read=function(buffer,offset,length,position,callback){var end=position+length,delta=end-this.buffer.length,written=delta>0?delta:length;this.buffer.copy(buffer,offset,position,end),setImmediate(function(){callback(null,written)})};BufferSlicer.prototype.write=function(buffer,offset,length,position,callback){buffer.copy(this.buffer,position,offset,offset+length),setImmediate(function(){callback(null,length,buffer)})};BufferSlicer.prototype.createReadStream=function(options){options=options||{};var readStream=new PassThrough(options);readStream.destroyed=!1,readStream.start=options.start||0,readStream.endOffset=options.end,readStream.pos=readStream.endOffset||this.buffer.length;for(var entireSlice=this.buffer.slice(readStream.start,readStream.pos),offset=0;;){var nextOffset=offset+this.maxChunkSize;if(nextOffset>=entireSlice.length){offset<entireSlice.length&&readStream.write(entireSlice.slice(offset,entireSlice.length));break}readStream.write(entireSlice.slice(offset,nextOffset)),offset=nextOffset}return readStream.end(),readStream.destroy=function(){readStream.destroyed=!0},readStream};BufferSlicer.prototype.createWriteStream=function(options){var bufferSlicer=this;options=options||{};var writeStream=new Writable2(options);return writeStream.start=options.start||0,writeStream.endOffset=options.end==null?this.buffer.length:+options.end,writeStream.bytesWritten=0,writeStream.pos=writeStream.start,writeStream.destroyed=!1,writeStream._write=function(buffer,encoding,callback){if(!writeStream.destroyed){var end=writeStream.pos+buffer.length;if(end>writeStream.endOffset){var err=new Error("maximum file length exceeded");err.code="ETOOBIG",writeStream.destroyed=!0,callback(err);return}buffer.copy(bufferSlicer.buffer,writeStream.pos,0,buffer.length),writeStream.bytesWritten+=buffer.length,writeStream.pos=end,writeStream.emit("progress"),callback()}},writeStream.destroy=function(){writeStream.destroyed=!0},writeStream};BufferSlicer.prototype.ref=function(){this.refCount+=1};BufferSlicer.prototype.unref=function(){if(this.refCount-=1,this.refCount<0)throw new Error("invalid unref")};function createFromBuffer(buffer,options){return new BufferSlicer(buffer,options)}function createFromFd(fd,options){return new FdSlicer(fd,options)}}});var require_buffer_crc32=__commonJS({"../../node_modules/.pnpm/buffer-crc32@0.2.13/node_modules/buffer-crc32/index.js"(exports,module){var Buffer2=__require("buffer").Buffer,CRC_TABLE=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];typeof Int32Array<"u"&&(CRC_TABLE=new Int32Array(CRC_TABLE));function ensureBuffer(input){if(Buffer2.isBuffer(input))return input;var hasNewBufferAPI=typeof Buffer2.alloc=="function"&&typeof Buffer2.from=="function";if(typeof input=="number")return hasNewBufferAPI?Buffer2.alloc(input):new Buffer2(input);if(typeof input=="string")return hasNewBufferAPI?Buffer2.from(input):new Buffer2(input);throw new Error("input must be buffer, number, or string, received "+typeof input)}function bufferizeInt(num){var tmp=ensureBuffer(4);return tmp.writeInt32BE(num,0),tmp}function _crc32(buf,previous){buf=ensureBuffer(buf),Buffer2.isBuffer(previous)&&(previous=previous.readUInt32BE(0));for(var crc=~~previous^-1,n=0;n<buf.length;n++)crc=CRC_TABLE[(crc^buf[n])&255]^crc>>>8;return crc^-1}function crc32(){return bufferizeInt(_crc32.apply(null,arguments))}crc32.signed=function(){return _crc32.apply(null,arguments)};crc32.unsigned=function(){return _crc32.apply(null,arguments)>>>0};module.exports=crc32}});var require_yauzl=__commonJS({"../../node_modules/.pnpm/yauzl@2.10.0/node_modules/yauzl/index.js"(exports){var fs21=__require("fs"),zlib=__require("zlib"),fd_slicer=require_fd_slicer(),crc32=require_buffer_crc32(),util2=__require("util"),EventEmitter=__require("events").EventEmitter,Transform=__require("stream").Transform,PassThrough=__require("stream").PassThrough,Writable2=__require("stream").Writable;exports.open=open2;exports.fromFd=fromFd;exports.fromBuffer=fromBuffer;exports.fromRandomAccessReader=fromRandomAccessReader;exports.dosDateTimeToDate=dosDateTimeToDate;exports.validateFileName=validateFileName;exports.ZipFile=ZipFile;exports.Entry=Entry;exports.RandomAccessReader=RandomAccessReader;function open2(path23,options,callback){typeof options=="function"&&(callback=options,options=null),options==null&&(options={}),options.autoClose==null&&(options.autoClose=!0),options.lazyEntries==null&&(options.lazyEntries=!1),options.decodeStrings==null&&(options.decodeStrings=!0),options.validateEntrySizes==null&&(options.validateEntrySizes=!0),options.strictFileNames==null&&(options.strictFileNames=!1),callback==null&&(callback=defaultCallback),fs21.open(path23,"r",function(err,fd){if(err)return callback(err);fromFd(fd,options,function(err2,zipfile){err2&&fs21.close(fd,defaultCallback),callback(err2,zipfile)})})}function fromFd(fd,options,callback){typeof options=="function"&&(callback=options,options=null),options==null&&(options={}),options.autoClose==null&&(options.autoClose=!1),options.lazyEntries==null&&(options.lazyEntries=!1),options.decodeStrings==null&&(options.decodeStrings=!0),options.validateEntrySizes==null&&(options.validateEntrySizes=!0),options.strictFileNames==null&&(options.strictFileNames=!1),callback==null&&(callback=defaultCallback),fs21.fstat(fd,function(err,stats){if(err)return callback(err);var reader=fd_slicer.createFromFd(fd,{autoClose:!0});fromRandomAccessReader(reader,stats.size,options,callback)})}function fromBuffer(buffer,options,callback){typeof options=="function"&&(callback=options,options=null),options==null&&(options={}),options.autoClose=!1,options.lazyEntries==null&&(options.lazyEntries=!1),options.decodeStrings==null&&(options.decodeStrings=!0),options.validateEntrySizes==null&&(options.validateEntrySizes=!0),options.strictFileNames==null&&(options.strictFileNames=!1);var reader=fd_slicer.createFromBuffer(buffer,{maxChunkSize:65536});fromRandomAccessReader(reader,buffer.length,options,callback)}function fromRandomAccessReader(reader,totalSize,options,callback){typeof options=="function"&&(callback=options,options=null),options==null&&(options={}),options.autoClose==null&&(options.autoClose=!0),options.lazyEntries==null&&(options.lazyEntries=!1),options.decodeStrings==null&&(options.decodeStrings=!0);var decodeStrings=!!options.decodeStrings;if(options.validateEntrySizes==null&&(options.validateEntrySizes=!0),options.strictFileNames==null&&(options.strictFileNames=!1),callback==null&&(callback=defaultCallback),typeof totalSize!="number")throw new Error("expected totalSize parameter to be a number");if(totalSize>Number.MAX_SAFE_INTEGER)throw new Error("zip file too large. only file sizes up to 2^52 are supported due to JavaScript's Number type being an IEEE 754 double.");reader.ref();var eocdrWithoutCommentSize=22,maxCommentSize=65535,bufferSize=Math.min(eocdrWithoutCommentSize+maxCommentSize,totalSize),buffer=newBuffer(bufferSize),bufferReadStart=totalSize-buffer.length;readAndAssertNoEof(reader,buffer,0,bufferSize,bufferReadStart,function(err){if(err)return callback(err);for(var i=bufferSize-eocdrWithoutCommentSize;i>=0;i-=1)if(buffer.readUInt32LE(i)===101010256){var eocdrBuffer=buffer.slice(i),diskNumber=eocdrBuffer.readUInt16LE(4);if(diskNumber!==0)return callback(new Error("multi-disk zip files are not supported: found disk number: "+diskNumber));var entryCount=eocdrBuffer.readUInt16LE(10),centralDirectoryOffset=eocdrBuffer.readUInt32LE(16),commentLength=eocdrBuffer.readUInt16LE(20),expectedCommentLength=eocdrBuffer.length-eocdrWithoutCommentSize;if(commentLength!==expectedCommentLength)return callback(new Error("invalid comment length. expected: "+expectedCommentLength+". found: "+commentLength));var comment=decodeStrings?decodeBuffer(eocdrBuffer,22,eocdrBuffer.length,!1):eocdrBuffer.slice(22);if(!(entryCount===65535||centralDirectoryOffset===4294967295))return callback(null,new ZipFile(reader,centralDirectoryOffset,totalSize,entryCount,comment,options.autoClose,options.lazyEntries,decodeStrings,options.validateEntrySizes,options.strictFileNames));var zip64EocdlBuffer=newBuffer(20),zip64EocdlOffset=bufferReadStart+i-zip64EocdlBuffer.length;readAndAssertNoEof(reader,zip64EocdlBuffer,0,zip64EocdlBuffer.length,zip64EocdlOffset,function(err2){if(err2)return callback(err2);if(zip64EocdlBuffer.readUInt32LE(0)!==117853008)return callback(new Error("invalid zip64 end of central directory locator signature"));var zip64EocdrOffset=readUInt64LE(zip64EocdlBuffer,8),zip64EocdrBuffer=newBuffer(56);readAndAssertNoEof(reader,zip64EocdrBuffer,0,zip64EocdrBuffer.length,zip64EocdrOffset,function(err3){return err3?callback(err3):zip64EocdrBuffer.readUInt32LE(0)!==101075792?callback(new Error("invalid zip64 end of central directory record signature")):(entryCount=readUInt64LE(zip64EocdrBuffer,32),centralDirectoryOffset=readUInt64LE(zip64EocdrBuffer,48),callback(null,new ZipFile(reader,centralDirectoryOffset,totalSize,entryCount,comment,options.autoClose,options.lazyEntries,decodeStrings,options.validateEntrySizes,options.strictFileNames)))})});return}callback(new Error("end of central directory record signature not found"))})}util2.inherits(ZipFile,EventEmitter);function ZipFile(reader,centralDirectoryOffset,fileSize,entryCount,comment,autoClose,lazyEntries,decodeStrings,validateEntrySizes,strictFileNames){var self2=this;EventEmitter.call(self2),self2.reader=reader,self2.reader.on("error",function(err){emitError(self2,err)}),self2.reader.once("close",function(){self2.emit("close")}),self2.readEntryCursor=centralDirectoryOffset,self2.fileSize=fileSize,self2.entryCount=entryCount,self2.comment=comment,self2.entriesRead=0,self2.autoClose=!!autoClose,self2.lazyEntries=!!lazyEntries,self2.decodeStrings=!!decodeStrings,self2.validateEntrySizes=!!validateEntrySizes,self2.strictFileNames=!!strictFileNames,self2.isOpen=!0,self2.emittedError=!1,self2.lazyEntries||self2._readEntry()}ZipFile.prototype.close=function(){this.isOpen&&(this.isOpen=!1,this.reader.unref())};function emitErrorAndAutoClose(self2,err){self2.autoClose&&self2.close(),emitError(self2,err)}function emitError(self2,err){self2.emittedError||(self2.emittedError=!0,self2.emit("error",err))}ZipFile.prototype.readEntry=function(){if(!this.lazyEntries)throw new Error("readEntry() called without lazyEntries:true");this._readEntry()};ZipFile.prototype._readEntry=function(){var self2=this;if(self2.entryCount===self2.entriesRead){setImmediate(function(){self2.autoClose&&self2.close(),!self2.emittedError&&self2.emit("end")});return}if(!self2.emittedError){var buffer=newBuffer(46);readAndAssertNoEof(self2.reader,buffer,0,buffer.length,self2.readEntryCursor,function(err){if(err)return emitErrorAndAutoClose(self2,err);if(!self2.emittedError){var entry=new Entry,signature=buffer.readUInt32LE(0);if(signature!==33639248)return emitErrorAndAutoClose(self2,new Error("invalid central directory file header signature: 0x"+signature.toString(16)));if(entry.versionMadeBy=buffer.readUInt16LE(4),entry.versionNeededToExtract=buffer.readUInt16LE(6),entry.generalPurposeBitFlag=buffer.readUInt16LE(8),entry.compressionMethod=buffer.readUInt16LE(10),entry.lastModFileTime=buffer.readUInt16LE(12),entry.lastModFileDate=buffer.readUInt16LE(14),entry.crc32=buffer.readUInt32LE(16),entry.compressedSize=buffer.readUInt32LE(20),entry.uncompressedSize=buffer.readUInt32LE(24),entry.fileNameLength=buffer.readUInt16LE(28),entry.extraFieldLength=buffer.readUInt16LE(30),entry.fileCommentLength=buffer.readUInt16LE(32),entry.internalFileAttributes=buffer.readUInt16LE(36),entry.externalFileAttributes=buffer.readUInt32LE(38),entry.relativeOffsetOfLocalHeader=buffer.readUInt32LE(42),entry.generalPurposeBitFlag&64)return emitErrorAndAutoClose(self2,new Error("strong encryption is not supported"));self2.readEntryCursor+=46,buffer=newBuffer(entry.fileNameLength+entry.extraFieldLength+entry.fileCommentLength),readAndAssertNoEof(self2.reader,buffer,0,buffer.length,self2.readEntryCursor,function(err2){if(err2)return emitErrorAndAutoClose(self2,err2);if(!self2.emittedError){var isUtf8=(entry.generalPurposeBitFlag&2048)!==0;entry.fileName=self2.decodeStrings?decodeBuffer(buffer,0,entry.fileNameLength,isUtf8):buffer.slice(0,entry.fileNameLength);var fileCommentStart=entry.fileNameLength+entry.extraFieldLength,extraFieldBuffer=buffer.slice(entry.fileNameLength,fileCommentStart);entry.extraFields=[];for(var i=0;i<extraFieldBuffer.length-3;){var headerId=extraFieldBuffer.readUInt16LE(i+0),dataSize=extraFieldBuffer.readUInt16LE(i+2),dataStart=i+4,dataEnd=dataStart+dataSize;if(dataEnd>extraFieldBuffer.length)return emitErrorAndAutoClose(self2,new Error("extra field length exceeds extra field buffer size"));var dataBuffer=newBuffer(dataSize);extraFieldBuffer.copy(dataBuffer,0,dataStart,dataEnd),entry.extraFields.push({id:headerId,data:dataBuffer}),i=dataEnd}if(entry.fileComment=self2.decodeStrings?decodeBuffer(buffer,fileCommentStart,fileCommentStart+entry.fileCommentLength,isUtf8):buffer.slice(fileCommentStart,fileCommentStart+entry.fileCommentLength),entry.comment=entry.fileComment,self2.readEntryCursor+=buffer.length,self2.entriesRead+=1,entry.uncompressedSize===4294967295||entry.compressedSize===4294967295||entry.relativeOffsetOfLocalHeader===4294967295){for(var zip64EiefBuffer=null,i=0;i<entry.extraFields.length;i++){var extraField=entry.extraFields[i];if(extraField.id===1){zip64EiefBuffer=extraField.data;break}}if(zip64EiefBuffer==null)return emitErrorAndAutoClose(self2,new Error("expected zip64 extended information extra field"));var index=0;if(entry.uncompressedSize===4294967295){if(index+8>zip64EiefBuffer.length)return emitErrorAndAutoClose(self2,new Error("zip64 extended information extra field does not include uncompressed size"));entry.uncompressedSize=readUInt64LE(zip64EiefBuffer,index),index+=8}if(entry.compressedSize===4294967295){if(index+8>zip64EiefBuffer.length)return emitErrorAndAutoClose(self2,new Error("zip64 extended information extra field does not include compressed size"));entry.compressedSize=readUInt64LE(zip64EiefBuffer,index),index+=8}if(entry.relativeOffsetOfLocalHeader===4294967295){if(index+8>zip64EiefBuffer.length)return emitErrorAndAutoClose(self2,new Error("zip64 extended information extra field does not include relative header offset"));entry.relativeOffsetOfLocalHeader=readUInt64LE(zip64EiefBuffer,index),index+=8}}if(self2.decodeStrings)for(var i=0;i<entry.extraFields.length;i++){var extraField=entry.extraFields[i];if(extraField.id===28789){if(extraField.data.length<6||extraField.data.readUInt8(0)!==1)continue;var oldNameCrc32=extraField.data.readUInt32LE(1);if(crc32.unsigned(buffer.slice(0,entry.fileNameLength))!==oldNameCrc32)continue;entry.fileName=decodeBuffer(extraField.data,5,extraField.data.length,!0);break}}if(self2.validateEntrySizes&&entry.compressionMethod===0){var expectedCompressedSize=entry.uncompressedSize;if(entry.isEncrypted()&&(expectedCompressedSize+=12),entry.compressedSize!==expectedCompressedSize){var msg="compressed/uncompressed size mismatch for stored file: "+entry.compressedSize+" != "+entry.uncompressedSize;return emitErrorAndAutoClose(self2,new Error(msg))}}if(self2.decodeStrings){self2.strictFileNames||(entry.fileName=entry.fileName.replace(/\\/g,"/"));var errorMessage2=validateFileName(entry.fileName,self2.validateFileNameOptions);if(errorMessage2!=null)return emitErrorAndAutoClose(self2,new Error(errorMessage2))}self2.emit("entry",entry),self2.lazyEntries||self2._readEntry()}})}})}};ZipFile.prototype.openReadStream=function(entry,options,callback){var self2=this,relativeStart=0,relativeEnd=entry.compressedSize;if(callback==null)callback=options,options={};else{if(options.decrypt!=null){if(!entry.isEncrypted())throw new Error("options.decrypt can only be specified for encrypted entries");if(options.decrypt!==!1)throw new Error("invalid options.decrypt value: "+options.decrypt);if(entry.isCompressed()&&options.decompress!==!1)throw new Error("entry is encrypted and compressed, and options.decompress !== false")}if(options.decompress!=null){if(!entry.isCompressed())throw new Error("options.decompress can only be specified for compressed entries");if(!(options.decompress===!1||options.decompress===!0))throw new Error("invalid options.decompress value: "+options.decompress)}if(options.start!=null||options.end!=null){if(entry.isCompressed()&&options.decompress!==!1)throw new Error("start/end range not allowed for compressed entry without options.decompress === false");if(entry.isEncrypted()&&options.decrypt!==!1)throw new Error("start/end range not allowed for encrypted entry without options.decrypt === false")}if(options.start!=null){if(relativeStart=options.start,relativeStart<0)throw new Error("options.start < 0");if(relativeStart>entry.compressedSize)throw new Error("options.start > entry.compressedSize")}if(options.end!=null){if(relativeEnd=options.end,relativeEnd<0)throw new Error("options.end < 0");if(relativeEnd>entry.compressedSize)throw new Error("options.end > entry.compressedSize");if(relativeEnd<relativeStart)throw new Error("options.end < options.start")}}if(!self2.isOpen)return callback(new Error("closed"));if(entry.isEncrypted()&&options.decrypt!==!1)return callback(new Error("entry is encrypted, and options.decrypt !== false"));self2.reader.ref();var buffer=newBuffer(30);readAndAssertNoEof(self2.reader,buffer,0,buffer.length,entry.relativeOffsetOfLocalHeader,function(err){try{if(err)return callback(err);var signature=buffer.readUInt32LE(0);if(signature!==67324752)return callback(new Error("invalid local file header signature: 0x"+signature.toString(16)));var fileNameLength=buffer.readUInt16LE(26),extraFieldLength=buffer.readUInt16LE(28),localFileHeaderEnd=entry.relativeOffsetOfLocalHeader+buffer.length+fileNameLength+extraFieldLength,decompress;if(entry.compressionMethod===0)decompress=!1;else if(entry.compressionMethod===8)decompress=options.decompress!=null?options.decompress:!0;else return callback(new Error("unsupported compression method: "+entry.compressionMethod));var fileDataStart=localFileHeaderEnd,fileDataEnd=fileDataStart+entry.compressedSize;if(entry.compressedSize!==0&&fileDataEnd>self2.fileSize)return callback(new Error("file data overflows file bounds: "+fileDataStart+" + "+entry.compressedSize+" > "+self2.fileSize));var readStream=self2.reader.createReadStream({start:fileDataStart+relativeStart,end:fileDataStart+relativeEnd}),endpointStream=readStream;if(decompress){var destroyed=!1,inflateFilter=zlib.createInflateRaw();readStream.on("error",function(err2){setImmediate(function(){destroyed||inflateFilter.emit("error",err2)})}),readStream.pipe(inflateFilter),self2.validateEntrySizes?(endpointStream=new AssertByteCountStream(entry.uncompressedSize),inflateFilter.on("error",function(err2){setImmediate(function(){destroyed||endpointStream.emit("error",err2)})}),inflateFilter.pipe(endpointStream)):endpointStream=inflateFilter,endpointStream.destroy=function(){destroyed=!0,inflateFilter!==endpointStream&&inflateFilter.unpipe(endpointStream),readStream.unpipe(inflateFilter),readStream.destroy()}}callback(null,endpointStream)}finally{self2.reader.unref()}})};function Entry(){}Entry.prototype.getLastModDate=function(){return dosDateTimeToDate(this.lastModFileDate,this.lastModFileTime)};Entry.prototype.isEncrypted=function(){return(this.generalPurposeBitFlag&1)!==0};Entry.prototype.isCompressed=function(){return this.compressionMethod===8};function dosDateTimeToDate(date5,time3){var day=date5&31,month=(date5>>5&15)-1,year=(date5>>9&127)+1980,millisecond=0,second=(time3&31)*2,minute=time3>>5&63,hour=time3>>11&31;return new Date(year,month,day,hour,minute,second,millisecond)}function validateFileName(fileName){return fileName.indexOf("\\")!==-1?"invalid characters in fileName: "+fileName:/^[a-zA-Z]:/.test(fileName)||/^\//.test(fileName)?"absolute path: "+fileName:fileName.split("/").indexOf("..")!==-1?"invalid relative path: "+fileName:null}function readAndAssertNoEof(reader,buffer,offset,length,position,callback){if(length===0)return setImmediate(function(){callback(null,newBuffer(0))});reader.read(buffer,offset,length,position,function(err,bytesRead){if(err)return callback(err);if(bytesRead<length)return callback(new Error("unexpected EOF"));callback()})}util2.inherits(AssertByteCountStream,Transform);function AssertByteCountStream(byteCount){Transform.call(this),this.actualByteCount=0,this.expectedByteCount=byteCount}AssertByteCountStream.prototype._transform=function(chunk,encoding,cb){if(this.actualByteCount+=chunk.length,this.actualByteCount>this.expectedByteCount){var msg="too many bytes in the stream. expected "+this.expectedByteCount+". got at least "+this.actualByteCount;return cb(new Error(msg))}cb(null,chunk)};AssertByteCountStream.prototype._flush=function(cb){if(this.actualByteCount<this.expectedByteCount){var msg="not enough bytes in the stream. expected "+this.expectedByteCount+". got only "+this.actualByteCount;return cb(new Error(msg))}cb()};util2.inherits(RandomAccessReader,EventEmitter);function RandomAccessReader(){EventEmitter.call(this),this.refCount=0}RandomAccessReader.prototype.ref=function(){this.refCount+=1};RandomAccessReader.prototype.unref=function(){var self2=this;if(self2.refCount-=1,self2.refCount>0)return;if(self2.refCount<0)throw new Error("invalid unref");self2.close(onCloseDone);function onCloseDone(err){if(err)return self2.emit("error",err);self2.emit("close")}};RandomAccessReader.prototype.createReadStream=function(options){var start=options.start,end=options.end;if(start===end){var emptyStream=new PassThrough;return setImmediate(function(){emptyStream.end()}),emptyStream}var stream=this._readStreamForRange(start,end),destroyed=!1,refUnrefFilter=new RefUnrefFilter(this);stream.on("error",function(err){setImmediate(function(){destroyed||refUnrefFilter.emit("error",err)})}),refUnrefFilter.destroy=function(){stream.unpipe(refUnrefFilter),refUnrefFilter.unref(),stream.destroy()};var byteCounter=new AssertByteCountStream(end-start);return refUnrefFilter.on("error",function(err){setImmediate(function(){destroyed||byteCounter.emit("error",err)})}),byteCounter.destroy=function(){destroyed=!0,refUnrefFilter.unpipe(byteCounter),refUnrefFilter.destroy()},stream.pipe(refUnrefFilter).pipe(byteCounter)};RandomAccessReader.prototype._readStreamForRange=function(start,end){throw new Error("not implemented")};RandomAccessReader.prototype.read=function(buffer,offset,length,position,callback){var readStream=this.createReadStream({start:position,end:position+length}),writeStream=new Writable2,written=0;writeStream._write=function(chunk,encoding,cb){chunk.copy(buffer,offset+written,0,chunk.length),written+=chunk.length,cb()},writeStream.on("finish",callback),readStream.on("error",function(error48){callback(error48)}),readStream.pipe(writeStream)};RandomAccessReader.prototype.close=function(callback){setImmediate(callback)};util2.inherits(RefUnrefFilter,PassThrough);function RefUnrefFilter(context){PassThrough.call(this),this.context=context,this.context.ref(),this.unreffedYet=!1}RefUnrefFilter.prototype._flush=function(cb){this.unref(),cb()};RefUnrefFilter.prototype.unref=function(cb){this.unreffedYet||(this.unreffedYet=!0,this.context.unref())};var cp437="\0âēâģâĨâĻâŖâ âĸââââââĒâĢâŧâēâââŧÂļ§âŦâ¨âââââââ˛âŧ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~âÃÃŧÊÃĸäà ÃĨçÃĒÃĢèïÎÃŦÃÃ
ÃÃĻÃôÃļÃ˛ÃģÚÃŋÃÃÂĸÂŖÂĨâ§ÆÃĄÃÃŗÃēÃąÃÂĒÂēÂŋâÂŦÂŊÂŧÂĄÂĢÂģâââââ¤âĄâĸâââŖââââââââ´âŦâââŧâââââŠâĻâ ââŦâ§â¨â¤âĨâââââĢâĒâââââââÎąÃÎĪÎŖĪÂĩĪÎĻÎΊδâĪÎĩâŠâĄÂąâĨâ¤â âĄÃˇâ°â¡ââŋ²â  ";function decodeBuffer(buffer,start,end,isUtf8){if(isUtf8)return buffer.toString("utf8",start,end);for(var result="",i=start;i<end;i++)result+=cp437[buffer[i]];return result}function readUInt64LE(buffer,offset){var lower32=buffer.readUInt32LE(offset),upper32=buffer.readUInt32LE(offset+4);return upper32*4294967296+lower32}var newBuffer;typeof Buffer.allocUnsafe=="function"?newBuffer=function(len){return Buffer.allocUnsafe(len)}:newBuffer=function(len){return new Buffer(len)};function defaultCallback(err){if(err)throw err}}});var require_extract_zip=__commonJS({"../../node_modules/.pnpm/extract-zip@2.0.1/node_modules/extract-zip/index.js"(exports,module){var debug=require_src()("extract-zip"),{createWriteStream,promises:fs21}=__require("fs"),getStream=require_get_stream(),path23=__require("path"),{promisify}=__require("util"),stream=__require("stream"),yauzl=require_yauzl(),openZip=promisify(yauzl.open),pipeline=promisify(stream.pipeline),Extractor=class{constructor(zipPath,opts){this.zipPath=zipPath,this.opts=opts}async extract(){return debug("opening",this.zipPath,"with opts",this.opts),this.zipfile=await openZip(this.zipPath,{lazyEntries:!0}),this.canceled=!1,new Promise((resolve3,reject)=>{this.zipfile.on("error",err=>{this.canceled=!0,reject(err)}),this.zipfile.readEntry(),this.zipfile.on("close",()=>{this.canceled||(debug("zip extraction complete"),resolve3())}),this.zipfile.on("entry",async entry=>{if(this.canceled){debug("skipping entry",entry.fileName,{cancelled:this.canceled});return}if(debug("zipfile entry",entry.fileName),entry.fileName.startsWith("__MACOSX/")){this.zipfile.readEntry();return}let destDir=path23.dirname(path23.join(this.opts.dir,entry.fileName));try{await fs21.mkdir(destDir,{recursive:!0});let canonicalDestDir=await fs21.realpath(destDir);if(path23.relative(this.opts.dir,canonicalDestDir).split(path23.sep).includes(".."))throw new Error(`Out of bound path "${canonicalDestDir}" found while processing file ${entry.fileName}`);await this.extractEntry(entry),debug("finished processing",entry.fileName),this.zipfile.readEntry()}catch(err){this.canceled=!0,this.zipfile.close(),reject(err)}})})}async extractEntry(entry){if(this.canceled){debug("skipping entry extraction",entry.fileName,{cancelled:this.canceled});return}this.opts.onEntry&&this.opts.onEntry(entry,this.zipfile);let dest=path23.join(this.opts.dir,entry.fileName),mode=entry.externalFileAttributes>>16&65535,IFMT=61440,IFDIR=16384,symlink=(mode&IFMT)===40960,isDir=(mode&IFMT)===IFDIR;!isDir&&entry.fileName.endsWith("/")&&(isDir=!0);let madeBy=entry.versionMadeBy>>8;isDir||(isDir=madeBy===0&&entry.externalFileAttributes===16),debug("extracting entry",{filename:entry.fileName,isDir,isSymlink:symlink});let procMode=this.getExtractedMode(mode,isDir)&511,destDir=isDir?dest:path23.dirname(dest),mkdirOptions={recursive:!0};if(isDir&&(mkdirOptions.mode=procMode),debug("mkdir",{dir:destDir,...mkdirOptions}),await fs21.mkdir(destDir,mkdirOptions),isDir)return;debug("opening read stream",dest);let readStream=await promisify(this.zipfile.openReadStream.bind(this.zipfile))(entry);if(symlink){let link=await getStream(readStream);debug("creating symlink",link,dest),await fs21.symlink(link,dest)}else await pipeline(readStream,createWriteStream(dest,{mode:procMode}))}getExtractedMode(entryMode,isDir){let mode=entryMode;return mode===0&&(isDir?(this.opts.defaultDirMode&&(mode=parseInt(this.opts.defaultDirMode,10)),mode||(mode=493)):(this.opts.defaultFileMode&&(mode=parseInt(this.opts.defaultFileMode,10)),mode||(mode=420))),mode}};module.exports=async function(zipPath,opts){if(debug("creating target directory",opts.dir),!path23.isAbsolute(opts.dir))throw new Error("Target directory is expected to be absolute");return await fs21.mkdir(opts.dir,{recursive:!0}),opts.dir=await fs21.realpath(opts.dir),new Extractor(zipPath,opts).extract()}}});var runtimeArgs_exports={};__export(runtimeArgs_exports,{parseNativeHostRuntimeArgs:()=>parseNativeHostRuntimeArgs,shouldExitWithoutLegacySocket:()=>shouldExitWithoutLegacySocket});function shouldExitWithoutLegacySocket(options,hasLegacySocket){return!hasLegacySocket&&(options.discoverCdp||options.skipBrowserRegistration)}function stripNativeMessagingLaunchArgs(argv){let[origin,parentWindow,...rest]=argv;return/^chrome-extension:\/\/[a-z]{32}\/$/.test(origin??"")?/^--parent-window=\d+$/.test(parentWindow??"")?rest:argv.slice(1):argv}async function parseNativeHostRuntimeArgs(argv,minimumIdleReleaseMinutes){let args=stripNativeMessagingLaunchArgs(argv),options={},readValue=(index,name)=>{let argument=args[index];if(argument===name){let value=args[index+1];if(value===void 0||value.startsWith("-"))throw new Error(`argument missing for option '${name}'`);return{nextIndex:index+1,value}}return argument?.startsWith(`${name}=`)?{nextIndex:index,value:argument.slice(name.length+1)}:null},parseInteger=(value,label,minimum,maximum)=>{let parsed=Number(value);if(!Number.isInteger(parsed)||parsed<minimum||parsed>maximum)throw new Error(`${label} must be an integer from ${minimum} to ${maximum}`);return parsed};for(let index=0;index<args.length;index+=1){let argument=args[index];if(argument==="--daemon"){options.daemon=!0;continue}if(argument==="--discover-cdp"){options.discoverCdp=!0;continue}if(argument==="--skip-browser-registration"){options.skipBrowserRegistration=!0;continue}if(argument==="--browser-headless"){options.browserHeadless=!0;continue}if(argument==="--version"||argument==="-v"){options.version=!0;continue}if(argument==="--help"||argument==="-h"){options.help=!0;continue}let cdpPort=readValue(index,"--cdp-port");if(cdpPort){options.cdpPort=parseInteger(cdpPort.value,"cdp-port",1,65535),index=cdpPort.nextIndex;continue}let idleRelease=readValue(index,"--agentbay-idle-release-minutes");if(idleRelease){options.agentBayIdleReleaseMinutes=parseInteger(idleRelease.value,"agentbay-idle-release-minutes",minimumIdleReleaseMinutes,Number.MAX_SAFE_INTEGER),index=idleRelease.nextIndex;continue}let stringOptions=[["--cdp-user-data-dir","cdpUserDataDir"],["--agentbay-session-id","agentBaySessionId"],["--browser-id","browserId"],["--browser-name","browserName"]],matchedStringOption=!1;for(let[name,property]of stringOptions){let parsed=readValue(index,name);if(parsed){options[property]=parsed.value,index=parsed.nextIndex,matchedStringOption=!0;break}}if(!matchedStringOption)throw new Error(argument?.startsWith("-")?`unknown option '${argument}'`:`unexpected argument '${argument}'`)}return{...options.agentBayIdleReleaseMinutes!==void 0?{agentBayIdleReleaseMinutes:options.agentBayIdleReleaseMinutes}:{},...options.agentBaySessionId?{agentBaySessionId:options.agentBaySessionId}:{},browserHeadless:options.browserHeadless===!0,browserId:options.browserId??"cdp",browserName:options.browserName??"CDP",cdpPort:options.cdpPort??9222,...options.cdpUserDataDir?{cdpUserDataDir:options.cdpUserDataDir}:{},daemon:options.daemon===!0,discoverCdp:options.discoverCdp===!0,help:options.help===!0,skipBrowserRegistration:options.skipBrowserRegistration===!0,version:options.version===!0}}var init_runtimeArgs=__esm({"src/runtimeArgs.ts"(){"use strict"}});import fs18 from"node:fs";import os9 from"node:os";import path19 from"node:path";import{execFileSync}from"node:child_process";function resolveNativeHostDirectory(options={}){let env=options.env??process.env,home=(options.homedir??os9.homedir)();switch(options.platform??process.platform){case"darwin":return path19.join(home,"Library/Application Support/Google/Chrome/NativeMessagingHosts");case"linux":return path19.join(home,".config/google-chrome/NativeMessagingHosts");case"win32":return path19.join(env.PROGRAMDATA||"C:\\ProgramData","Google\\Chrome\\NativeMessagingHosts");default:throw new Error(`Unsupported platform: ${String(options.platform??process.platform)}`)}}function unregisterWindowsNativeHost(hostName){let registryKey=`HKCU\\SOFTWARE\\Google\\Chrome\\NativeMessagingHosts\\${hostName}`;try{execFileSync("reg",["delete",registryKey,"/f"],{stdio:"pipe"})}catch{}}function uninstallNativeHostArtifacts(options={},dependencies={}){let{mode="both",silent=!1}=options;if(mode==="both")return["skills","mcp"].map(integrationMode=>uninstallNativeHostArtifacts({...options,mode:integrationMode},dependencies)).every(Boolean);let writeLine=dependencies.writeLine??(line=>console.error(line)),log3=line=>{silent||writeLine(line)};try{let existsSync11=dependencies.existsSync??fs18.existsSync,platform=dependencies.platform??process.platform,hostDir=dependencies.hostDir??resolveNativeHostDirectory({env:dependencies.env,homedir:dependencies.homedir,platform}),unlinkSync2=dependencies.unlinkSync??fs18.unlinkSync,unregister=dependencies.unregisterWindowsNativeHost??unregisterWindowsNativeHost,hostName=MEARL_NATIVE_HOST_NAMES[mode],launcherExtension=platform==="win32"?"cmd":"sh",artifacts=[path19.join(hostDir,`${hostName}.json`),path19.join(hostDir,`${hostName}-launcher.${launcherExtension}`)];for(let artifact of artifacts)existsSync11(artifact)&&(unlinkSync2(artifact),log3(`â
Removed: ${artifact}`));return platform==="win32"&&unregister(hostName),!0}catch(error48){return log3(`â Uninstall failed: ${error48 instanceof Error?error48.message:String(error48)}`),!1}}var MEARL_NATIVE_HOST_NAMES,init_nativeHost=__esm({"../setup/dist/nativeHost.js"(){"use strict";MEARL_NATIVE_HOST_NAMES={skills:"com.alibaba.mearl.skills",mcp:"com.alibaba.mearl.mcp"}}});var install_exports={};__export(install_exports,{installNativeHost:()=>installNativeHost,parseNativeHostInstallArgs:()=>parseNativeHostInstallArgs,resolveHostDir:()=>resolveHostDir,runCli:()=>runCli,uninstallNativeHost:()=>uninstallNativeHost});import fs19 from"node:fs";import path20 from"node:path";import{execFileSync as execFileSync2}from"node:child_process";import{createRequire as createRequire9}from"node:module";import{fileURLToPath as fileURLToPath4}from"node:url";function resolveHostDir(){return resolveNativeHostDirectory()}function resolveNativeHostPath(){let siblingPath=path20.join(__dirname2,"index.js");if(fs19.existsSync(siblingPath))return siblingPath;try{return createRequire9(import.meta.url).resolve("@mearl/native-host/runtime")}catch{throw new Error("Cannot locate native-host runtime entry point. Ensure @mearl/native-host is installed correctly.")}}function registerWindowsNativeHost(hostName,manifestPath){let regKey=`HKCU\\SOFTWARE\\Google\\Chrome\\NativeMessagingHosts\\${hostName}`;execFileSync2("reg",["add",regKey,"/ve","/t","REG_SZ","/d",manifestPath,"/f"],{stdio:"pipe"})}function createLauncherScript(hostDir,hostPath,hostName){let nodePath=path20.resolve(process.execPath);if(process.platform==="win32"){let launcherPath2=path20.join(hostDir,`${hostName}-launcher.cmd`),content2=`@echo off\r
|
|
429
429
|
"${nodePath}" "${hostPath}" %*\r
|
|
430
430
|
`;return fs19.writeFileSync(launcherPath2,content2,"utf-8"),launcherPath2}let launcherPath=path20.join(hostDir,`${hostName}-launcher.sh`),content=["#!/bin/sh",`NODE_BIN=${JSON.stringify(nodePath)}`,`HOST_SCRIPT=${JSON.stringify(hostPath)}`,'exec "$NODE_BIN" "$HOST_SCRIPT" "$@"',""].join(`
|
|
431
431
|
`);return fs19.writeFileSync(launcherPath,content,"utf-8"),fs19.chmodSync(launcherPath,493),launcherPath}async function installNativeHost(options={}){let{mode="both",extensionId=DEFAULT_EXTENSION_ID,silent=!1,skipIfExists=!1}=options;if(mode==="both")return(await Promise.all(ALL_MODES.map(m=>installNativeHost({...options,mode:m})))).every(Boolean);let hostName=MEARL_NATIVE_HOST_NAMES[mode];if(!hostName)throw new Error(`Unknown mode: ${mode}. Expected 'skills' or 'mcp'.`);let log3=(...args)=>{silent||console.error(...args)};try{let hostDir=resolveHostDir();if(skipIfExists){let manifestPath2=path20.join(hostDir,`${hostName}.json`);if(fs19.existsSync(manifestPath2))return log3(`â
Already installed: ${manifestPath2}`),!0}fs19.existsSync(hostDir)||(fs19.mkdirSync(hostDir,{recursive:!0}),log3(`â
Created directory: ${hostDir}`));let resolvedHostPath=resolveNativeHostPath();log3(`â
Native host path: ${resolvedHostPath}`);let launcherPath=createLauncherScript(hostDir,resolvedHostPath,hostName);log3(`â
Launcher script: ${launcherPath}`);let manifest={name:hostName,description:"Mearl Native Messaging Bridge",path:launcherPath,type:"stdio",allowed_origins:[`chrome-extension://${extensionId}/`]},manifestPath=path20.join(hostDir,`${hostName}.json`);return fs19.writeFileSync(manifestPath,JSON.stringify(manifest,null,2)),process.platform==="win32"?(registerWindowsNativeHost(hostName,manifestPath),log3(`â
Windows registry key created for: ${hostName}`)):fs19.chmodSync(manifestPath,420),log3(`â
Manifest installed: ${manifestPath}`),log3(`â
Extension ID: ${extensionId}`),log3(`â
Host name: ${hostName}`),!0}catch(error48){return log3(`â Installation failed: ${error48 instanceof Error?error48.message:String(error48)}`),error48 instanceof Error&&"code"in error48&&error48.code==="EACCES"&&log3(`
|
|
@@ -475,7 +475,7 @@ ${truncated}...`}function extractFields(data,fields){if(fields.length>100)throw
|
|
|
475
475
|
catch (e) { return { error: 'Invalid CSS selector "' + sel + '": ' + e.message + '. ' + ${JSON.stringify(INVALID_NATIVE_SELECTOR_HINT)} }; }
|
|
476
476
|
if (!el) return { error: 'Element not found: ' + sel };
|
|
477
477
|
return scroll.call(el, dir, dist, sel, policy);
|
|
478
|
-
})()`}function unwrapPageScrollResult(result,missingResultMessage){if(!result)throw new Error(missingResultMessage);if("error"in result)throw new Error(result.error);return result}var DEVICE_PRESETS={"iphone-15-pro":{width:393,height:852,deviceScaleFactor:3,mobile:!0,userAgent:"Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",platform:"iPhone",platformVersion:"17.0",architecture:"",model:"iPhone",safeAreaInsets:{top:59,right:0,bottom:34,left:0},landscapeSafeAreaInsets:{top:0,right:59,bottom:21,left:59}},"iphone-se":{width:375,height:667,deviceScaleFactor:2,mobile:!0,userAgent:"Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1",platform:"iPhone",platformVersion:"16.0",architecture:"",model:"iPhone",safeAreaInsets:{top:20,right:0,bottom:0,left:0},landscapeSafeAreaInsets:{top:0,right:0,bottom:0,left:0}},"pixel-8":{width:412,height:915,deviceScaleFactor:2.625,mobile:!0,userAgent:"Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36",platform:"Android",platformVersion:"14",architecture:"",model:"Pixel 8",safeAreaInsets:{top:30,right:0,bottom:24,left:0},landscapeSafeAreaInsets:{top:0,right:24,bottom:0,left:24}},"ipad-mini":{width:768,height:1024,deviceScaleFactor:2,mobile:!1,userAgent:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15",platform:"macOS",platformVersion:"10.15.7",architecture:"x86",model:"",safeAreaInsets:{top:24,right:0,bottom:20,left:0},landscapeSafeAreaInsets:{top:0,right:24,bottom:20,left:24}},"galaxy-s23":{width:360,height:780,deviceScaleFactor:3,mobile:!0,userAgent:"Mozilla/5.0 (Linux; Android 14; SM-S911B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36",platform:"Android",platformVersion:"14",architecture:"",model:"SM-S911B",safeAreaInsets:{top:30,right:0,bottom:24,left:0},landscapeSafeAreaInsets:{top:0,right:24,bottom:0,left:24}}};function resolveEmulationConfig(input){if(input.preset&&!(input.preset in DEVICE_PRESETS))throw new Error(`set_device_emulation: unknown preset "${input.preset}". Available: ${Object.keys(DEVICE_PRESETS).join(", ")}`);let preset=input.preset?DEVICE_PRESETS[input.preset]:void 0,width=input.width??preset?.width,height=input.height??preset?.height;if(!width||!height)throw new Error('set_device_emulation: must provide either "preset" or both "width" and "height"');let mobile=input.mobile??preset?.mobile??!0,orientation=input.orientation??"portrait",[finalWidth,finalHeight]=orientation==="landscape"?[height,width]:[width,height],userAgent=input.userAgent??preset?.userAgent??"";if(!userAgent)throw new Error('set_device_emulation: "userAgent" is required when no preset is used (preset supplies a default)');let safeAreaInsets=orientation==="landscape"?preset?.landscapeSafeAreaInsets??{top:preset?.safeAreaInsets.left??0,right:preset?.safeAreaInsets.top??0,bottom:preset?.safeAreaInsets.right??0,left:preset?.safeAreaInsets.bottom??0}:preset?.safeAreaInsets??{top:0,right:0,bottom:0,left:0};return{width:finalWidth,height:finalHeight,deviceScaleFactor:input.deviceScaleFactor??preset?.deviceScaleFactor??(mobile?2:1),mobile,userAgent,platform:preset?.platform??(mobile?"iPhone":"macOS"),platformVersion:preset?.platformVersion??"",architecture:preset?.architecture??"",model:preset?.model??"",touch:input.touch??mobile,orientation,safeAreaInsets,presetName:input.preset}}function buildEnableEmulationCommands(config2){let safeAreaInsets=config2.safeAreaInsets??{top:0,right:0,bottom:0,left:0};return[{method:"Emulation.setDeviceMetricsOverride",params:{width:config2.width,height:config2.height,screenWidth:config2.width,screenHeight:config2.height,deviceScaleFactor:config2.deviceScaleFactor,mobile:config2.mobile,screenOrientation:{type:config2.orientation==="landscape"?"landscapePrimary":"portraitPrimary",angle:config2.orientation==="landscape"?90:0}}},{method:"Emulation.setUserAgentOverride",params:{userAgent:config2.userAgent,platform:config2.platform,userAgentMetadata:{mobile:config2.mobile,platform:config2.platform,platformVersion:config2.platformVersion,architecture:config2.architecture,model:config2.model}}},{method:"Emulation.setTouchEmulationEnabled",params:config2.touch?{enabled:!0,maxTouchPoints:5}:{enabled:!1}},{method:"Emulation.setEmitTouchEventsForMouse",params:{enabled:config2.touch,configuration:"mobile"}},{method:"Emulation.setSafeAreaInsetsOverride",params:{insets:{top:safeAreaInsets.top,topMax:safeAreaInsets.top,right:safeAreaInsets.right,rightMax:safeAreaInsets.right,bottom:safeAreaInsets.bottom,bottomMax:safeAreaInsets.bottom,left:safeAreaInsets.left,leftMax:safeAreaInsets.left}},optional:!0}]}function buildDisableEmulationCommands(){return[{method:"Emulation.clearDeviceMetricsOverride",params:{}},{method:"Emulation.setUserAgentOverride",params:{userAgent:""}},{method:"Emulation.setTouchEmulationEnabled",params:{enabled:!1}},{method:"Emulation.setEmitTouchEventsForMouse",params:{enabled:!1}},{method:"Emulation.setSafeAreaInsetsOverride",params:{insets:{}},optional:!0}]}function matchAXNodesByText(nodes,options){let{text,role,exact=!0}=options;if(typeof text!="string"||text.length===0)return{hits:[]};let hits=[];for(let node of nodes){if(node.ignored||node.backendDOMNodeId===void 0)continue;let name=node.name?.value;if(typeof name!="string"||name.length===0||!(exact?name===text:name.includes(text)))continue;let nodeRole=node.role?.value??"";role&&nodeRole!==role||hits.push({backendNodeId:node.backendDOMNodeId,role:nodeRole,name})}return{hits}}function formatAXTextMatchCandidates(hits,limit=5){return hits.slice(0,limit).map((hit,idx)=>{let name=hit.name.length>60?`${hit.name.slice(0,60)}âĻ`:hit.name,role=hit.role||"(no-role)";return` ${idx+1}. ${role} "${name}"`}).join(`
|
|
478
|
+
})()`}function unwrapPageScrollResult(result,missingResultMessage){if(!result)throw new Error(missingResultMessage);if("error"in result)throw new Error(result.error);return result}var IPHONE_SAFARI_26_USER_AGENT="Mozilla/5.0 (iPhone; CPU iPhone OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Mobile/15E148 Safari/604.1",ANDROID_CHROME_152_USER_AGENT="Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Mobile Safari/537.36",DEVICE_PRESETS={"iphone-17-pro":{width:402,height:874,deviceScaleFactor:3,mobile:!0,userAgent:IPHONE_SAFARI_26_USER_AGENT,platform:"iPhone",platformVersion:"26.0",architecture:"",model:"iPhone",safeAreaInsets:{top:62,right:0,bottom:34,left:0},landscapeSafeAreaInsets:{top:0,right:62,bottom:21,left:62},appProfileModel:"iPhone 17 Pro",appProfileOs:"ios",appearance:{cutout:"dynamic-island"}},"iphone-17e":{width:390,height:844,deviceScaleFactor:3,mobile:!0,userAgent:IPHONE_SAFARI_26_USER_AGENT,platform:"iPhone",platformVersion:"26.0",architecture:"",model:"iPhone",safeAreaInsets:{top:47,right:0,bottom:34,left:0},landscapeSafeAreaInsets:{top:0,right:47,bottom:21,left:47},appProfileModel:"iPhone 17e",appProfileOs:"ios",appearance:{cutout:"notch"}},"pixel-11":{width:412,height:923,deviceScaleFactor:2.625,mobile:!0,userAgent:ANDROID_CHROME_152_USER_AGENT,platform:"Android",platformVersion:"17",architecture:"arm",model:"Pixel 11",safeAreaInsets:{top:30,right:0,bottom:24,left:0},landscapeSafeAreaInsets:{top:0,right:24,bottom:0,left:24},appProfileModel:"Pixel 11",appProfileOs:"android",appearance:{cutout:"none"}},"ipad-mini-a17-pro":{width:744,height:1133,deviceScaleFactor:2,mobile:!1,touch:!0,userAgent:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Safari/605.1.15",platform:"macOS",platformVersion:"10.15.7",architecture:"x86",model:"",safeAreaInsets:{top:24,right:0,bottom:20,left:0},landscapeSafeAreaInsets:{top:0,right:24,bottom:20,left:24},appProfileModel:"iPad mini (A17 Pro)",appProfileOs:"ios",appearance:{cutout:"none"}},"galaxy-s26":{width:360,height:780,deviceScaleFactor:3,mobile:!0,userAgent:ANDROID_CHROME_152_USER_AGENT,platform:"Android",platformVersion:"16",architecture:"arm",model:"SM-S942B",safeAreaInsets:{top:30,right:0,bottom:24,left:0},landscapeSafeAreaInsets:{top:0,right:24,bottom:0,left:24},appProfileModel:"SM-S942B",appProfileOs:"android",appearance:{cutout:"none"}},"pura-x-max":{width:664,height:939,deviceScaleFactor:2.75,mobile:!0,userAgent:"Mozilla/5.0 (Phone;OpenHarmony 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 ArkWeb/6.0.0.42 Mobile",platform:"OpenHarmony",platformVersion:"6.0",architecture:"",model:"HUAWEI Pura X Max",safeAreaInsets:{top:30,right:0,bottom:24,left:0},landscapeSafeAreaInsets:{top:0,right:24,bottom:0,left:24},appProfileModel:"HUAWEI Pura X Max",appProfileOs:"android",appearance:{cutout:"none"}},"iphone-15-pro":{width:393,height:852,deviceScaleFactor:3,mobile:!0,userAgent:"Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",platform:"iPhone",platformVersion:"17.0",architecture:"",model:"iPhone",safeAreaInsets:{top:59,right:0,bottom:34,left:0},landscapeSafeAreaInsets:{top:0,right:59,bottom:21,left:59},appProfileModel:"iPhone 15 Pro",appProfileOs:"ios",appearance:{cutout:"dynamic-island"}},"iphone-se":{width:375,height:667,deviceScaleFactor:2,mobile:!0,userAgent:"Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1",platform:"iPhone",platformVersion:"16.0",architecture:"",model:"iPhone",safeAreaInsets:{top:20,right:0,bottom:0,left:0},landscapeSafeAreaInsets:{top:0,right:0,bottom:0,left:0},appProfileModel:"iPhone SE",appProfileOs:"ios",appearance:{cutout:"none"}},"pixel-8":{width:412,height:915,deviceScaleFactor:2.625,mobile:!0,userAgent:"Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36",platform:"Android",platformVersion:"14",architecture:"",model:"Pixel 8",safeAreaInsets:{top:30,right:0,bottom:24,left:0},landscapeSafeAreaInsets:{top:0,right:24,bottom:0,left:24},appProfileModel:"Pixel 8",appProfileOs:"android",appearance:{cutout:"none"}},"ipad-mini":{width:768,height:1024,deviceScaleFactor:2,mobile:!1,touch:!0,userAgent:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15",platform:"macOS",platformVersion:"10.15.7",architecture:"x86",model:"",safeAreaInsets:{top:24,right:0,bottom:20,left:0},landscapeSafeAreaInsets:{top:0,right:24,bottom:20,left:24},appProfileModel:"iPad mini",appProfileOs:"ios",appearance:{cutout:"none"}},"galaxy-s23":{width:360,height:780,deviceScaleFactor:3,mobile:!0,userAgent:"Mozilla/5.0 (Linux; Android 14; SM-S911B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36",platform:"Android",platformVersion:"14",architecture:"",model:"SM-S911B",safeAreaInsets:{top:30,right:0,bottom:24,left:0},landscapeSafeAreaInsets:{top:0,right:24,bottom:0,left:24},appProfileModel:"SM-S911B",appProfileOs:"android",appearance:{cutout:"none"}}};function resolveEmulationConfig(input){if(input.preset&&!(input.preset in DEVICE_PRESETS))throw new Error(`set_device_emulation: unknown preset "${input.preset}". Available: ${Object.keys(DEVICE_PRESETS).join(", ")}`);let preset=input.preset?DEVICE_PRESETS[input.preset]:void 0,width=input.width??preset?.width,height=input.height??preset?.height;if(!width||!height)throw new Error('set_device_emulation: must provide either "preset" or both "width" and "height"');let mobile=input.mobile??preset?.mobile??!0,orientation=input.orientation??"portrait",scale=input.scale??1;if(!Number.isFinite(scale)||scale<=0)throw new Error('set_device_emulation: "scale" must be a finite positive number');let[finalWidth,finalHeight]=orientation==="landscape"?[height,width]:[width,height],userAgent=input.userAgent??preset?.userAgent??"";if(!userAgent)throw new Error('set_device_emulation: "userAgent" is required when no preset is used (preset supplies a default)');let safeAreaInsets=orientation==="landscape"?preset?.landscapeSafeAreaInsets??{top:preset?.safeAreaInsets.left??0,right:preset?.safeAreaInsets.top??0,bottom:preset?.safeAreaInsets.right??0,left:preset?.safeAreaInsets.bottom??0}:preset?.safeAreaInsets??{top:0,right:0,bottom:0,left:0},appearance={cutout:orientation==="landscape"?"none":preset?.appearance.cutout??"none"};return{width:finalWidth,height:finalHeight,deviceScaleFactor:input.deviceScaleFactor??preset?.deviceScaleFactor??(mobile?2:1),scale,mobile,userAgent,platform:preset?.platform??(mobile?"iPhone":"macOS"),platformVersion:preset?.platformVersion??"",architecture:preset?.architecture??"",model:preset?.model??"",touch:input.touch??preset?.touch??mobile,orientation,safeAreaInsets,appearance,presetName:input.preset}}function buildEnableEmulationCommands(config2){let safeAreaInsets=config2.safeAreaInsets??{top:0,right:0,bottom:0,left:0};return[{method:"Emulation.setDeviceMetricsOverride",params:{width:config2.width,height:config2.height,screenWidth:config2.width,screenHeight:config2.height,deviceScaleFactor:config2.deviceScaleFactor,scale:config2.scale??1,mobile:config2.mobile,screenOrientation:{type:config2.orientation==="landscape"?"landscapePrimary":"portraitPrimary",angle:config2.orientation==="landscape"?90:0}}},{method:"Emulation.setUserAgentOverride",params:{userAgent:config2.userAgent,platform:config2.platform,userAgentMetadata:{mobile:config2.mobile,platform:config2.platform,platformVersion:config2.platformVersion,architecture:config2.architecture,model:config2.model}}},{method:"Emulation.setTouchEmulationEnabled",params:config2.touch?{enabled:!0,maxTouchPoints:5}:{enabled:!1}},{method:"Emulation.setEmitTouchEventsForMouse",params:{enabled:config2.touch,configuration:"mobile"}},{method:"Emulation.setSafeAreaInsetsOverride",params:{insets:{top:safeAreaInsets.top,topMax:safeAreaInsets.top,right:safeAreaInsets.right,rightMax:safeAreaInsets.right,bottom:safeAreaInsets.bottom,bottomMax:safeAreaInsets.bottom,left:safeAreaInsets.left,leftMax:safeAreaInsets.left}},optional:!0}]}function buildDisableEmulationCommands(){return[{method:"Emulation.clearDeviceMetricsOverride",params:{}},{method:"Emulation.setUserAgentOverride",params:{userAgent:""}},{method:"Emulation.setTouchEmulationEnabled",params:{enabled:!1}},{method:"Emulation.setEmitTouchEventsForMouse",params:{enabled:!1}},{method:"Emulation.setSafeAreaInsetsOverride",params:{insets:{}},optional:!0}]}function matchAXNodesByText(nodes,options){let{text,role,exact=!0}=options;if(typeof text!="string"||text.length===0)return{hits:[]};let hits=[];for(let node of nodes){if(node.ignored||node.backendDOMNodeId===void 0)continue;let name=node.name?.value;if(typeof name!="string"||name.length===0||!(exact?name===text:name.includes(text)))continue;let nodeRole=node.role?.value??"";role&&nodeRole!==role||hits.push({backendNodeId:node.backendDOMNodeId,role:nodeRole,name})}return{hits}}function formatAXTextMatchCandidates(hits,limit=5){return hits.slice(0,limit).map((hit,idx)=>{let name=hit.name.length>60?`${hit.name.slice(0,60)}âĻ`:hit.name,role=hit.role||"(no-role)";return` ${idx+1}. ${role} "${name}"`}).join(`
|
|
479
479
|
`)}function resolvePageClickDispatchPolicy(clickMode,visibilityState,touchEmulationEnabled){return clickMode!==void 0&&clickMode!=="auto"?{clickMode,stateAwareControls:clickMode==="dom"}:visibilityState==="hidden"?{clickMode:"dom",stateAwareControls:!0,fallbackReason:"page-hidden"}:{clickMode:touchEmulationEnabled?"touch":"mouse",stateAwareControls:!0}}function createPageClickResult(requestedTarget,dispatchTarget){let normalizedDispatchTarget={tag:dispatchTarget.tag,text:dispatchTarget.text},resolvedTarget={tag:dispatchTarget.sourceTarget?.tag??normalizedDispatchTarget.tag,text:dispatchTarget.sourceTarget?.text??normalizedDispatchTarget.text,strategy:dispatchTarget.strategy??"self",distance:dispatchTarget.distance??0};return{clicked:!0,tag:normalizedDispatchTarget.tag,text:requestedTarget.name||normalizedDispatchTarget.text,requestedTarget,resolvedTarget,dispatchTarget:normalizedDispatchTarget,...dispatchTarget.hitTarget?{hitTarget:dispatchTarget.hitTarget}:{},...dispatchTarget.frame?{frame:dispatchTarget.frame}:{},...dispatchTarget.coordinates?{coordinates:dispatchTarget.coordinates}:{},...dispatchTarget.actionableAncestorCandidates?.length?{actionableAncestorCandidates:dispatchTarget.actionableAncestorCandidates}:{},...dispatchTarget.controlState?{controlState:dispatchTarget.controlState}:{},...dispatchTarget.dispatchMode?{dispatchMode:dispatchTarget.dispatchMode}:{},...dispatchTarget.pointerType?{pointerType:dispatchTarget.pointerType}:{}}}function clickElementViaJS(){let el=this.nodeType===3?this.parentElement:this;if(!el||!el.isConnected)return null;let sourceTarget={tag:el.tagName?el.tagName.toLowerCase():"",text:(el.textContent||"").trim().slice(0,100)};if(el.tagName==="OPTION"){let select=el.closest("select");if(select){let desc=Object.getOwnPropertyDescriptor(window.HTMLSelectElement.prototype,"value");desc&&desc.set?desc.set.call(select,el.value):select.value=el.value,select.dispatchEvent(new Event("input",{bubbles:!0})),select.dispatchEvent(new Event("change",{bubbles:!0}));let rect2=select.getBoundingClientRect();return{tag:"option",text:(el.textContent||"").trim().slice(0,100),cx:rect2.x+rect2.width/2,cy:rect2.y+rect2.height/2,strategy:"self",distance:0,sourceTarget}}}function isActionable(node){if(!node||node.nodeType!==1)return!1;if(/^(A|BUTTON|INPUT|SELECT|TEXTAREA|SUMMARY|DETAILS|LABEL)$/i.test(node.tagName)||/button|link|tab|menuitem|checkbox|radio|option|switch/i.test(node.getAttribute("role")||"")||node.isContentEditable||typeof node.onclick=="function")return!0;let tabIndexAttribute=node.getAttribute("tabindex");if(tabIndexAttribute===null)return!1;let tabIndex=Number(tabIndexAttribute);return Number.isFinite(tabIndex)&&tabIndex>=0}let target=el,strategy="self",distance=0;if(!isActionable(target)){let ancestor=target.parentElement;for(;ancestor&&ancestor!==document.body&&distance<6;){if(distance+=1,isActionable(ancestor)){target=ancestor,strategy="actionable-ancestor";break}ancestor=ancestor.parentElement}}if(strategy==="self"&&!isActionable(target)){let cursor=target,descendantDistance=0;for(;cursor.children.length===1;){let child=cursor.children[0];if(!child||child.nodeType!==1||!(child.textContent||"").trim())break;cursor=child,descendantDistance+=1}cursor!==target?(target=cursor,strategy="single-child-descendant",distance=descendantDistance):distance=0}let rect=target.getBoundingClientRect();(rect.top<0||rect.left<0||rect.bottom>window.innerHeight||rect.right>window.innerWidth)&&(target.scrollIntoView({block:"center",inline:"center",behavior:"instant"}),rect=target.getBoundingClientRect());let cx=rect.x+rect.width/2,cy=rect.y+rect.height/2;try{let touch=new Touch({identifier:Date.now(),target,clientX:cx,clientY:cy});target.dispatchEvent(new TouchEvent("touchstart",{touches:[touch],targetTouches:[touch],changedTouches:[touch],bubbles:!0,cancelable:!0})),target.dispatchEvent(new TouchEvent("touchend",{touches:[],targetTouches:[],changedTouches:[touch],bubbles:!0,cancelable:!0}))}catch{}let controlState,controlType=target.tagName==="INPUT"&&/^(checkbox|radio)$/i.test(target.type||"")?String(target.type).toLowerCase():"";if(controlType==="checkbox"||controlType==="radio"){let checkedBefore=!!target.checked;target.click(),controlState={type:controlType,checkedBefore,checkedAfter:!!target.checked}}else target.click();return{tag:target.tagName?target.tagName.toLowerCase():"",text:(target.textContent||"").trim().slice(0,100),cx,cy,strategy,distance,sourceTarget,...controlState?{controlState}:{}}}function getClickCoordsFromNode(){let el=this.nodeType===3?this.parentElement:this;if(!el||!el.isConnected||!el.getBoundingClientRect)return null;let sourceTarget={tag:el.tagName?el.tagName.toLowerCase():"",text:(el.textContent||"").trim().slice(0,100)};function isActionable(node){if(!node||node.nodeType!==1)return!1;if(/^(A|BUTTON|INPUT|SELECT|TEXTAREA|SUMMARY|DETAILS|LABEL)$/i.test(node.tagName)||/button|link|tab|menuitem|checkbox|radio|option|switch/i.test(node.getAttribute("role")||"")||node.isContentEditable||typeof node.onclick=="function")return!0;let tabIndexAttribute=node.getAttribute("tabindex");if(tabIndexAttribute===null)return!1;let tabIndex=Number(tabIndexAttribute);return Number.isFinite(tabIndex)&&tabIndex>=0}let target=el,strategy="self",distance=0;if(!isActionable(target)){let ancestor=target.parentElement;for(;ancestor&&ancestor!==document.body&&distance<6;){if(distance+=1,isActionable(ancestor)){target=ancestor,strategy="actionable-ancestor";break}ancestor=ancestor.parentElement}}if(strategy==="self"&&!isActionable(target)){let cursor=target,descendantDistance=0;for(;cursor.children.length===1;){let child=cursor.children[0];if(!child||child.nodeType!==1||!(child.textContent||"").trim())break;cursor=child,descendantDistance+=1}cursor!==target?(target=cursor,strategy="single-child-descendant",distance=descendantDistance):distance=0}let actionableAncestorCandidates=[];if(strategy==="self"&&!isActionable(target)){let sourceRect=el.getBoundingClientRect(),ancestor=el.parentElement,candidateDistance=0;for(;ancestor&&ancestor!==document.body&&candidateDistance<6;){candidateDistance+=1;let rect2=ancestor.getBoundingClientRect(),reason=getComputedStyle(ancestor).cursor==="pointer"?"cursor-pointer":rect2.width*rect2.height>sourceRect.width*sourceRect.height*1.5?"containing-block":null;if(reason){let escapeCss=value=>globalThis.CSS&&typeof globalThis.CSS.escape=="function"?globalThis.CSS.escape(value):value.replace(/[^a-zA-Z0-9_-]/g,character=>`\\${character}`),candidateSelector=ancestor.id?`#${escapeCss(ancestor.id)}`:"";if(!candidateSelector){let path23=[],cursor=ancestor;for(;cursor&&cursor!==document.documentElement&&path23.length<5;){let parent=cursor.parentElement,tag=cursor.tagName.toLowerCase();if(!parent){path23.unshift(tag);break}let siblings=Array.from(parent.children).filter(item=>item.tagName===cursor.tagName),index=siblings.indexOf(cursor)+1;path23.unshift(siblings.length>1?`${tag}:nth-of-type(${index})`:tag),cursor=parent}candidateSelector=path23.join(" > ")}candidateSelector&&actionableAncestorCandidates.push({selector:candidateSelector,tag:ancestor.tagName.toLowerCase(),text:(ancestor.textContent||"").trim().slice(0,100),distance:candidateDistance,reason})}if(actionableAncestorCandidates.length>=3)break;ancestor=ancestor.parentElement}}let rect=target.getBoundingClientRect();return(rect.top<0||rect.left<0||rect.bottom>window.innerHeight||rect.right>window.innerWidth)&&(target.scrollIntoView({block:"center",inline:"center",behavior:"instant"}),rect=target.getBoundingClientRect()),{x:rect.x+rect.width/2,y:rect.y+rect.height/2,tag:target.tagName?target.tagName.toLowerCase():"",text:(target.textContent||"").trim().slice(0,100),...target.tagName==="INPUT"?{inputType:String(target.type||"").toLowerCase()}:{},strategy,distance,sourceTarget,...actionableAncestorCandidates.length>0?{actionableAncestorCandidates}:{}}}function isPageDragPoint(value){if(!value||typeof value!="object")return!1;let point=value;return Number.isFinite(point.x)&&Number.isFinite(point.y)&&point.x>=0&&point.y>=0}function resolveEndpoint(value,name){if(typeof value=="string"&&value.trim().length>0)return value.trim();if(isPageDragPoint(value))return{x:value.x,y:value.y};throw new Error(`page_drag: "${name}" must be a non-empty CSS/@ref selector or { x, y } viewport point.`)}function resolvePageDragInput(data){if(!data||typeof data!="object")throw new Error("page_drag: payload is required");if(data.dragMode!==void 0&&!["auto","dom","mouse","touch"].includes(data.dragMode))throw new Error('page_drag: "dragMode" must be one of auto, dom, mouse, touch');let durationMs=data.durationMs??400;if(!Number.isFinite(durationMs)||durationMs<0||durationMs>5e3)throw new Error('page_drag: "durationMs" must be between 0 and 5000.');return{from:resolveEndpoint(data.from,"from"),to:resolveEndpoint(data.to,"to"),dragMode:data.dragMode??"auto",durationMs:Math.round(durationMs)}}function resolvePageDragDispatchPolicy(dragMode,visibilityState,touchEmulationEnabled){let requestedMode=dragMode??"auto",pointerType=requestedMode==="mouse"||requestedMode==="touch"?requestedMode:touchEmulationEnabled?"touch":"mouse";return requestedMode==="dom"?{dispatchMode:"dom",pointerType}:requestedMode==="auto"&&visibilityState==="hidden"?{dispatchMode:"dom",pointerType,fallbackReason:"page-hidden"}:{dispatchMode:"trusted-input",pointerType}}function buildPageDragPath(from,to,durationMs){let steps=Math.max(2,Math.min(60,Math.ceil(durationMs/25)));return{points:Array.from({length:steps},(_,index)=>{let ratio=(index+1)/steps;return{x:from.x+(to.x-from.x)*ratio,y:from.y+(to.y-from.y)*ratio}}),intervalMs:durationMs/steps}}function dragBetweenPointsInPage(from,points,pointerType){let target=document.elementFromPoint(from.x,from.y);if(!target)return{dragged:!1,steps:0,error:`No element found at drag start point (${from.x}, ${from.y})`};if(points.length===0)return{dragged:!1,steps:0,error:"Drag path must contain at least one point"};let view=target.ownerDocument.defaultView??window,realm=view,pointerId=1,pointerInit=(point,buttons,pressure)=>({bubbles:!0,cancelable:!0,composed:!0,view,clientX:point.x,clientY:point.y,screenX:point.x,screenY:point.y,button:0,buttons,pointerId,pointerType,isPrimary:!0,pressure,width:1,height:1}),dispatchPointer=(type,point,buttons,pressure)=>typeof realm.PointerEvent!="function"?!1:(target.dispatchEvent(new realm.PointerEvent(type,pointerInit(point,buttons,pressure))),!0),dispatchMouse=(type,point,buttons)=>typeof realm.MouseEvent!="function"?!1:(target.dispatchEvent(new realm.MouseEvent(type,{bubbles:!0,cancelable:!0,composed:!0,view,clientX:point.x,clientY:point.y,screenX:point.x,screenY:point.y,button:0,buttons})),!0),createTouch=point=>{let init={identifier:pointerId,target,clientX:point.x,clientY:point.y,screenX:point.x,screenY:point.y,pageX:point.x+view.scrollX,pageY:point.y+view.scrollY,radiusX:1,radiusY:1,rotationAngle:0,force:.5};return typeof realm.Touch=="function"?new realm.Touch(init):init},dispatchTouch=(type,point)=>{if(typeof realm.TouchEvent!="function")return!1;let touch=createTouch(point),activeTouches=type==="touchend"?[]:[touch];return target.dispatchEvent(new realm.TouchEvent(type,{bubbles:!0,cancelable:!0,composed:!0,touches:activeTouches,targetTouches:activeTouches,changedTouches:[touch]})),!0},dispatched=dispatchPointer("pointerdown",from,1,.5);dispatched=pointerType==="touch"?dispatchTouch("touchstart",from)||dispatched:dispatchMouse("mousedown",from,1)||dispatched;for(let point of points)dispatched=dispatchPointer("pointermove",point,1,.5)||dispatched,dispatched=pointerType==="touch"?dispatchTouch("touchmove",point)||dispatched:dispatchMouse("mousemove",point,1)||dispatched;let end=points[points.length-1];return dispatched=pointerType==="touch"?dispatchTouch("touchend",end)||dispatched:dispatchMouse("mouseup",end,0)||dispatched,dispatched=dispatchPointer("pointerup",end,0,0)||dispatched,dispatched?{dragged:!0,steps:points.length}:{dragged:!1,steps:0,error:"This page does not support synthetic drag events"}}var DRAG_BETWEEN_POINTS_IN_PAGE_SOURCE=dragBetweenPointsInPage.toString();function buildPageDragDomExpression(from,points,pointerType){return`(${DRAG_BETWEEN_POINTS_IN_PAGE_SOURCE})(${JSON.stringify(from)}, ${JSON.stringify(points)}, ${JSON.stringify(pointerType)})`}function unwrapPageDragDomResult(result){if(!result)throw new Error("page_drag: DOM simulation returned no result");if(!result.dragged)throw new Error(`page_drag: ${result.error}`);return result}function getDragCoordsFromNode(){let el=this.nodeType===Node.TEXT_NODE?this.parentElement:this;if(!el||typeof el.getBoundingClientRect!="function")return null;let rect=el.getBoundingClientRect(),viewportWidth=window.visualViewport?.width??window.innerWidth,viewportHeight=window.visualViewport?.height??window.innerHeight;if(rect.width<=0||rect.height<=0)return{x:0,y:0,tag:"",text:"",error:"Element has no visible bounds"};if(rect.right<=0||rect.bottom<=0||rect.left>=viewportWidth||rect.top>=viewportHeight)return{x:0,y:0,tag:"",text:"",error:"Element is outside the current viewport; scroll it into view before dragging"};let x=Math.min(Math.max(rect.left+rect.width/2,0),Math.max(viewportWidth-1,0)),y=Math.min(Math.max(rect.top+rect.height/2,0),Math.max(viewportHeight-1,0));return{x,y,tag:el.tagName?.toLowerCase()??"",text:(el.textContent??"").trim().slice(0,100)}}var SKIP_ROLES=new Set(["none","generic","InlineTextBox","LineBreak","paragraph","Section","LabelText"]),ALWAYS_SKIP_ROLES=new Set(["InlineTextBox","LineBreak","graphics-symbol","graphics-document"]),INTERACTIVE_ROLES=new Set(["button","checkbox","combobox","gridcell","link","listbox","menuitem","menuitemcheckbox","menuitemradio","option","radio","scrollbar","searchbox","slider","spinbutton","switch","tab","textbox","treeitem"]);function isInteractiveSnapshotNode(node){let focusedControl=!!node.focused&&node.role!=="RootWebArea"&&node.role!=="WebArea";return INTERACTIVE_ROLES.has(node.role)||focusedControl||node.checked!==void 0||node.expanded!==void 0||!!node.selected}function hasInteractiveSnapshotNode(node){return node?isInteractiveSnapshotNode(node)?!0:(node.children??[]).some(hasInteractiveSnapshotNode):!1}var CHECKABLE_AX_ROLES=new Set(["checkbox","menuitemcheckbox","menuitemradio","radio","switch"]);function resolveDOMSnapshotViewportBounds(metrics){let viewport=metrics.visualViewport??metrics.cssVisualViewport;return normalizePageViewportBounds({left:viewport?.pageX??0,top:viewport?.pageY??0,width:viewport?.clientWidth,height:viewport?.clientHeight})}function normalizePageViewportBounds(value){if(!value||typeof value!="object")return null;let{left,top,width,height}=value;return typeof left!="number"||typeof top!="number"||typeof width!="number"||typeof height!="number"||!Number.isFinite(left)||!Number.isFinite(top)||!Number.isFinite(width)||!Number.isFinite(height)||width<=0||height<=0?null:{left,top,width,height}}function readDOMCheckedState(){let tag=String(this&&this.tagName||"").toLowerCase(),type=String(this&&this.type||"").toLowerCase();if(tag==="input"&&(type==="checkbox"||type==="radio"))return!!this.checked;let ariaChecked=this&&this.getAttribute&&this.getAttribute("aria-checked");if(ariaChecked==="mixed")return"mixed";if(ariaChecked==="true")return!0;if(ariaChecked==="false")return!1}async function reconcileAXCheckedStates(nodes,readCheckedState){let candidates=nodes.filter(node=>node.backendDOMNodeId!==void 0&&CHECKABLE_AX_ROLES.has(node.role?.value??"")),nextIndex=0,workers=Array.from({length:Math.min(8,candidates.length)},async()=>{for(;nextIndex<candidates.length;){let node=candidates[nextIndex++];if(!(!node||node.backendDOMNodeId===void 0))try{let checked=await readCheckedState(node.backendDOMNodeId);if(checked===void 0)continue;let properties=node.properties??=[],existing=properties.find(property=>property.name==="checked");existing?existing.value.value=checked:properties.push({name:"checked",value:{value:checked}})}catch{}}});await Promise.all(workers)}function extractAXProperties(node){let result={};if(!node.properties)return result;for(let prop of node.properties)switch(prop.name){case"focused":prop.value.value===!0&&(result.focused=!0);break;case"checked":result.checked=prop.value.value==="mixed"?"mixed":prop.value.value===!0;break;case"disabled":prop.value.value===!0&&(result.disabled=!0);break;case"required":prop.value.value===!0&&(result.required=!0);break;case"expanded":result.expanded=prop.value.value===!0;break;case"selected":prop.value.value===!0&&(result.selected=!0);break;case"level":result.level=prop.value.value;break}return result}function formatSnapshotNode(node,indent,lines){let line=" ".repeat(indent);node.ref&&(line+=`${node.ref} `),line+=`[${node.role}`,node.name&&(line+=` "${node.name}"`),line+="]";let annotations=[];if(node.value!==void 0&&annotations.push(`value="${node.value}"`),node.focused&&annotations.push("focused"),node.checked===!0&&annotations.push("checked"),node.checked==="mixed"&&annotations.push("mixed"),node.disabled&&annotations.push("disabled"),node.required&&annotations.push("required"),node.expanded===!0&&annotations.push("expanded"),node.expanded===!1&&annotations.push("collapsed"),node.selected&&annotations.push("selected"),node.level!==void 0&&annotations.push(`level=${node.level}`),node.description&&annotations.push(`desc="${node.description}"`),annotations.length>0&&(line+=` (${annotations.join(", ")})`),lines.push(line),node.children)for(let child of node.children)formatSnapshotNode(child,indent+1,lines)}function filterSnapshotTree(node,mode,visibleBackendNodeIds){if(!node)return null;if(mode==="full")return node;let keepSelf=mode==="interactive"?isInteractiveSnapshotNode(node):node.backendDOMNodeId!==void 0&&!!visibleBackendNodeIds?.has(node.backendDOMNodeId);if(mode==="interactive"&&keepSelf)return node;let children2=(node.children??[]).map(child=>filterSnapshotTree(child,mode,visibleBackendNodeIds)).filter(child=>child!==null);return!keepSelf&&children2.length===0?null:{...node,...children2.length>0?{children:children2}:{children:void 0}}}function snapshotNodeMatchesQuery(node,query){return query.role&&node.role!==query.role?!1:query.text===void 0?!0:query.exact??!0?node.name===query.text:node.name.includes(query.text)}function resolvePageSnapshotQuery(query){if(query===void 0)return;if(!query||typeof query!="object"||Array.isArray(query))throw new Error("page_snapshot: query must be an object");let{text,role,exact}=query;if(text!==void 0&&(typeof text!="string"||!text.trim()))throw new Error("page_snapshot: query.text must be a non-empty string");if(role!==void 0&&(typeof role!="string"||!role.trim()))throw new Error("page_snapshot: query.role must be a non-empty string");if(text===void 0&&role===void 0)throw new Error("page_snapshot: query must include text or role");if(exact!==void 0&&typeof exact!="boolean")throw new Error("page_snapshot: query.exact must be a boolean");return{...text!==void 0?{text}:{},...role!==void 0?{role}:{},...exact!==void 0?{exact}:{}}}function snapshotQueryMatch(node){return{...node.ref?{ref:node.ref}:{},role:node.role,name:node.name,...node.value!==void 0?{value:node.value}:{},...node.disabled?{disabled:!0}:{},...node.checked!==void 0?{checked:node.checked}:{},...node.selected?{selected:!0}:{},...node.expanded!==void 0?{expanded:node.expanded}:{}}}function compactSnapshotQueryField(value){if(value.length<=2048)return{value,truncated:!1};let marker="âĻ [truncated] âĻ",remaining=2048-marker.length,head=Math.ceil(remaining/2),tail=Math.floor(remaining/2);return{value:value.slice(0,head)+marker+value.slice(-tail),truncated:!0}}function compactSnapshotQueryMatch(match){let role=compactSnapshotQueryField(match.role),name=compactSnapshotQueryField(match.name),value=match.value===void 0?void 0:compactSnapshotQueryField(match.value);return{match:{...match,role:role.value,name:name.value,...value?{value:value.value}:{}},truncated:role.truncated||name.truncated||!!value?.truncated}}function limitPageSnapshotQueryMatches(matches){let limited=[],encoder=new TextEncoder,bytes=2,truncated=!1;for(let candidate of matches){if(limited.length>=100){truncated=!0;break}let compacted=compactSnapshotQueryMatch(candidate),candidateBytes=encoder.encode(JSON.stringify(compacted.match)).byteLength+(limited.length>0?1:0);if(bytes+candidateBytes>262144){truncated=!0;break}limited.push(compacted.match),bytes+=candidateBytes,truncated=truncated||compacted.truncated}return limited.length<matches.length&&(truncated=!0),{matches:limited,truncated}}function filterSnapshotTreeByQuery(node,query){if(!node)return{tree:null,matches:[]};let matches=[],children2=[];for(let child of node.children??[]){let childResult=filterSnapshotTreeByQuery(child,query);matches.push(...childResult.matches),childResult.tree&&children2.push(childResult.tree)}let matchesSelf=snapshotNodeMatchesQuery(node,query);return matchesSelf&&matches.unshift(snapshotQueryMatch(node)),!matchesSelf&&children2.length===0?{tree:null,matches}:{tree:{...node,...children2.length>0?{children:children2}:{children:void 0}},matches}}function countSnapshotNodes(node){return node?1+(node.children??[]).reduce((total,child)=>total+countSnapshotNodes(child),0):0}function takeHeadTail(items,limit){let available=Math.max(0,Math.floor(limit)-1),tailCount=available>1?Math.max(1,Math.floor(available*.3)):0,headCount=Math.max(0,available-tailCount);return{items:[...items.slice(0,headCount),...items.slice(Math.max(headCount,items.length-tailCount))],headCount}}function formatSnapshotWithLimits(lines,limits={}){let maxNodes=limits.maxNodes===void 0||limits.maxNodes===0?1/0:Math.max(3,Math.floor(limits.maxNodes)),maxChars=limits.maxChars===void 0?6e4:limits.maxChars===0?1/0:Math.max(200,Math.floor(limits.maxChars)),outputLines=lines,truncated=!1;if(outputLines.length>maxNodes){let originalCount=outputLines.length,selected=takeHeadTail(outputLines,maxNodes);outputLines=[...selected.items.slice(0,selected.headCount),`... [snapshot nodes omitted: showing ${selected.items.length} of ${originalCount}; use rootSelector or mode:"viewport"]`,...selected.items.slice(selected.headCount)],truncated=!0}let snapshot=outputLines.join(`
|
|
480
480
|
`);if(snapshot.length>maxChars){let originalLength=snapshot.length,marker=`
|
|
481
481
|
... [snapshot content omitted: showing at most ${maxChars} of ${originalLength} chars; use rootSelector, mode:"viewport", or maxChars:0]
|
|
@@ -567,7 +567,279 @@ ${SOURCE_BADGES[source]}
|
|
|
567
567
|
for (const icon of state.originalIcons || []) document.head.appendChild(icon);
|
|
568
568
|
}
|
|
569
569
|
delete window.__mearlControlledFavicon__;
|
|
570
|
-
})();`;async function ensureControlledIndicator(session,controlSource="local"){return enqueueIndicatorOperation(session,async()=>{let current=injectedSessions.get(session);if(current?.controlSource!==controlSource){injectedSessions.set(session,{identifier:null,controlSource});try{await ensureCdpDomain(session.client,"Page"),current?.identifier&&await session.client.sendCommand("Page.removeScriptToEvaluateOnNewDocument",{identifier:current.identifier}).catch(()=>{});let result=await session.client.sendCommand("Page.addScriptToEvaluateOnNewDocument",{source:createFaviconScript(controlSource),runImmediately:!0});injectedSessions.set(session,{identifier:result?.identifier??null,controlSource})}catch{injectedSessions.delete(session)}}})}async function releaseControlledIndicator(session){return enqueueIndicatorOperation(session,async()=>{let current=injectedSessions.get(session);injectedSessions.delete(session),current?.identifier&&await session.client.sendCommand("Page.removeScriptToEvaluateOnNewDocument",{identifier:current.identifier}).catch(()=>{}),await session.client.sendCommand("Runtime.evaluate",{expression:RESTORE_FAVICON_SCRIPT}).catch(()=>{})})}var actionMap=new Map;function registerActions(actions){for(let action of actions){if(actionMap.has(action.name))throw new Error(`CDP action "${action.name}" is already registered`);actionMap.set(action.name,action)}}function getRegisteredActionNames(){return[...actionMap.keys()]}async function dispatchCdpAction(cdpSession2,action,data,controlSource="local"){let entry=actionMap.get(action);if(!entry)throw new Error(`Action "${action}" is not supported in CDP mode`);if(entry.session==="browser")return entry.handler(cdpSession2,data,controlSource);let tabId=typeof data?.tabId=="number"?data.tabId:void 0,pageSession=await cdpSession2.getPageSession(tabId);return await ensureControlledIndicator(pageSession,controlSource),entry.handler(pageSession,data,controlSource)}var mockStore=new Map,fetchInterceptEnabled=new Set;function clearCdpMockState(){mockStore.clear(),fetchInterceptEnabled.clear()}function tryParseJson(value){try{return JSON.parse(value)}catch{return value}}function isSubset(subset,superset){return subset===superset?!0:subset==null||superset==null?subset===superset:typeof subset!="object"||typeof superset!="object"?String(subset)===String(superset):Array.isArray(subset)?Array.isArray(superset)&&JSON.stringify(subset)===JSON.stringify(superset):Object.entries(subset).every(([key,value])=>key in superset?isSubset(value,superset[key]):!1)}function matchesConditions(mock,request){if(!mock.conditions||Object.keys(mock.conditions).length===0)return!0;let requestData={};try{new URL(request.url??"").searchParams.forEach((value,key)=>{requestData[key]=tryParseJson(value)})}catch{}if(request.postData)try{let json2=JSON.parse(request.postData);typeof json2=="object"&&json2!==null&&Object.assign(requestData,json2)}catch{try{new URLSearchParams(request.postData).forEach((value,key)=>{requestData[key]=tryParseJson(value)})}catch{}}return isSubset(mock.conditions,requestData)?!0:requestData.data&&typeof requestData.data=="object"?isSubset(mock.conditions,requestData.data):!1}function findMatchedMock(url2,postData){for(let list of mockStore.values())for(let mock of list)if(mock.enabled&&(url2.includes(`/${mock.apiName}/`)||url2.includes(mock.apiName))&&matchesConditions(mock,{url:url2,postData}))return mock;return null}function sameConditions(a,b){let aKeys=a?Object.keys(a):[],bKeys=b?Object.keys(b):[];return aKeys.length===0||bKeys.length===0?aKeys.length===0&&bKeys.length===0:aKeys.length!==bKeys.length?!1:aKeys.every(k=>JSON.stringify(a[k])===JSON.stringify(b[k]))}function stripEncodingHeaders(headers){if(!headers)return[];let stripped=new Set(["content-encoding","content-length"]);return headers.filter(header=>!stripped.has(header.name.toLowerCase()))}function ensureCorsHeaders(headers,request){let origin=Object.entries(request.headers??{}).find(([name])=>name.toLowerCase()==="origin")?.[1];if(!origin)return headers;let result=[...headers],hasHeader=name=>result.some(header=>header.name.toLowerCase()===name.toLowerCase());return hasHeader("access-control-allow-origin")||result.push({name:"access-control-allow-origin",value:origin}),hasHeader("access-control-allow-credentials")||result.push({name:"access-control-allow-credentials",value:"true"}),result}async function ensureMockInterception(session){fetchInterceptEnabled.has(session.targetId)||(await session.client.sendCommand("Fetch.enable",{patterns:[{urlPattern:"*",requestStage:"Request"},{urlPattern:"*",requestStage:"Response"}]}),fetchInterceptEnabled.add(session.targetId),session.client.on("Fetch.requestPaused",async params=>{let url2=params.request?.url??"",isResponseStage=params.responseStatusCode!=null||params.responseErrorReason!=null,passthrough=()=>session.client.sendCommand(isResponseStage?"Fetch.continueResponse":"Fetch.continueRequest",{requestId:params.requestId}).catch(()=>{});if(params.request?.method==="OPTIONS"){await passthrough();return}let matchedMock=findMatchedMock(url2,params.request?.postData),fulfillMock=async(mock,responseCode,responseHeaders)=>{let responseBody=JSON.stringify(mock.responseData),base64Body=Buffer.from(responseBody,"utf-8").toString("base64");await session.client.sendCommand("Fetch.fulfillRequest",{requestId:params.requestId,responseCode,responseHeaders,body:base64Body})};if(!matchedMock){await passthrough();return}try{if(!isResponseStage){matchedMock.duration!==void 0?(matchedMock.duration>0&&await new Promise(r=>setTimeout(r,matchedMock.duration)),await fulfillMock(matchedMock,200,ensureCorsHeaders([{name:"content-type",value:"application/json; charset=utf-8"},{name:"x-mock-by",value:"mearl-cdp"}],params.request))):await passthrough();return}await fulfillMock(matchedMock,params.responseStatusCode??200,stripEncodingHeaders(params.responseHeaders))}catch{await passthrough()}}))}async function cdpSetMock(session,data){let{apiName,mockData,fields,enabled,duration:duration3,conditions}=data;if(!apiName||typeof apiName!="string"||apiName.trim()==="")throw new Error("Invalid apiName");if(enabled===!1)return mockStore.delete(apiName),{success:!0,affectedCount:1,message:`Mock disabled for ${apiName}`};if(mockData===void 0&&(!fields||fields.length===0))throw new Error("Either mockData or fields must be provided");if(fields&&fields.length>100)throw new Error("Too many fields: maximum 100 fields allowed");let normConditions=conditions&&Object.keys(conditions).length>0?conditions:void 0,finalMockData=mockData;if(fields&&fields.length>0){let conditionMatcher={apiName,responseData:null,conditions:normConditions,enabled:!0},baseRequest=[...session.buffers.requests].reverse().find(request=>request.method!=="OPTIONS"&&request.responseBody!==null&&request.responseBody!==void 0&&(request.apiName?.includes(apiName)||request.url?.includes(apiName))&&matchesConditions(conditionMatcher,{url:request.url,postData:typeof request.postData=="string"?request.postData:void 0}));finalMockData=baseRequest?.responseBody?JSON.parse(JSON.stringify(baseRequest.responseBody)):{};for(let field of fields)setValueByPath(finalMockData,field.path,field.value)}let entry={apiName,responseData:finalMockData,duration:duration3,conditions:normConditions,enabled:!0},list=mockStore.get(apiName)??[],idx=list.findIndex(m=>sameConditions(m.conditions,normConditions));return idx>=0?list[idx]=entry:list.push(entry),mockStore.set(apiName,list),await ensureMockInterception(session),{success:!0,affectedCount:1,message:`Mock set for ${apiName}`}}function cdpGetMocks(_session,data){let matcher=data?.apiName?new RegExp(data.apiName,"i"):null,mocks=[...mockStore.values()].flat().filter(m=>!matcher||matcher.test(m.apiName)).map(m=>({apiName:m.apiName,responseData:m.responseData,duration:m.duration??0,conditions:m.conditions,disabled:!m.enabled}));return{mocks,count:mocks.length}}registerActions([{name:"set_mock",session:"page",handler:cdpSetMock},{name:"get_mocks",session:"page",handler:async(s,d)=>cdpGetMocks(s,d)}]);
|
|
570
|
+
})();`;async function ensureControlledIndicator(session,controlSource="local"){return enqueueIndicatorOperation(session,async()=>{let current=injectedSessions.get(session);if(current?.controlSource!==controlSource){injectedSessions.set(session,{identifier:null,controlSource});try{await ensureCdpDomain(session.client,"Page"),current?.identifier&&await session.client.sendCommand("Page.removeScriptToEvaluateOnNewDocument",{identifier:current.identifier}).catch(()=>{});let result=await session.client.sendCommand("Page.addScriptToEvaluateOnNewDocument",{source:createFaviconScript(controlSource),runImmediately:!0});injectedSessions.set(session,{identifier:result?.identifier??null,controlSource})}catch{injectedSessions.delete(session)}}})}async function releaseControlledIndicator(session){return enqueueIndicatorOperation(session,async()=>{let current=injectedSessions.get(session);injectedSessions.delete(session),current?.identifier&&await session.client.sendCommand("Page.removeScriptToEvaluateOnNewDocument",{identifier:current.identifier}).catch(()=>{}),await session.client.sendCommand("Runtime.evaluate",{expression:RESTORE_FAVICON_SCRIPT}).catch(()=>{})})}var actionMap=new Map;function registerActions(actions){for(let action of actions){if(actionMap.has(action.name))throw new Error(`CDP action "${action.name}" is already registered`);actionMap.set(action.name,action)}}function getRegisteredActionNames(){return[...actionMap.keys()]}async function dispatchCdpAction(cdpSession2,action,data,controlSource="local"){let entry=actionMap.get(action);if(!entry)throw new Error(`Action "${action}" is not supported in CDP mode`);if(entry.session==="browser")return entry.handler(cdpSession2,data,controlSource);let tabId=typeof data?.tabId=="number"?data.tabId:void 0,pageSession=await cdpSession2.getPageSession(tabId);return await ensureControlledIndicator(pageSession,controlSource),entry.handler(pageSession,data,controlSource)}var mockStore=new Map,fetchInterceptEnabled=new Set;function clearCdpMockState(){mockStore.clear(),fetchInterceptEnabled.clear()}function tryParseJson(value){try{return JSON.parse(value)}catch{return value}}function isSubset(subset,superset){return subset===superset?!0:subset==null||superset==null?subset===superset:typeof subset!="object"||typeof superset!="object"?String(subset)===String(superset):Array.isArray(subset)?Array.isArray(superset)&&JSON.stringify(subset)===JSON.stringify(superset):Object.entries(subset).every(([key,value])=>key in superset?isSubset(value,superset[key]):!1)}function matchesConditions(mock,request){if(!mock.conditions||Object.keys(mock.conditions).length===0)return!0;let requestData={};try{new URL(request.url??"").searchParams.forEach((value,key)=>{requestData[key]=tryParseJson(value)})}catch{}if(request.postData)try{let json2=JSON.parse(request.postData);typeof json2=="object"&&json2!==null&&Object.assign(requestData,json2)}catch{try{new URLSearchParams(request.postData).forEach((value,key)=>{requestData[key]=tryParseJson(value)})}catch{}}return isSubset(mock.conditions,requestData)?!0:requestData.data&&typeof requestData.data=="object"?isSubset(mock.conditions,requestData.data):!1}function findMatchedMock(url2,postData){for(let list of mockStore.values())for(let mock of list)if(mock.enabled&&(url2.includes(`/${mock.apiName}/`)||url2.includes(mock.apiName))&&matchesConditions(mock,{url:url2,postData}))return mock;return null}function sameConditions(a,b){let aKeys=a?Object.keys(a):[],bKeys=b?Object.keys(b):[];return aKeys.length===0||bKeys.length===0?aKeys.length===0&&bKeys.length===0:aKeys.length!==bKeys.length?!1:aKeys.every(k=>JSON.stringify(a[k])===JSON.stringify(b[k]))}function stripEncodingHeaders(headers){if(!headers)return[];let stripped=new Set(["content-encoding","content-length"]);return headers.filter(header=>!stripped.has(header.name.toLowerCase()))}function ensureCorsHeaders(headers,request){let origin=Object.entries(request.headers??{}).find(([name])=>name.toLowerCase()==="origin")?.[1];if(!origin)return headers;let result=[...headers],hasHeader=name=>result.some(header=>header.name.toLowerCase()===name.toLowerCase());return hasHeader("access-control-allow-origin")||result.push({name:"access-control-allow-origin",value:origin}),hasHeader("access-control-allow-credentials")||result.push({name:"access-control-allow-credentials",value:"true"}),result}async function ensureMockInterception(session){fetchInterceptEnabled.has(session.targetId)||(await session.client.sendCommand("Fetch.enable",{patterns:[{urlPattern:"*",requestStage:"Request"},{urlPattern:"*",requestStage:"Response"}]}),fetchInterceptEnabled.add(session.targetId),session.client.on("Fetch.requestPaused",async params=>{let url2=params.request?.url??"",isResponseStage=params.responseStatusCode!=null||params.responseErrorReason!=null,passthrough=()=>session.client.sendCommand(isResponseStage?"Fetch.continueResponse":"Fetch.continueRequest",{requestId:params.requestId}).catch(()=>{});if(params.request?.method==="OPTIONS"){await passthrough();return}let matchedMock=findMatchedMock(url2,params.request?.postData),fulfillMock=async(mock,responseCode,responseHeaders)=>{let responseBody=JSON.stringify(mock.responseData),base64Body=Buffer.from(responseBody,"utf-8").toString("base64");await session.client.sendCommand("Fetch.fulfillRequest",{requestId:params.requestId,responseCode,responseHeaders,body:base64Body})};if(!matchedMock){await passthrough();return}try{if(!isResponseStage){matchedMock.duration!==void 0?(matchedMock.duration>0&&await new Promise(r=>setTimeout(r,matchedMock.duration)),await fulfillMock(matchedMock,200,ensureCorsHeaders([{name:"content-type",value:"application/json; charset=utf-8"},{name:"x-mock-by",value:"mearl-cdp"}],params.request))):await passthrough();return}await fulfillMock(matchedMock,params.responseStatusCode??200,stripEncodingHeaders(params.responseHeaders))}catch{await passthrough()}}))}async function cdpSetMock(session,data){let{apiName,mockData,fields,enabled,duration:duration3,conditions}=data;if(!apiName||typeof apiName!="string"||apiName.trim()==="")throw new Error("Invalid apiName");if(enabled===!1)return mockStore.delete(apiName),{success:!0,affectedCount:1,message:`Mock disabled for ${apiName}`};if(mockData===void 0&&(!fields||fields.length===0))throw new Error("Either mockData or fields must be provided");if(fields&&fields.length>100)throw new Error("Too many fields: maximum 100 fields allowed");let normConditions=conditions&&Object.keys(conditions).length>0?conditions:void 0,finalMockData=mockData;if(fields&&fields.length>0){let conditionMatcher={apiName,responseData:null,conditions:normConditions,enabled:!0},baseRequest=[...session.buffers.requests].reverse().find(request=>request.method!=="OPTIONS"&&request.responseBody!==null&&request.responseBody!==void 0&&(request.apiName?.includes(apiName)||request.url?.includes(apiName))&&matchesConditions(conditionMatcher,{url:request.url,postData:typeof request.postData=="string"?request.postData:void 0}));finalMockData=baseRequest?.responseBody?JSON.parse(JSON.stringify(baseRequest.responseBody)):{};for(let field of fields)setValueByPath(finalMockData,field.path,field.value)}let entry={apiName,responseData:finalMockData,duration:duration3,conditions:normConditions,enabled:!0},list=mockStore.get(apiName)??[],idx=list.findIndex(m=>sameConditions(m.conditions,normConditions));return idx>=0?list[idx]=entry:list.push(entry),mockStore.set(apiName,list),await ensureMockInterception(session),{success:!0,affectedCount:1,message:`Mock set for ${apiName}`}}function cdpGetMocks(_session,data){let matcher=data?.apiName?new RegExp(data.apiName,"i"):null,mocks=[...mockStore.values()].flat().filter(m=>!matcher||matcher.test(m.apiName)).map(m=>({apiName:m.apiName,responseData:m.responseData,duration:m.duration??0,conditions:m.conditions,disabled:!m.enabled}));return{mocks,count:mocks.length}}registerActions([{name:"set_mock",session:"page",handler:cdpSetMock},{name:"get_mocks",session:"page",handler:async(s,d)=>cdpGetMocks(s,d)}]);function installDeviceChromeView(root,config2,options={}){let ownerDocument=root.ownerDocument,browser=ownerDocument.defaultView??window,labels={screenshot:"Screenshot",copied:"Copied",downloaded:"Downloaded",captureFailed:"Capture failed",bottomAction:"App simulation settings",...options.labels},state={statusBarVisible:!0,statusBarBackground:"#ffffff",textColor:"#0f131a",bottomActionEnabled:!1,...options.initialState},normalizedBarHeight=value=>Number.isFinite(value)?Math.min(200,Math.max(0,Math.round(value))):0,statusBarHeight=normalizedBarHeight(config2.statusBarHeight),bottomBarHeight=normalizedBarHeight(config2.bottomBarHeight),cutout=config2.platform==="ios"?config2.cutout:"none",cutoutMarkup=cutout==="none"?"":cutout==="dynamic-island"?`<button id="device-cutout" type="button" data-kind="${cutout}" data-state="idle"><svg id="cutout-camera" viewBox="0 0 20 20" aria-hidden="true"><path d="M6.5 5.5 7.7 3.8h4.6l1.2 1.7h2.2c1 0 1.8.8 1.8 1.8v7c0 1-.8 1.8-1.8 1.8H4.3c-1 0-1.8-.8-1.8-1.8v-7c0-1 .8-1.8 1.8-1.8z"/><circle cx="10" cy="10.5" r="3.2"/></svg><svg id="cutout-check" viewBox="0 0 20 20" aria-hidden="true"><path d="m4.5 10.5 3.2 3.2 7.8-7.8"/></svg></button>`:`<span id="device-cutout" data-kind="${cutout}" aria-hidden="true"></span>`;root.innerHTML=`<style>
|
|
571
|
+
:host {
|
|
572
|
+
all: initial !important;
|
|
573
|
+
position: fixed !important;
|
|
574
|
+
inset: 0 !important;
|
|
575
|
+
display: block !important;
|
|
576
|
+
z-index: 2147483600 !important;
|
|
577
|
+
overflow: visible !important;
|
|
578
|
+
pointer-events: none !important;
|
|
579
|
+
contain: layout style !important;
|
|
580
|
+
isolation: isolate !important;
|
|
581
|
+
}
|
|
582
|
+
*, *::before, *::after {
|
|
583
|
+
box-sizing: border-box;
|
|
584
|
+
pointer-events: none !important;
|
|
585
|
+
}
|
|
586
|
+
#device-chrome {
|
|
587
|
+
position: absolute;
|
|
588
|
+
inset: 0;
|
|
589
|
+
overflow: visible;
|
|
590
|
+
color: #0f131a;
|
|
591
|
+
font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", "PingFang SC", sans-serif;
|
|
592
|
+
font-synthesis: none;
|
|
593
|
+
-webkit-font-smoothing: antialiased;
|
|
594
|
+
text-rendering: geometricPrecision;
|
|
595
|
+
user-select: none;
|
|
596
|
+
}
|
|
597
|
+
.system-bar {
|
|
598
|
+
position: absolute;
|
|
599
|
+
left: 0;
|
|
600
|
+
right: 0;
|
|
601
|
+
background: #ffffff;
|
|
602
|
+
-webkit-backdrop-filter: none;
|
|
603
|
+
backdrop-filter: none;
|
|
604
|
+
}
|
|
605
|
+
#status-bar {
|
|
606
|
+
top: 0;
|
|
607
|
+
height: calc(${statusBarHeight}px + 1px);
|
|
608
|
+
min-height: 0;
|
|
609
|
+
overflow: visible;
|
|
610
|
+
}
|
|
611
|
+
#status-content {
|
|
612
|
+
position: relative;
|
|
613
|
+
z-index: 1;
|
|
614
|
+
height: ${statusBarHeight}px;
|
|
615
|
+
display: flex;
|
|
616
|
+
align-items: center;
|
|
617
|
+
justify-content: space-between;
|
|
618
|
+
padding: 0 21px 0 27px;
|
|
619
|
+
font-size: 15px;
|
|
620
|
+
font-weight: 600;
|
|
621
|
+
line-height: 1;
|
|
622
|
+
letter-spacing: -.25px;
|
|
623
|
+
font-variant-numeric: tabular-nums;
|
|
624
|
+
}
|
|
625
|
+
#time {
|
|
626
|
+
position: relative;
|
|
627
|
+
z-index: 1;
|
|
628
|
+
min-width: 54px;
|
|
629
|
+
text-align: left;
|
|
630
|
+
}
|
|
631
|
+
#status-indicators {
|
|
632
|
+
position: relative;
|
|
633
|
+
z-index: 1;
|
|
634
|
+
height: 14px;
|
|
635
|
+
display: flex;
|
|
636
|
+
align-items: center;
|
|
637
|
+
gap: 6.5px;
|
|
638
|
+
}
|
|
639
|
+
#status-indicators svg {
|
|
640
|
+
display: block;
|
|
641
|
+
overflow: visible;
|
|
642
|
+
fill: none;
|
|
643
|
+
stroke: currentColor;
|
|
644
|
+
}
|
|
645
|
+
#signal {
|
|
646
|
+
width: 18px;
|
|
647
|
+
height: 12px;
|
|
648
|
+
fill: currentColor !important;
|
|
649
|
+
stroke: none !important;
|
|
650
|
+
}
|
|
651
|
+
#wifi {
|
|
652
|
+
width: 18px;
|
|
653
|
+
height: 14px;
|
|
654
|
+
stroke-width: 2.2;
|
|
655
|
+
stroke-linecap: round;
|
|
656
|
+
stroke-linejoin: round;
|
|
657
|
+
}
|
|
658
|
+
#battery {
|
|
659
|
+
width: 28px;
|
|
660
|
+
height: 13px;
|
|
661
|
+
stroke-width: 1.25;
|
|
662
|
+
}
|
|
663
|
+
#battery-outline { opacity: .42; }
|
|
664
|
+
#battery-level { fill: currentColor; stroke: none; }
|
|
665
|
+
#battery-cap { fill: currentColor; stroke: none; opacity: .45; }
|
|
666
|
+
#device-cutout {
|
|
667
|
+
appearance: none;
|
|
668
|
+
position: absolute;
|
|
669
|
+
left: 50%;
|
|
670
|
+
z-index: 2;
|
|
671
|
+
display: var(--mearl-device-cutout-display, block);
|
|
672
|
+
border: 0;
|
|
673
|
+
padding: 0;
|
|
674
|
+
max-height: 100%;
|
|
675
|
+
transform: translateX(-50%);
|
|
676
|
+
background: #000;
|
|
677
|
+
color: #fff;
|
|
678
|
+
box-shadow: inset 0 0 0 .5px rgba(255, 255, 255, .08);
|
|
679
|
+
}
|
|
680
|
+
#device-cutout[data-kind="dynamic-island"] {
|
|
681
|
+
top: 50%;
|
|
682
|
+
width: 126px;
|
|
683
|
+
height: min(37px, calc(100% - 4px));
|
|
684
|
+
display: var(--mearl-device-cutout-display, flex);
|
|
685
|
+
align-items: center;
|
|
686
|
+
justify-content: center;
|
|
687
|
+
transform: translate(-50%, -50%);
|
|
688
|
+
border-radius: 999px;
|
|
689
|
+
pointer-events: auto !important;
|
|
690
|
+
cursor: pointer;
|
|
691
|
+
-webkit-tap-highlight-color: transparent;
|
|
692
|
+
transition: width 320ms cubic-bezier(.34, 1.56, .64, 1), transform 160ms ease;
|
|
693
|
+
}
|
|
694
|
+
#device-cutout[data-kind="dynamic-island"]:active {
|
|
695
|
+
transform: translate(-50%, -50%) scale(.97);
|
|
696
|
+
}
|
|
697
|
+
#device-cutout[data-kind="dynamic-island"]:focus-visible {
|
|
698
|
+
outline: 2px solid #2563eb;
|
|
699
|
+
outline-offset: 2px;
|
|
700
|
+
}
|
|
701
|
+
#device-cutout[data-kind="dynamic-island"][data-state="copied"],
|
|
702
|
+
#device-cutout[data-kind="dynamic-island"][data-state="downloaded"],
|
|
703
|
+
#device-cutout[data-kind="dynamic-island"][data-state="failed"] {
|
|
704
|
+
width: 154px;
|
|
705
|
+
padding: 0 10px;
|
|
706
|
+
justify-content: space-between;
|
|
707
|
+
}
|
|
708
|
+
#cutout-camera, #cutout-check {
|
|
709
|
+
display: none;
|
|
710
|
+
width: 15px;
|
|
711
|
+
height: 15px;
|
|
712
|
+
fill: none;
|
|
713
|
+
stroke: currentColor;
|
|
714
|
+
stroke-width: 1.8;
|
|
715
|
+
stroke-linecap: round;
|
|
716
|
+
stroke-linejoin: round;
|
|
717
|
+
}
|
|
718
|
+
#device-cutout[data-state="copied"] #cutout-camera,
|
|
719
|
+
#device-cutout[data-state="downloaded"] #cutout-camera,
|
|
720
|
+
#device-cutout[data-state="failed"] #cutout-camera,
|
|
721
|
+
#device-cutout[data-state="copied"] #cutout-check,
|
|
722
|
+
#device-cutout[data-state="downloaded"] #cutout-check,
|
|
723
|
+
#device-cutout[data-state="failed"] #cutout-check {
|
|
724
|
+
display: block;
|
|
725
|
+
}
|
|
726
|
+
#device-cutout[data-kind="notch"] {
|
|
727
|
+
top: 0;
|
|
728
|
+
width: 164px;
|
|
729
|
+
height: min(31px, 100%);
|
|
730
|
+
border-radius: 0 0 18px 18px;
|
|
731
|
+
}
|
|
732
|
+
#bottom-bar {
|
|
733
|
+
bottom: 0;
|
|
734
|
+
height: ${bottomBarHeight}px;
|
|
735
|
+
min-height: 0;
|
|
736
|
+
background: transparent;
|
|
737
|
+
-webkit-backdrop-filter: none;
|
|
738
|
+
backdrop-filter: none;
|
|
739
|
+
}
|
|
740
|
+
#gesture-surface {
|
|
741
|
+
appearance: none;
|
|
742
|
+
position: absolute;
|
|
743
|
+
left: 50%;
|
|
744
|
+
bottom: 0;
|
|
745
|
+
width: 166px;
|
|
746
|
+
max-width: calc(100% - 32px);
|
|
747
|
+
height: 24px;
|
|
748
|
+
transform: translateX(-50%);
|
|
749
|
+
border: 0;
|
|
750
|
+
padding: 0;
|
|
751
|
+
background: transparent;
|
|
752
|
+
color: inherit;
|
|
753
|
+
}
|
|
754
|
+
#gesture-surface[data-interactive="true"] {
|
|
755
|
+
pointer-events: auto !important;
|
|
756
|
+
cursor: pointer;
|
|
757
|
+
-webkit-tap-highlight-color: transparent;
|
|
758
|
+
}
|
|
759
|
+
#gesture-surface[data-interactive="true"]:focus-visible {
|
|
760
|
+
outline: 2px solid #2563eb;
|
|
761
|
+
outline-offset: -2px;
|
|
762
|
+
}
|
|
763
|
+
#gesture-indicator {
|
|
764
|
+
position: absolute;
|
|
765
|
+
left: 50%;
|
|
766
|
+
bottom: 8px;
|
|
767
|
+
width: 134px;
|
|
768
|
+
max-width: 100%;
|
|
769
|
+
height: 5px;
|
|
770
|
+
transform: translateX(-50%);
|
|
771
|
+
border-radius: 999px;
|
|
772
|
+
background: currentColor;
|
|
773
|
+
opacity: .92;
|
|
774
|
+
transition: transform 120ms ease, opacity 120ms ease;
|
|
775
|
+
}
|
|
776
|
+
#gesture-surface[data-interactive="true"]:hover #gesture-indicator {
|
|
777
|
+
opacity: 1;
|
|
778
|
+
transform: translateX(-50%) scaleX(1.05);
|
|
779
|
+
}
|
|
780
|
+
#device-chrome[data-platform="android"] {
|
|
781
|
+
font-family: Roboto, "Noto Sans SC", "Segoe UI", sans-serif;
|
|
782
|
+
}
|
|
783
|
+
#device-chrome[data-platform="android"] #status-content {
|
|
784
|
+
padding: 0 12px;
|
|
785
|
+
font-size: 12px;
|
|
786
|
+
font-weight: 500;
|
|
787
|
+
letter-spacing: 0;
|
|
788
|
+
}
|
|
789
|
+
#device-chrome[data-platform="android"] #status-indicators {
|
|
790
|
+
gap: 5px;
|
|
791
|
+
transform: scale(.86);
|
|
792
|
+
transform-origin: right center;
|
|
793
|
+
}
|
|
794
|
+
#device-chrome[data-platform="android"] #gesture-indicator {
|
|
795
|
+
bottom: 6px;
|
|
796
|
+
width: 108px;
|
|
797
|
+
height: 4px;
|
|
798
|
+
opacity: .82;
|
|
799
|
+
}
|
|
800
|
+
@media(prefers-reduced-motion: reduce) {
|
|
801
|
+
#device-cutout, #gesture-indicator { transition: none; }
|
|
802
|
+
}
|
|
803
|
+
</style>
|
|
804
|
+
<div id="device-chrome" data-platform="${config2.platform}" data-cutout="${cutout}">
|
|
805
|
+
<div id="status-bar" class="system-bar" data-mearl-device-status-bar>
|
|
806
|
+
<div id="status-content">
|
|
807
|
+
<span id="time"></span>
|
|
808
|
+
${cutoutMarkup}
|
|
809
|
+
<span id="status-indicators" aria-hidden="true">
|
|
810
|
+
<svg id="signal" viewBox="0 0 18 12"><rect x="0" y="8" width="3" height="4" rx="1"/><rect x="5" y="6" width="3" height="6" rx="1"/><rect x="10" y="3" width="3" height="9" rx="1"/><rect x="15" y="0" width="3" height="12" rx="1"/></svg>
|
|
811
|
+
<svg id="wifi" viewBox="1 3.8 22 17.2"><path d="M2 8.82a15 15 0 0 1 20 0"/><path d="M5 12.859a10 10 0 0 1 14 0"/><path d="M8.5 16.429a5 5 0 0 1 7 0"/><path d="M12 20h.01"/></svg>
|
|
812
|
+
<svg id="battery" viewBox="0 0 28 13"><rect id="battery-outline" x=".65" y=".65" width="23" height="11.7" rx="3.1"/><rect id="battery-level" x="2.35" y="2.35" width="19.6" height="8.3" rx="1.7"/><path id="battery-cap" d="M25 4.1c1.1.35 1.7 1.15 1.7 2.4s-.6 2.05-1.7 2.4z"/></svg>
|
|
813
|
+
</span>
|
|
814
|
+
</div>
|
|
815
|
+
</div>
|
|
816
|
+
<div id="bottom-bar" class="system-bar" data-mearl-device-bottom-bar>
|
|
817
|
+
<button id="gesture-surface" type="button" data-interactive="false" disabled aria-hidden="true"><span id="gesture-indicator" aria-hidden="true"></span></button>
|
|
818
|
+
</div>
|
|
819
|
+
</div>`;let deviceChrome=root.querySelector("#device-chrome"),statusBar=root.querySelector("#status-bar"),time3=root.querySelector("#time"),cutoutButton=root.querySelector("#device-cutout"),cutoutStatusPath=root.querySelector("#cutout-check path"),gestureSurface=root.querySelector("#gesture-surface"),screenshotPending=!1,resetTimer=null,destroyed=!1,updateTime=()=>{if(!time3)return;let now=new Date;time3.textContent=`${String(now.getHours()).padStart(2,"0")}:${String(now.getMinutes()).padStart(2,"0")}`};updateTime();let timeTimer=browser.setInterval(updateTime,3e4),setCutoutState=nextState=>{if(!cutoutButton||cutoutButton.tagName!=="BUTTON")return;cutoutButton.dataset.state=nextState;let label=nextState==="copied"?labels.copied:nextState==="downloaded"?labels.downloaded:nextState==="failed"?labels.captureFailed:labels.screenshot;cutoutButton.setAttribute("aria-label",label),cutoutButton.title=label,cutoutStatusPath?.setAttribute("d",nextState==="failed"?"M5.5 5.5l9 9m0-9-9 9":"m4.5 10.5 3.2 3.2 7.8-7.8")},screenshotBlob=data=>{let binary=browser.atob(data),bytes=new Uint8Array(binary.length);for(let index=0;index<binary.length;index+=1)bytes[index]=binary.charCodeAt(index);return new browser.Blob([bytes],{type:"image/png"})},downloadScreenshot=blob=>{let link=ownerDocument.createElement("a"),objectUrl=browser.URL.createObjectURL(blob);link.href=objectUrl,link.download=`mearl-screenshot-${new Date().toISOString().replace(/[:.]/g,"-")}.png`,link.style.display="none",ownerDocument.body.appendChild(link),link.click(),link.remove(),browser.setTimeout(()=>browser.URL.revokeObjectURL(objectUrl),1e3)},applyState=()=>{if(statusBar&&(statusBar.style.display=state.statusBarVisible?"":"none",statusBar.style.background=state.statusBarBackground),deviceChrome&&(deviceChrome.style.color=state.textColor),gestureSurface){let interactive=!!(state.bottomActionEnabled&&options.onBottomAction);gestureSurface.dataset.interactive=String(interactive),gestureSurface.disabled=!interactive,gestureSurface.setAttribute("aria-hidden",String(!interactive)),interactive?(gestureSurface.setAttribute("aria-label",labels.bottomAction),gestureSurface.title=labels.bottomAction):(gestureSurface.removeAttribute("aria-label"),gestureSurface.removeAttribute("title"))}};return cutoutButton?.tagName==="BUTTON"&&(setCutoutState("idle"),cutoutButton.disabled=!options.captureScreenshot,cutoutButton.addEventListener("click",()=>{destroyed||!options.captureScreenshot||screenshotPending||cutoutButton.dataset.state!=="idle"||(screenshotPending=!0,cutoutButton.setAttribute("aria-busy","true"),options.captureScreenshot().then(({data})=>screenshotBlob(data)).then(async blob=>{let ClipboardItemConstructor=browser.ClipboardItem;if(browser.navigator.clipboard?.write&&ClipboardItemConstructor)try{await browser.navigator.clipboard.write([new ClipboardItemConstructor({"image/png":blob})]),setCutoutState("copied");return}catch{}downloadScreenshot(blob),setCutoutState("downloaded")}).catch(()=>setCutoutState("failed")).finally(()=>{screenshotPending=!1,!destroyed&&(cutoutButton.setAttribute("aria-busy","false"),resetTimer=browser.setTimeout(()=>{resetTimer=null,screenshotPending||setCutoutState("idle")},1600))}))})),gestureSurface?.addEventListener("click",()=>{!destroyed&&state.bottomActionEnabled&&options.onBottomAction?.()}),applyState(),{updateState(nextState){destroyed||(Object.assign(state,nextState),applyState())},destroy(){destroyed||(destroyed=!0,browser.clearInterval(timeTimer),resetTimer!==null&&browser.clearTimeout(resetTimer),root.replaceChildren())}}}var deviceShellStates=new WeakMap,DEVICE_SHELL_BINDING="__mearlCdpDeviceShellRelay",DEVICE_SHELL_RESPONSE="__mearlCdpDeviceShellResponse",FRAME_INTERACTIVITY_SETTLE_TIMEOUT_MS=420,FRAME_INTERACTIVITY_POLL_MS=20;function findActiveWebView(frameTree){if(!frameTree)return;let root=frameTree.frame?.name==="__mearl_root__"?frameTree.frame:void 0,layer=frameTree.frame?.name==="__mearl_layer__"?frameTree.frame:void 0;for(let child of frameTree.childFrames??[]){let match=findActiveWebView(child);match&&(match.name==="__mearl_layer__"?layer=match:root??=match)}return layer??root}function collectDeviceShellFrames(frameTree,frames=[]){if(!frameTree)return frames;(frameTree.frame?.name==="__mearl_root__"||frameTree.frame?.name==="__mearl_layer__")&&frames.push(frameTree.frame);for(let child of frameTree.childFrames??[])collectDeviceShellFrames(child,frames);return frames}async function readFrameOwnerInteractivity(client2,frameId){try{let owner=await client2.sendCommand("DOM.getFrameOwner",{frameId});if(owner.backendNodeId===void 0)return;let attributes=(await client2.sendCommand("DOM.describeNode",{backendNodeId:owner.backendNodeId,depth:0})).node?.attributes;if(!attributes)return;let names=new Set(attributes.filter((_,index)=>index%2===0)),ariaHiddenIndex=attributes.indexOf("aria-hidden");return!names.has("inert")&&(ariaHiddenIndex<0||attributes[ariaHiddenIndex+1]!=="true")}catch{return}}async function resolveInteractiveWebViewFrame(client2){let deadline=Date.now()+FRAME_INTERACTIVITY_SETTLE_TIMEOUT_MS,fallback;do{let frameTree=(await client2.sendCommand("Page.getFrameTree").catch(()=>null))?.frameTree;fallback=findActiveWebView(frameTree)??fallback;let candidates=collectDeviceShellFrames(frameTree),inspected=!1;for(let index=candidates.length-1;index>=0;index-=1){let candidate=candidates[index];if(candidate.id===frameTree?.frame?.id)continue;let interactive=await readFrameOwnerInteractivity(client2,candidate.id);if(interactive!==void 0&&(inspected=!0,interactive))return candidate}if(!inspected||Date.now()>=deadline)return fallback;await new Promise(resolve3=>setTimeout(resolve3,FRAME_INTERACTIVITY_POLL_MS))}while(Date.now()<deadline);return fallback}function trackExecutionContexts(state,client2){let contexts=new Map;return state.executionContexts.set(client2,contexts),[client2.on("Runtime.executionContextsCleared",()=>contexts.clear()),client2.on("Runtime.executionContextCreated",params=>{let context=params?.context,frameId=context?.auxData?.frameId;typeof frameId=="string"&&context?.auxData?.isDefault===!0&&typeof context.id=="number"&&contexts.set(frameId,context.id)}),client2.on("Runtime.executionContextDestroyed",params=>{let executionContextId=params?.executionContextId;for(let[frameId,contextId]of contexts)contextId===executionContextId&&contexts.delete(frameId)})]}async function installChildTarget(session,state,params){let sessionId=params.sessionId;if(typeof sessionId!="string")return;let child=session.client.createChildSession(sessionId),disposeListeners=trackExecutionContexts(state,child);try{if(params.targetInfo?.type!=="iframe"||deviceShellStates.get(session)!==state)return;await child.sendCommand("Runtime.enable");let frameName=await child.sendCommand("Runtime.evaluate",{expression:"window.name",returnByValue:!0}).then(result=>result.result?.value);if(frameName!=="__mearl_root__"&&frameName!=="__mearl_layer__")return;let frameTree=await child.sendCommand("Page.getFrameTree").catch(()=>null);if(state.attachedWebViews.set(sessionId,{client:child,name:frameName,frameId:frameTree?.frameTree?.frame?.id??params.targetInfo?.targetId,order:state.nextAttachedOrder++,disposeListeners}),!state.childEnvironmentManagedByApp)for(let{method,params:commandParams,optional:optional2}of buildEnableEmulationCommands(state.emulation))await child.sendCommand(method,commandParams).catch(error48=>{if(!optional2)throw error48})}finally{if(!state.attachedWebViews.has(sessionId)){for(let dispose of disposeListeners)dispose();state.executionContexts.delete(child)}await child.sendCommand("Runtime.runIfWaitingForDebugger").catch(()=>{})}}async function enableDeviceShellFrameRouting(session,state){state.disposeListeners.push(...trackExecutionContexts(state,session.client)),state.disposeListeners.push(session.client.on("Target.attachedToTarget",params=>{installChildTarget(session,state,params).catch(()=>{})})),state.disposeListeners.push(session.client.on("Target.detachedFromTarget",params=>{if(deviceShellStates.get(session)!==state)return;let attached=state.attachedWebViews.get(params?.sessionId);if(attached){for(let dispose of attached.disposeListeners)dispose();state.executionContexts.delete(attached.client),state.attachedWebViews.delete(params.sessionId)}})),await session.client.sendCommand("Runtime.enable"),await session.client.sendCommand("Target.setAutoAttach",{autoAttach:!0,waitForDebuggerOnStart:!0,flatten:!0,filter:[{type:"iframe"},{exclude:!0}]})}function serializeForSource(value){return JSON.stringify(value).replace(/[\u2028\u2029]/g,character=>character==="\u2028"?"\\u2028":"\\u2029")}function installDeviceShell(config2,installChromeView,bindingName,responseName){let browser=globalThis,target=globalThis,document2=browser.document;if(browser.top!==globalThis||!/^https?:$/i.test(browser.location.protocol))return;let businessUrl=browser.location.href;try{let shellRoot=document2.createElement("html"),shellHead=document2.createElement("head"),charset=document2.createElement("meta"),viewport=document2.createElement("meta"),title=document2.createElement("title"),style=document2.createElement("style"),shellBody=document2.createElement("body"),frame=document2.createElement("iframe"),chromeHost=document2.createElement("div");shellRoot.setAttribute("data-mearl-device-shell",""),shellBody.setAttribute("data-mearl-device-shell",""),charset.setAttribute("charset","utf-8"),viewport.name="viewport",viewport.content="width=device-width,initial-scale=1,viewport-fit=cover",style.textContent=`
|
|
820
|
+
:root, body { width: 100%; height: 100%; margin: 0; overflow: hidden; background: #fff; }
|
|
821
|
+
[data-mearl-root-webview] {
|
|
822
|
+
position: fixed; left: 0; right: 0; top: ${config2.statusBarHeight}px;
|
|
823
|
+
width: 100%; height: calc(100% - ${config2.statusBarHeight}px);
|
|
824
|
+
border: 0; display: block; background: #fff; z-index: 0;
|
|
825
|
+
}
|
|
826
|
+
`,shellHead.append(charset,viewport,title,style),shellRoot.append(shellHead,shellBody),frame.name="__mearl_root__",frame.setAttribute("data-mearl-root-webview","device-shell"),frame.addEventListener("load",()=>{frame.getAttribute("src")&&frame.getAttribute("src")!=="about:blank"&&frame.setAttribute("data-mearl-webview-ready","")}),chromeHost.setAttribute("data-mearl-device-chrome-host","");let pendingScreenshots=new Map,nextScreenshotId=1;target[responseName]=(requestId,result)=>{let pending=pendingScreenshots.get(requestId);pending&&(pendingScreenshots.delete(requestId),browser.clearTimeout(pending.timer),typeof result?.data=="string"?pending.resolve({data:result.data}):pending.reject(new Error(String(result?.error??"Screenshot failed"))))};let binding=target[bindingName],captureScreenshot=typeof binding=="function"?()=>new Promise((resolve3,reject)=>{let requestId=nextScreenshotId++,timer=browser.setTimeout(()=>{pendingScreenshots.delete(requestId),reject(new Error("Screenshot timed out"))},15e3);pendingScreenshots.set(requestId,{resolve:resolve3,reject,timer});try{binding(JSON.stringify({type:"screenshot",requestId}))}catch(error48){pendingScreenshots.delete(requestId),browser.clearTimeout(timer),reject(error48 instanceof Error?error48:new Error(String(error48)))}}):void 0;installChromeView(chromeHost.attachShadow({mode:"open"}),config2,{captureScreenshot}),shellBody.append(frame,chromeHost);let currentRoot=document2.documentElement;currentRoot?document2.replaceChild(shellRoot,currentRoot):document2.appendChild(shellRoot),typeof browser.stop=="function"&&browser.stop(),frame.src=businessUrl}catch(error48){console.warn("[Mearl Device Shell] failed to create root WebView",error48)}}function resolveDeviceShellConfig(emulation){let platform=/iPhone|iPad|iPod|Mac/i.test(emulation.platform)?"ios":"android";return{platform,statusBarHeight:emulation.orientation==="landscape"?24:Math.max(0,Math.round(emulation.safeAreaInsets.top)),bottomBarHeight:Math.max(0,Math.round(emulation.safeAreaInsets.bottom)),cutout:platform==="ios"?emulation.appearance.cutout:"none"}}function buildDeviceShellSource(config2){return`;(${installDeviceShell.toString()})(${serializeForSource(config2)},(${installDeviceChromeView.toString()}),${JSON.stringify(DEVICE_SHELL_BINDING)},${JSON.stringify(DEVICE_SHELL_RESPONSE)});`}async function evaluateDeviceShellContext(session,contextId,expression,options={}){return session.client.sendCommand("Runtime.evaluate",{expression,...contextId===void 0?{}:{contextId},...options})}function listenForDeviceShellRequests(session,state){return session.client.on("Runtime.bindingCalled",params=>{if(params?.name!==DEVICE_SHELL_BINDING||deviceShellStates.get(session)!==state)return;let request;try{request=JSON.parse(params.payload)}catch{return}if(request.type!=="screenshot"||typeof request.requestId!="number")return;let requestId=request.requestId,contextId=typeof params.executionContextId=="number"?params.executionContextId:void 0,reply=result=>evaluateDeviceShellContext(session,contextId,`globalThis[${JSON.stringify(DEVICE_SHELL_RESPONSE)}]?.(${requestId},${serializeForSource(result)})`);(async()=>{let hiddenState;try{hiddenState=(await evaluateDeviceShellContext(session,contextId,`(() => {
|
|
827
|
+
const root = document.documentElement;
|
|
828
|
+
if (!root) return {};
|
|
829
|
+
const property = '--mearl-device-cutout-display';
|
|
830
|
+
const value = root.style.getPropertyValue(property);
|
|
831
|
+
const priority = root.style.getPropertyPriority(property);
|
|
832
|
+
root.style.setProperty(property, 'none', 'important');
|
|
833
|
+
return { value, priority };
|
|
834
|
+
})()`,{returnByValue:!0})).result?.value,await evaluateDeviceShellContext(session,contextId,"new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)))",{awaitPromise:!0});let result=await session.client.sendCommand("Page.captureScreenshot",{format:"png"});await reply({data:result.data})}catch(error48){await reply({error:error48 instanceof Error?error48.message:String(error48)}).catch(()=>{})}finally{hiddenState&&await evaluateDeviceShellContext(session,contextId,`(() => {
|
|
835
|
+
const root = document.documentElement;
|
|
836
|
+
if (!root) return;
|
|
837
|
+
const property = '--mearl-device-cutout-display';
|
|
838
|
+
const state = ${serializeForSource(hiddenState)};
|
|
839
|
+
if (root.style.getPropertyValue(property) !== 'none') return;
|
|
840
|
+
if (state.value) root.style.setProperty(property, state.value, state.priority);
|
|
841
|
+
else root.style.removeProperty(property);
|
|
842
|
+
})()`).catch(()=>{})}})()})}function isCdpDeviceShellActive(session){return deviceShellStates.has(session)}function setCdpDeviceShellChildEnvironmentManagedByApp(session,managed){let state=deviceShellStates.get(session);state&&(state.childEnvironmentManagedByApp=managed)}async function resolveCdpDeviceShellPageEndpoint(session){let state=deviceShellStates.get(session);if(!state)return{client:session.client};let attached=Array.from(state.attachedWebViews.values()).filter(webView=>!webView.client.closed).sort((left,right)=>right.order-left.order),activeInParent=await resolveInteractiveWebViewFrame(session.client),attachedActive=activeInParent?attached.find(webView=>webView.frameId===activeInParent.id):void 0;if(attachedActive)return{client:attachedActive.client,url:activeInParent?.url};let attachedRoot=attached.find(webView=>webView.name==="__mearl_root__");if(attachedRoot){let active=await resolveInteractiveWebViewFrame(attachedRoot.client);return active&&active.id!==attachedRoot.frameId?{client:attachedRoot.client,frameId:active.id,url:active.url}:{client:attachedRoot.client,url:active?.url}}if(!activeInParent)throw new Error("Device shell business WebView is not ready");return{client:session.client,frameId:activeInParent.id,url:activeInParent.url}}async function sendCdpDeviceShellPageCommand(session,method,params={},timeoutMs){let send=(client2,command,commandParams)=>timeoutMs===void 0?client2.sendCommand(command,commandParams):client2.sendCommand(command,commandParams,timeoutMs),state=deviceShellStates.get(session);if(!state)return send(session.client,method,params);let endpoint=await resolveCdpDeviceShellPageEndpoint(session);if(endpoint.frameId===void 0)return send(endpoint.client,method,params);let contextId=state.executionContexts.get(endpoint.client)?.get(endpoint.frameId);if((method==="Runtime.evaluate"||method==="DOM.resolveNode")&&contextId===void 0){let deadline=Date.now()+1e3;for(;Date.now()<deadline&&contextId===void 0;){let currentEndpoint=await resolveCdpDeviceShellPageEndpoint(session);if(currentEndpoint.client!==endpoint.client||currentEndpoint.frameId!==endpoint.frameId)return sendCdpDeviceShellPageCommand(session,method,params,timeoutMs);await new Promise(resolve3=>setTimeout(resolve3,10)),contextId=state.executionContexts.get(endpoint.client)?.get(endpoint.frameId)}if(contextId===void 0)throw new Error("Device shell business WebView execution context is unavailable")}let nextParams={...params};if(method==="Runtime.evaluate"&&contextId!==void 0&&(nextParams.contextId=contextId),method==="DOM.resolveNode"&&contextId!==void 0&&(nextParams.executionContextId=contextId),method==="Accessibility.getFullAXTree"&&(nextParams.frameId=endpoint.frameId),method==="Page.navigate"&&(nextParams.frameId=endpoint.frameId),method==="Page.reload"){if(!endpoint.url)throw new Error("Device shell business WebView URL is unavailable");return send(endpoint.client,"Page.navigate",{url:endpoint.url,frameId:endpoint.frameId})}return send(endpoint.client,method,nextParams)}function getCdpDeviceShellInputOffset(session){let state=deviceShellStates.get(session);return state?{x:0,y:state.statusBarHeight}:{x:0,y:0}}async function applyCdpDeviceShell(session,emulation){let config2=resolveDeviceShellConfig(emulation),configKey=JSON.stringify(config2),previous=deviceShellStates.get(session);if(previous?.configKey===configKey)return previous.emulation=emulation,previous.childEnvironmentManagedByApp||await Promise.all(Array.from(previous.attachedWebViews.values()).map(async webView=>{for(let{method,params,optional:optional2}of buildEnableEmulationCommands(emulation))await webView.client.sendCommand(method,params).catch(error48=>{if(!optional2)throw error48})})),!1;if(previous){for(let dispose of previous.disposeListeners.splice(0))dispose();for(let attached of previous.attachedWebViews.values())for(let dispose of attached.disposeListeners)dispose();previous.attachedWebViews.clear(),previous.executionContexts.clear(),await session.client.sendCommand("Page.removeScriptToEvaluateOnNewDocument",{identifier:previous.documentScriptIdentifier}).catch(()=>{}),await session.client.sendCommand("Runtime.removeBinding",{name:DEVICE_SHELL_BINDING}).catch(()=>{})}await session.client.sendCommand("Runtime.addBinding",{name:DEVICE_SHELL_BINDING});let result=await session.client.sendCommand("Page.addScriptToEvaluateOnNewDocument",{source:buildDeviceShellSource(config2)});if(typeof result.identifier!="string"||!result.identifier)throw deviceShellStates.delete(session),await session.client.sendCommand("Runtime.removeBinding",{name:DEVICE_SHELL_BINDING}).catch(()=>{}),new Error("Chrome did not return a device shell bootstrap script identifier");let state={configKey,documentScriptIdentifier:result.identifier,emulation,statusBarHeight:config2.statusBarHeight,executionContexts:new Map,attachedWebViews:new Map,nextAttachedOrder:0,childEnvironmentManagedByApp:!1,disposeListeners:[]};return deviceShellStates.set(session,state),state.disposeListeners.push(listenForDeviceShellRequests(session,state)),await enableDeviceShellFrameRouting(session,state),!0}async function clearCdpDeviceShell(session){let state=deviceShellStates.get(session);if(!state)return!1;deviceShellStates.delete(session);for(let dispose of state.disposeListeners.splice(0))dispose();for(let attached of state.attachedWebViews.values())for(let dispose of attached.disposeListeners)dispose();return state.attachedWebViews.clear(),state.executionContexts.clear(),await session.client.sendCommand("Page.removeScriptToEvaluateOnNewDocument",{identifier:state.documentScriptIdentifier}).catch(()=>{}),await session.client.sendCommand("Runtime.removeBinding",{name:DEVICE_SHELL_BINDING}).catch(()=>{}),state.childEnvironmentManagedByApp||await session.client.sendCommand("Target.setAutoAttach",{autoAttach:!1,waitForDebuggerOnStart:!1,flatten:!0}).catch(()=>{}),!0}function hasLoadedRootWebView(frameTree){if(!frameTree)return!1;let frame=frameTree.frame;return frame?.name==="__mearl_root__"&&typeof frame.url=="string"&&/^https?:/i.test(frame.url)?!0:Array.isArray(frameTree.childFrames)?frameTree.childFrames.some(child=>hasLoadedRootWebView(child)):!1}async function waitForCdpDeviceShellLoad(session,timeoutMs=15e3){let deadline=Date.now()+timeoutMs;for(;Date.now()<deadline;){let result=await session.client.sendCommand("Page.getFrameTree").catch(()=>null);if(hasLoadedRootWebView(result?.frameTree))return;await new Promise(resolve3=>setTimeout(resolve3,50))}throw new Error(`Device shell root WebView load timeout after ${timeoutMs}ms`)}var RECORDING_INJECTED_SCRIPT=`
|
|
571
843
|
(function() {
|
|
572
844
|
if (window.__mtopRecording) return;
|
|
573
845
|
window.__mtopRecording = true;
|
|
@@ -742,43 +1014,43 @@ ${SOURCE_BADGES[source]}
|
|
|
742
1014
|
window.__mtopRecording = false;
|
|
743
1015
|
return { endUrl: endUrl };
|
|
744
1016
|
})()
|
|
745
|
-
`,RECORDING_BINDING_NAME="__mtopRecordReport",cdpRecordingSessions=new Map,RECORDING_MAX_REQUESTS=500,RECORDING_MAX_ACTIONS=1e3;async function cdpRecordStart(session,_data){if(cdpRecordingSessions.has(session.targetId))throw new Error(`Already recording on target ${session.targetId}. Call record_stop before starting a new recording.`);let recordingSession={targetId:session.targetId,startTime:Date.now(),startUrl:"",actions:[]};try{await session.client.sendCommand("Runtime.addBinding",{name:RECORDING_BINDING_NAME})}catch(err){throw new Error(`Failed to register recording binding: ${err?.message??err}. CDP target may not support Runtime domain.`,{cause:err})}let nextSeq=1,onBindingCalled=params=>{if(params?.name===RECORDING_BINDING_NAME)try{let action=JSON.parse(params.payload);action.seq=nextSeq++,recordingSession.actions.push(action),recordingSession.actions.length>RECORDING_MAX_ACTIONS&&recordingSession.actions.splice(0,recordingSession.actions.length-RECORDING_MAX_ACTIONS)}catch{}};recordingSession.removeBindingListener=session.client.on("Runtime.bindingCalled",onBindingCalled);try{let result=await session.client.sendCommand("Page.addScriptToEvaluateOnNewDocument",{source:RECORDING_INJECTED_SCRIPT});recordingSession.scriptIdentifier=result?.identifier}catch(err){throw recordingSession.removeBindingListener?.(),new Error(`Failed to register recording script: ${err?.message??err}.`,{cause:err})}try{let value=(await session.client.sendCommand("Runtime.evaluate",{expression:RECORDING_BOOTSTRAP_SCRIPT,returnByValue:!0})).result?.value??{};recordingSession.startUrl=value.startUrl??""}catch{recordingSession.startUrl=""}return cdpRecordingSessions.set(session.targetId,recordingSession),{recording:!0,tabId:session.targetId,startTime:recordingSession.startTime}}async function cdpRecordStop(session,_data){let recordingSession=cdpRecordingSessions.get(session.targetId);if(!recordingSession)return{wasRecording:!1,actions:[],requests:[],requestsTruncated:!1,duration:0,startUrl:"",endUrl:""};if(cdpRecordingSessions.delete(session.targetId),recordingSession.removeBindingListener?.(),recordingSession.scriptIdentifier)try{await session.client.sendCommand("Page.removeScriptToEvaluateOnNewDocument",{identifier:recordingSession.scriptIdentifier})}catch{}let endUrl="";try{endUrl=(await session.client.sendCommand("Runtime.evaluate",{expression:RECORDING_TEARDOWN_SCRIPT,returnByValue:!0})).result?.value?.endUrl??""}catch{}try{await session.client.sendCommand("Runtime.removeBinding",{name:RECORDING_BINDING_NAME})}catch{}let endTime=Date.now(),startTime=recordingSession.startTime,duration3=Math.round((endTime-startTime)/1e3),allRequests=session.buffers.requests.filter(r=>r.timestampMs>=startTime),requests=allRequests.length>RECORDING_MAX_REQUESTS?allRequests.slice(-RECORDING_MAX_REQUESTS):allRequests;return{wasRecording:!0,actions:annotateActionsWithRequests(recordingSession.actions,requests,endTime),requests:serializeRecordingRequests(requests),requestsTruncated:allRequests.length>RECORDING_MAX_REQUESTS,duration:duration3,startUrl:recordingSession.startUrl,endUrl}}async function releaseCdpRecordings(sessions){await Promise.allSettled(sessions.filter(session=>cdpRecordingSessions.has(session.targetId)).map(session=>cdpRecordStop(session,{})));for(let recordingSession of cdpRecordingSessions.values())recordingSession.removeBindingListener?.();cdpRecordingSessions.clear()}registerActions([{name:"record_start",session:"page",handler:cdpRecordStart},{name:"record_stop",session:"page",handler:cdpRecordStop}]);var WINDVANE="WindVane/8.7.0",WV_BRIDGE={global:"WindVane",style:"windvane"},MEGA_BRIDGE={global:"__megability_bridge__",style:"mega"},WV_NATIVE_BACK={event:"wvBackClickEvent",controlFunction:"_windvane_backControl"},FLIGGY_NATIVE_BACK={event:"WV.Back"},ALIPAY_NATIVE_BACK={event:"back"},FLIGGY_OVERLAY={enabledParam:"_fli_overlay",topRatioParam:"_fli_overlay_ratio",radiusParam:"_fli_overlay_radius",maskAlphaParam:"_fli_overlay_mask_alpha",tapCloseParam:"_fli_overlay_tap_close",tapCloseSelectors:["#qwen-titlebar .qwen-titlebar-icon-wrapper:last-child"],defaultTopRatio:.2,defaultRadius:0,defaultMaskAlpha:.3,defaultTapClose:!0},TAOBAO_OVERLAY={enabledParam:"useWebdialog",topRatioParam:"topRatio",heightRatioParam:"height_pct",radiusParam:"cornerRadius",maskAlphaParam:"maskAlpha",tapCloseParam:"tapEnable",tapCloseSelectors:["#qwen-titlebar .qwen-titlebar-icon-wrapper:last-child"],defaultTopRatio:.2,defaultRadius:6,defaultMaskAlpha:.5,defaultTapClose:!0},FLIGGY_IMAGE_PICKER={schemes:["page://ask_take_photo"],api:"mtop.trip.serverless.api.gateway",version:"2.0",fcId:"240417431173407785",fcGroup:"fl-images",uploadUrlFunction:"uploadByTokenUrl",prefix:"temp",region:"CN"},FLIGGY_LAYER_URL_PROXY={sourceHostPrefix:"edith.",pathPrefix:"/proxy/",targetHostSuffixes:["wapa.taobao.com"],defaultTargetHost:"market.wapa.taobao.com"},FLIGGY_ROOT_CONTAINER={statusBarHeightCookie:{name:"_fli_barHeight",domain:"taobao.com",path:"/"}},FLIGGY_TITLE_BAR_HIDDEN_PATHNAMES=["/app/trip/rx-home/pages/home","/app/trip/rx-trip-ai/pages/home"],FLIGGY_STATUS_BAR_BACKGROUND_COLORS={"/app/trip/rx-home/pages/home":"#fff","/app/trip/rx-trip-ai/pages/home":"#dbdbff"};function emptyActions(){return{open:[],close:[],title:[],navigationBar:[],statusBar:[],systemInfo:[],mtop:[],kvGet:[],kvSet:[],kvDelete:[],pageContext:[],responses:{},behaviors:{},noop:[],silent:[]}}function mergeActions(...maps){let out=emptyActions();for(let m of maps)out.open.push(...m.open),out.close.push(...m.close),out.title.push(...m.title),out.navigationBar.push(...m.navigationBar??[]),out.statusBar.push(...m.statusBar??[]),out.systemInfo.push(...m.systemInfo),out.mtop.push(...m.mtop),out.kvGet.push(...m.kvGet??[]),out.kvSet.push(...m.kvSet??[]),out.kvDelete.push(...m.kvDelete??[]),out.pageContext.push(...m.pageContext??[]),Object.assign(out.responses,m.responses??{}),Object.assign(out.behaviors,m.behaviors??{}),out.noop.push(...m.noop),out.silent.push(...m.silent??[]);return out}var APP_BRIDGE_BEHAVIORS=["navigate","closeAll","closeBackData","postMessage","notifySubscribe","notifyUnsubscribe","notifyPost","sharedFileRead","sharedFileWrite","sharedDataGet","sharedDataSet","legacyBroadcastCreate","legacyBroadcastPost","legacyBroadcastClose","memoryGet","memorySet","memoryDelete","availabilityMap","userInfo","networkInfo","geolocation","permission","prefetch","fptTrack","mtopStream","previewFile","toast","unsupportedNativeInput","payment","userTrack","calendar","networkQualityMonitor","beaconRequest"],APP_BRIDGE_BEHAVIOR_SET=new Set(APP_BRIDGE_BEHAVIORS),BRIDGE_ACTION_ARRAY_KEYS=["open","close","title","navigationBar","statusBar","systemInfo","mtop","kvGet","kvSet","kvDelete","pageContext","noop"];function isJsonValue(value,seen=new Set){if(value===null||typeof value=="string"||typeof value=="boolean")return!0;if(typeof value=="number")return Number.isFinite(value);if(typeof value!="object"||seen.has(value))return!1;seen.add(value);let valid=Array.isArray(value)?value.every(item=>isJsonValue(item,seen)):Object.values(value).every(item=>isJsonValue(item,seen));return seen.delete(value),valid}function validateAppBridgeConfig(value){if(!value||typeof value!="object"||Array.isArray(value))throw new Error("bridgeConfig must be an object");let root=value;if(Object.keys(root).some(key=>key!=="methods"))throw new Error('bridgeConfig only supports the "methods" field');if(!root.methods||typeof root.methods!="object"||Array.isArray(root.methods))throw new Error("bridgeConfig.methods must be an object");let entries=Object.entries(root.methods);if(entries.length>200)throw new Error("bridgeConfig supports at most 200 methods");let methods2={};for(let[method,rawConfig]of entries){if(!method.trim()||method.length>200)throw new Error("bridgeConfig method names must contain 1-200 characters");if(method==="__proto__"||method==="prototype"||method==="constructor")throw new Error(`bridgeConfig method name "${method}" is reserved`);if(!rawConfig||typeof rawConfig!="object"||Array.isArray(rawConfig))throw new Error(`bridgeConfig.methods.${method} must be an object`);let methodConfig=rawConfig,supportedKeys=new Set(["behavior","response","noop","silent"]);if(Object.keys(methodConfig).some(key=>!supportedKeys.has(key)))throw new Error(`bridgeConfig.methods.${method} contains an unsupported field`);if("behavior"in methodConfig&&typeof methodConfig.behavior!="string")throw new Error(`bridgeConfig.methods.${method}.behavior must be a string`);let hasBehavior=typeof methodConfig.behavior=="string",hasResponse=Object.prototype.hasOwnProperty.call(methodConfig,"response"),hasNoop=methodConfig.noop===!0;if(Number(hasBehavior)+Number(hasResponse)+Number(hasNoop)!==1)throw new Error(`bridgeConfig.methods.${method} must define exactly one of behavior, response, or noop=true`);if(hasBehavior&&!APP_BRIDGE_BEHAVIOR_SET.has(methodConfig.behavior))throw new Error(`bridgeConfig.methods.${method} has an unsupported behavior`);if(hasResponse&&!isJsonValue(methodConfig.response))throw new Error(`bridgeConfig.methods.${method}.response must be valid JSON data`);if("noop"in methodConfig&&methodConfig.noop!==!0)throw new Error(`bridgeConfig.methods.${method}.noop must be true when provided`);if("silent"in methodConfig&&typeof methodConfig.silent!="boolean")throw new Error(`bridgeConfig.methods.${method}.silent must be a boolean`);methods2[method]={...hasBehavior&&{behavior:methodConfig.behavior},...hasResponse&&{response:JSON.parse(JSON.stringify(methodConfig.response))},...hasNoop&&{noop:!0},...methodConfig.silent===!0&&{silent:!0}}}let normalized={methods:methods2};if(JSON.stringify(normalized).length>65536)throw new Error("bridgeConfig must not exceed 64 KiB");return normalized}function applyAppBridgeConfig(actions,config2){let out=mergeActions(actions);if(!config2)return out;let{methods:methods2}=validateAppBridgeConfig(config2);for(let[method,methodConfig]of Object.entries(methods2)){for(let key of BRIDGE_ACTION_ARRAY_KEYS){let values=out[key];values&&(out[key]=values.filter(value=>value!==method))}out.silent=(out.silent??[]).filter(value=>value!==method),delete out.responses?.[method],delete out.behaviors?.[method],methodConfig.behavior?out.behaviors[method]=methodConfig.behavior:Object.prototype.hasOwnProperty.call(methodConfig,"response")?out.responses[method]=methodConfig.response:methodConfig.noop&&out.noop.push(method),methodConfig.silent&&out.silent.push(method)}return out}var WV_ACTIONS={open:["WVNative.openWindow","Base.openBrowser","EtaoJsbridgeUtil.openWindow","TMBridge.pushWindow","Third.openThirdWeb"],close:["WebAppInterface.pop","Triver.pop","TMBridge.popWindow","EleWVHybridAPI.popWindow","Third.closeWebView"],title:["WebAppInterface.setCustomPageTitle"],navigationBar:["Triver.setNavigationBarStyle"],statusBar:["WebAppInterface.setStatusBarStyle","Application.setStatusBarStyle"],systemInfo:[],mtop:["MtopWVPlugin.send"],behaviors:{"WVNetwork.getNetworkType":"networkInfo","WVFile.read":"sharedFileRead","WVFile.write":"sharedFileWrite","SharedData.getSharedData":"sharedDataGet","SharedData.setSharedData":"sharedDataSet","WVBroadcast.createChannel":"legacyBroadcastCreate","WVBroadcast.postMessage":"legacyBroadcastPost","WVBroadcast.close":"legacyBroadcastClose"},noop:["WVNative.enableHookNativeBack","WVNative.forbidPanGesture","WVNative.setGestureBack","WVTBUserTrack.toUT","WVTBUserTrack.toUT2"],silent:["WVNetwork.getNetworkType","WVTBUserTrack.toUT","WVTBUserTrack.toUT2"]},COMMON_SCHEME_RULES=[{match:"page:",param:"params"},{match:"taobaotravel:",param:"params"},{match:"alipays://platformapi/starth5app",param:"url"},{match:"alipays://platformapi/startapp",param:"page"},{match:"eleme://web",param:"url"},{match:"amapuri://webview/",param:"url"}],FLIGGY_SCHEME_RULES=[{match:"fliggy://order/detail",targetPath:"/app/trip/rx-flight-detail/pages/index",targetHostPrefix:"market",targetParams:{titleBarHidden:"2"}},...COMMON_SCHEME_RULES],WV_ACTIVE_EVENTS=["WV.Event.APP.Active"],FLIGGY_AI_UI_NOOPS=["handleLiveActivity","ai_ask_scroll_position","ai_ask_input_status","ai_ask_set_keyboard_tags","ai_ask_h5_awaken_input","ai_ask_reset_input","ai_ask_hide_input","home_ai_page_scroll","ai_ask_hide_keyboard","ai_ask_clear_keyboard_tags","ai_ask_init_mask","ai_ask_hide_mask","ai_ask_transfer_to_wenwen","ai_ask_transfer_to_mask","close_loading_view","open_loading_view","set_ai_ask_container_status","to_set_notifaction","home_refresh","ai_ask_page_load_success","ai_ask_set_session_info","ai_ask_input_set_mention_url","ai_ask_input_set_scene","ai_float_brain_panel_back_to_top_panel_page","ai_float_brain_panel_set_tools"],APP_PROFILES={fliggy:{name:"fliggy",label:"éŖįĒ",appName:"LX",defaultAppVersion:"10.0.0",uaTokens:["AliTrip/{v}",WINDVANE],globals:{},bridges:[WV_BRIDGE,{global:"alitripBridge",style:"fliggy"},{global:"core",style:"fliggy"},{global:"methodChannel",style:"callback"}],activeEvents:WV_ACTIVE_EVENTS,actions:mergeActions(WV_ACTIONS,{...emptyActions(),open:["goto","ai_float_brain_panel_collapse_and_open_url"],close:[],title:["set_webview_title"],navigationBar:["set_ui"],statusBar:["set_status_bar_style"],systemInfo:["client_info","WVNativeDetector.getModelInfo"],kvGet:["get_kvcache"],kvSet:["set_kvcache"],kvDelete:["del_kvcache"],pageContext:["ai_float_brain_panel_get_page_context"],responses:{is_open_push:{is_open:!1},get_unread_message:{style:"POINT",count:0},get_v10_ab_info:{v10Version:!0},get_ai_ask_container_status:{status:"FULL"},ai_ask_get_keyboard_height:{height:0},get_idfa:{},get_caid:{},get_theme_conf:{},cppay_app_install:{result:""}},behaviors:{"page://goto":"navigate","page://close":"closeBackData",back:"closeBackData",user_info:"userInfo",ai_ask_get_memory_cache:"memoryGet",ai_ask_set_memory_cache:"memorySet",ai_ask_del_memory_cache:"memoryDelete",channelJudgeJsBridge:"availabilityMap",networktype:"networkInfo",network_quality_monitor:"networkQualityMonitor",request:"beaconRequest",store_calendar_event:"calendar",remove_calendar_event:"calendar",check_batch_calendar:"calendar",search_batch_calendar_events:"calendar",lbs:"geolocation",permission:"permission",cacheFetch:"prefetch",fptTrack:"fptTrack",toUT:"userTrack","WVTBUserTrack.toUT":"userTrack","WVTBUserTrack.toUT2":"userTrack",mtop_stream:"mtopStream",ai_ask_preview_file:"previewFile",toast:"toast",ai_ask_input_bridge:"unsupportedNativeInput",cppay:"payment",minipay:"payment",union_pay:"payment"},noop:["swipe_back","track_error_with_alarm","cacheUpdate","long_press_save_image",...FLIGGY_AI_UI_NOOPS],silent:["native://biz/mtop_normal_sign","toUT","get_idfa","get_caid","channelJudgeJsBridge","get_unread_message","get_v10_ab_info","lbs","networktype","network_quality_monitor","request","long_press_save_image","WVNativeDetector.getModelInfo","set_status_bar_style","get_theme_conf","cacheFetch","cppay_app_install","track_error_with_alarm",...FLIGGY_AI_UI_NOOPS]}),schemes:FLIGGY_SCHEME_RULES,imagePicker:FLIGGY_IMAGE_PICKER,layerUrlProxy:FLIGGY_LAYER_URL_PROXY,rootContainer:FLIGGY_ROOT_CONTAINER,titleBarHiddenPathnames:FLIGGY_TITLE_BAR_HIDDEN_PATHNAMES,statusBarBackgroundColors:FLIGGY_STATUS_BAR_BACKGROUND_COLORS,urlSyncHostSuffixes:["m.taobao.com","wapa.taobao.com"],overlay:FLIGGY_OVERLAY,popBeforeOpenParam:"_fli_popBeforeOpen",nativeBack:FLIGGY_NATIVE_BACK,forceH5Mtop:!0},taobao:{name:"taobao",label:"ææēæˇåŽ",appName:"TB",defaultAppVersion:"10.39.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE,MEGA_BRIDGE],activeEvents:WV_ACTIVE_EVENTS,actions:WV_ACTIONS,schemes:COMMON_SCHEME_RULES,overlay:TAOBAO_OVERLAY,nativeBack:WV_NATIVE_BACK},wechat:{name:"wechat",label:"垎äŋĄ",appName:"WeChat",defaultAppVersion:"8.0.58",uaFamily:"wechatMiniProgram",uaTokens:[],globals:{__wxjs_environment:"miniprogram"},bridges:[{global:"wx.miniProgram",style:"wechatMiniProgram"}],activeEvents:[],actions:{...emptyActions(),open:["navigateTo","redirectTo","switchTab","reLaunch"],close:["navigateBack"],noop:["postMessage"]},schemes:COMMON_SCHEME_RULES},tmall:{name:"tmall",label:"夊įĢ",appName:"TM",defaultAppVersion:"15.22.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE],activeEvents:WV_ACTIVE_EVENTS,actions:WV_ACTIONS,schemes:COMMON_SCHEME_RULES,nativeBack:WV_NATIVE_BACK},alipay:{name:"alipay",label:"æ¯äģåŽ",appName:"AP",defaultAppVersion:"10.6.0",uaTokens:["AlipayClient/{v}"],globals:{},bridges:[{global:"AlipayJSBridge",style:"alipay"}],activeEvents:[],actions:{open:["pushWindow","startApp"],close:["popWindow"],title:["setTitle"],navigationBar:["hideBackButton","showBackButton"],systemInfo:["getSystemInfo"],mtop:[],behaviors:{getNetworkType:"networkInfo",addNotifyListener:"notifySubscribe",removeNotifyListener:"notifyUnsubscribe",postNotification:"notifyPost"},noop:["postWebViewMessage","setGestureBack"],silent:["getNetworkType"]},schemes:COMMON_SCHEME_RULES,nativeBack:ALIPAY_NATIVE_BACK},koubei:{name:"koubei",label:"åŖįĸ",appName:"KB",defaultAppVersion:"9.5.0",uaTokens:["KoubeiClient/{v}"],globals:{},bridges:[{global:"AlipayJSBridge",style:"alipay"}],activeEvents:[],actions:{open:["pushWindow","startApp"],close:["popWindow"],title:["setTitle"],navigationBar:["hideBackButton","showBackButton"],systemInfo:["getSystemInfo"],mtop:[],behaviors:{getNetworkType:"networkInfo",addNotifyListener:"notifySubscribe",removeNotifyListener:"notifyUnsubscribe",postNotification:"notifyPost"},noop:["postWebViewMessage","setGestureBack"],silent:["getNetworkType"]},schemes:COMMON_SCHEME_RULES,nativeBack:ALIPAY_NATIVE_BACK},"taobao-tj":{name:"taobao-tj",label:"æˇåŽįšäģˇį",appName:"LT",defaultAppVersion:"10.32.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE],activeEvents:WV_ACTIVE_EVENTS,actions:WV_ACTIONS,schemes:COMMON_SCHEME_RULES,nativeBack:WV_NATIVE_BACK},"taobao-live":{name:"taobao-live",label:"æˇåŽį´æ",appName:"TAOBAOLIVEAPP",defaultAppVersion:"3.10.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE],activeEvents:WV_ACTIVE_EVENTS,actions:WV_ACTIONS,schemes:COMMON_SCHEME_RULES,nativeBack:WV_NATIVE_BACK},xianyu:{name:"xianyu",label:"é˛éąŧ",appName:"FM",defaultAppVersion:"7.15.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE],activeEvents:WV_ACTIVE_EVENTS,actions:WV_ACTIONS,schemes:COMMON_SCHEME_RULES,nativeBack:WV_NATIVE_BACK},etao:{name:"etao",label:"䏿ˇ",appName:"ET",defaultAppVersion:"9.27.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE],activeEvents:WV_ACTIVE_EVENTS,actions:WV_ACTIONS,schemes:COMMON_SCHEME_RULES,nativeBack:WV_NATIVE_BACK},eleme:{name:"eleme",label:"éĨŋäēäš",appName:"ELMC",defaultAppVersion:"11.12.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE],activeEvents:WV_ACTIVE_EVENTS,actions:WV_ACTIONS,schemes:COMMON_SCHEME_RULES,nativeBack:WV_NATIVE_BACK},damai:{name:"damai",label:"大éēĻ",appName:"DM",defaultAppVersion:"8.9.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE],activeEvents:WV_ACTIVE_EVENTS,actions:WV_ACTIONS,schemes:COMMON_SCHEME_RULES,nativeBack:WV_NATIVE_BACK},btrip:{name:"btrip",label:"éŋéåæ
",appName:"BLX",defaultAppVersion:"9.12.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE,{global:"methodChannel",style:"btrip"}],activeEvents:WV_ACTIVE_EVENTS,actions:mergeActions(WV_ACTIONS,{...emptyActions(),open:["goto"],behaviors:{back:"closeBackData"}}),schemes:COMMON_SCHEME_RULES,nativeBack:WV_NATIVE_BACK},amap:{name:"amap",label:"éĢåžˇå°åž",appName:"amap",defaultAppVersion:"13.8.0",uaTokens:[],globals:{},bridges:[{global:"AmapApp.bridge",style:"amap"}],activeEvents:[],actions:{open:["loadSchema","infoH5JsAction"],close:[],title:["setWebViewTitle"],systemInfo:[],mtop:[],noop:["interceptNativeBackEvent"]},schemes:COMMON_SCHEME_RULES,nativeBack:{handler:"onNativeBackEvent"}},qianwen:{name:"qianwen",label:"åéŽ",appName:"TONGYI",defaultAppVersion:"3.20.0",uaTokens:[],globals:{},bridges:[{global:"ucapi",style:"invoke"}],activeEvents:[],actions:{open:["biz.openPageUrl","webdialog.show"],close:["biz.closeWebPage","webdialog.pop"],title:[],systemInfo:[],mtop:[],behaviors:{"base.postmessage":"postMessage","biz.popToRootWindow":"closeAll","biz.popToTopChatWindow":"closeAll"},noop:[]},schemes:COMMON_SCHEME_RULES,messageEvent:"QKEVT_OnReceiveMessage"},lingyou:{name:"lingyou",label:"įŋ游",appName:"hongtu",defaultAppVersion:"1.5.0",uaTokens:["hongtu/{v}"],globals:{},bridges:[{global:"WKWebViewJavascriptBridge",style:"callHandler"},{global:"WebViewJavascriptBridge",style:"callHandler"}],activeEvents:[],actions:{...emptyActions(),open:["jumpPage"],close:["closePage"],title:["setPageTitle"]},schemes:COMMON_SCHEME_RULES},didi:{name:"didi",label:"æģ´æģ´åēčĄ",appName:"didi.passenger",defaultAppVersion:"6.9.0",uaTokens:["didi.passenger/{v}"],globals:{},bridges:[{global:"didiBridge",style:"didi"},{global:"Fusion",style:"didi"}],activeEvents:[],actions:{...emptyActions(),open:["openPage"],close:["closePage"]},schemes:COMMON_SCHEME_RULES},easybike:{name:"easybike",label:"æå°į¨čŊĻ",appName:"easybike",defaultAppVersion:"9.0.0",uaTokens:["app=easybike;"],globals:{},bridges:[{global:"webkit.messageHandlers.callNative",style:"easybikeNative"},{global:"AppFunctions",style:"easybikeNative"}],activeEvents:[],actions:mergeActions(WV_ACTIONS,{...emptyActions(),close:["business/hitch.closeWebView"]}),schemes:COMMON_SCHEME_RULES}};function buildAppProfileUa(profile,options={}){let os11=options.os??"ios",version2=options.appVersion??profile.defaultAppVersion,deviceModel=options.deviceModel??"Pixel 8 Pro";if(profile.uaFamily==="wechatMiniProgram")return os11==="android"?`Mozilla/5.0 (Linux; Android 14; ${deviceModel}; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/120.0.6099.43 Mobile MicroMessenger/${version2} WeChat/arm64 NetType/WIFI Language/zh_CN miniProgram`:`Mozilla/5.0 (iPhone; CPU iPhone OS 17_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/${version2} NetType/WIFI Language/zh_CN miniProgram`;let tokens=profile.uaTokens.map(t=>t.replaceAll("{v}",version2)).filter(Boolean),tail=tokens.length>0?` ${tokens.join(" ")}`:"";return os11==="android"?`Mozilla/5.0 (Linux; Android 14; ${deviceModel}) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/120.0.6099.43 Mobile Safari/537.36 AliApp(${profile.appName}/${version2})${tail}`:`Mozilla/5.0 (iPhone; CPU iPhone OS 17_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) AliApp(${profile.appName}/${version2})${tail}`}function resolveAppProfile(name,options={}){let profile=APP_PROFILES[name];if(!profile)throw new Error(`Unknown app profile "${name}". Available: ${Object.keys(APP_PROFILES).join(", ")}`);let os11=options.os??"ios",version2=options.appVersion??profile.defaultAppVersion,deviceModel=options.deviceModel??(os11==="android"?"Pixel 8 Pro":"iPhone15,3"),globals={...profile.globals,__APP_NAME__:profile.appName,__APP_VERSION__:version2,__FLI_DEVICE_MODEL__:deviceModel,__DEVICE_MODEL__:deviceModel},ua=buildAppProfileUa(profile,options);return{profile:profile.name,label:profile.label,ua,injected:{profile:profile.name,label:profile.label,globals,bridges:profile.bridges,activeEvents:profile.activeEvents,maxTouchPoints:5,statusBarHeight:os11==="android"?30:59,safeAreaInsets:os11==="android"?{top:30,right:0,bottom:24,left:0}:{top:59,right:0,bottom:34,left:0},language:"zh-Hans",userAgent:ua,navigatorPlatform:os11==="android"?"Linux armv8l":"iPhone",platform:os11==="android"?"Android":"iOS",systemVersion:os11==="android"?"14":"17.5",clientType:os11==="android"?"android":"iphone",actions:applyAppBridgeConfig(profile.actions,options.bridgeConfig),schemes:profile.schemes,...profile.imagePicker&&{imagePicker:profile.imagePicker},...profile.overlay&&{overlay:profile.overlay},...profile.popBeforeOpenParam&&{popBeforeOpenParam:profile.popBeforeOpenParam},...profile.messageEvent&&{messageEvent:profile.messageEvent},...profile.nativeBack&&{nativeBack:profile.nativeBack},...profile.layerUrlProxy&&{layerUrlProxy:profile.layerUrlProxy},...profile.urlSyncHostSuffixes&&{urlSyncHostSuffixes:profile.urlSyncHostSuffixes},...profile.forceH5Mtop&&{forceH5Mtop:!0},simulateSystemBars:options.simulateSystemBars!==!1,rootContainer:{enabled:!0,...profile.rootContainer?.statusBarHeightCookie&&{initialCookies:[{...profile.rootContainer.statusBarHeightCookie,value:String(os11==="android"?30:59)}]}},titleBar:{navigationBarHeight:os11==="android"?48:44,backgroundColor:"#ffffff",textColor:"#0f131a",...profile.titleBarHiddenPathnames&&{hiddenPathnames:profile.titleBarHiddenPathnames},...profile.statusBarBackgroundColors&&{statusBarBackgroundColors:profile.statusBarBackgroundColors}}},recommendedPreset:os11==="android"?"pixel-8":"iphone-15-pro"}}function installAppProfileEnvironment(config2){let w=window;if(w.__mearlAppProfile__)return null;w.__mearlAppProfile__=config2.profile;let SRC="mearl-app-bridge",TAG=`[AppBridge:${config2.label}]`,ROOT_FRAME_NAME="__mearl_root__",LAYER_FRAME_NAME="__mearl_layer__",isTop=window===window.top,isRootFrame=!isTop&&window.name===ROOT_FRAME_NAME,isLayerFrame=!isTop&&window.name===LAYER_FRAME_NAME,isContainerFrame=isTop||isRootFrame||isLayerFrame,usesRootContainer=isTop&&config2.rootContainer?.enabled===!0,simulateSystemBars=config2.simulateSystemBars!==!1,safeAreaInsets=config2.safeAreaInsets??{top:config2.statusBarHeight,right:0,bottom:0,left:0},log3=(...args)=>console.info(TAG,...args);for(let[key,value]of Object.entries(config2.globals))try{w[key]=value}catch{}typeof w.__STATUS_BAR_HEIGHT__!="number"&&(w.__STATUS_BAR_HEIGHT__=config2.statusBarHeight),typeof w.__SAFE_AREA_INSET_BOTTOM__!="number"&&(w.__SAFE_AREA_INSET_BOTTOM__=safeAreaInsets.bottom);let applySafeAreaCssVariables=()=>{let root=document.documentElement;if(!root)return!1;try{return root.style.setProperty("--safe-area-inset-top",`${safeAreaInsets.top}px`),root.style.setProperty("--safe-area-inset-right",`${safeAreaInsets.right}px`),root.style.setProperty("--safe-area-inset-bottom",`${safeAreaInsets.bottom}px`),root.style.setProperty("--safe-area-inset-left",`${safeAreaInsets.left}px`),!0}catch{return!1}};if(!applySafeAreaCssVariables()){let observer=new MutationObserver(()=>{applySafeAreaCssVariables()&&observer.disconnect()});observer.observe(document,{childList:!0})}if(config2.forceH5Mtop){let downstreamMtopParamsHandler=w.MTOP_PARAMS_HANDLER,forceH5Mtop=params=>{let resolved=params;if(typeof downstreamMtopParamsHandler=="function")try{resolved=downstreamMtopParamsHandler.call(window,params)??params}catch{resolved=params}return{...resolved&&typeof resolved=="object"?resolved:{},useNative:!1}};try{Object.defineProperty(w,"MTOP_PARAMS_HANDLER",{configurable:!0,get:()=>forceH5Mtop,set:handler=>{handler!==forceH5Mtop&&(downstreamMtopParamsHandler=handler)}})}catch{w.MTOP_PARAMS_HANDLER=forceH5Mtop}}for(let[key,value]of[["userAgent",config2.userAgent],["platform",config2.navigatorPlatform],["vendor","Apple Computer, Inc."],["appVersion",config2.userAgent.replace(/^Mozilla\//,"")]])try{Object.defineProperty(navigator,key,{get:()=>value,configurable:!0})}catch{}try{Object.defineProperty(navigator,"maxTouchPoints",{get:()=>config2.maxTouchPoints})}catch{}return{w,SRC,TAG,ROOT_FRAME_NAME,LAYER_FRAME_NAME,isTop,isRootFrame,isLayerFrame,isContainerFrame,usesRootContainer,simulateSystemBars,safeAreaInsets,log:log3}}function installAppProfileSystemBars(config2,environment,host){let{SRC,isTop,isContainerFrame,simulateSystemBars,safeAreaInsets}=environment,titleBarMode="auto",titleBarRoot=null,titleBarSpacer=null,systemStatusView=null,systemBottomRoot=null,systemBottomSurface=null,rootTitleBarView=null,titleBarTitleVisible=!0,titleBarBackVisible=!0,titleBarBackground=config2.titleBar?.backgroundColor??"#ffffff",titleBarTextColor=config2.titleBar?.textColor??"#111111",titleBarStateExplicit=!1,presentedRootTitleBarState=null,normalizeProxyPathPrefix=prefix=>{let withLeadingSlash=prefix.startsWith("/")?prefix:`/${prefix}`;return withLeadingSlash.endsWith("/")?withLeadingSlash:`${withLeadingSlash}/`},matchesProxyTarget=(hostname3,suffixes)=>suffixes.some(suffix=>hostname3===suffix||hostname3.endsWith(`.${suffix}`)),normalizePathname=pathname=>{let withLeadingSlash=pathname.startsWith("/")?pathname:`/${pathname}`;return withLeadingSlash.length>1&&withLeadingSlash.endsWith("/")?withLeadingSlash.slice(0,-1):withLeadingSlash},businessPathname=href=>{try{let current=new URL(href,location.href),proxy=config2.layerUrlProxy;if(!proxy)return normalizePathname(current.pathname);let prefix=normalizeProxyPathPrefix(proxy.pathPrefix);if(!current.pathname.startsWith(prefix))return normalizePathname(current.pathname);let rest=current.pathname.slice(prefix.length),slash=rest.indexOf("/"),hostName=slash===-1?rest:rest.slice(0,slash),pathname=slash===-1?"/":rest.slice(slash),hostname3=new URL(`${current.protocol}//${hostName}`).hostname;return matchesProxyTarget(hostname3,proxy.targetHostSuffixes)?normalizePathname(pathname):normalizePathname(current.pathname)}catch{return null}},matchesConfiguredPathname=(href,pathnames)=>{let pathname=businessPathname(href);return pathname!==null&&pathnames.some(configuredPathname=>normalizePathname(configuredPathname)===pathname)},isTruthyParam=value=>value==="1"||value?.toLowerCase()==="true"||value?.toUpperCase()==="YES",isTransparentColor=value=>{let normalized=value.replace(/\s/g,"").toLowerCase();return normalized==="transparent"||normalized==="#0000"||normalized==="#00000000"||normalized==="rgba(0,0,0,0)"},pageRequestedTitleBarMode=(href=location.href,includeMeta=!0)=>{try{let params=new URL(href,location.href).searchParams,webviewOptions=new URLSearchParams(params.get("__webview_options__")??""),option=key=>params.get(key)??webviewOptions.get(key);if(config2.profile==="fliggy"){let hidden=params.get("titleBarHidden");if(hidden==="1")return"status-inset";if(hidden==="2")return"status"}if(config2.profile==="taobao"&&option("disableNav")?.toUpperCase()==="YES")return isTruthyParam(option("status_bar_transparent"))?"status":"status-inset";if(config2.profile==="alipay"||config2.profile==="koubei"){if(option("showTitleBar")?.toUpperCase()==="NO")return"status-inset";let transparentTitle=option("transparentTitle")?.toLowerCase();if(transparentTitle&&["always","auto","custom"].includes(transparentTitle))return"overlay"}let overlayParam=config2.overlay?.enabledParam;return overlayParam&&isTruthyParam(params.get(overlayParam))||includeMeta&&document.getElementById("WV.Meta.Nav.HideNavBar")?.getAttribute("value")==="HideStatusBar"?"status":null}catch{return null}},pageRequestsHiddenTitleBar=(href=location.href)=>matchesConfiguredPathname(href,config2.titleBar?.hiddenPathnames??[]),configuredStatusBarBackground=(href=location.href)=>{let colors=config2.titleBar?.statusBarBackgroundColors??{},pathname=businessPathname(href);return pathname===null?null:Object.entries(colors).find(([configuredPathname])=>normalizePathname(configuredPathname)===pathname)?.[1]??null},pageRequestsHiddenStatusBar=(href=location.href)=>{try{let params=new URL(href,location.href).searchParams;return isTruthyParam(params.get("statusBarHidden"))||isTruthyParam(params.get("hideStatusBar"))?!0:/(?:^|&)showStatusBar=NO(?:&|$)/i.test(params.get("__webview_options__")??"")}catch{return!1}},resolveTitleBarMode=(href,fallback,includeMeta)=>{if(titleBarMode!=="auto")return titleBarMode;if(pageRequestsHiddenStatusBar(href))return"hidden";if(pageRequestsHiddenTitleBar(href))return"status-inset";let requestedMode=pageRequestedTitleBarMode(href,includeMeta);return requestedMode||fallback},resolveStatusBarBackground=(href,mode,navigationBarBackground)=>configuredStatusBarBackground(href)??(mode==="normal"||mode==="status-inset"?navigationBarBackground:"transparent"),ownTitleBarState=()=>{let mode=resolveTitleBarMode(location.href,"normal",!0);return{mode,title:document.title||config2.label,titleVisible:titleBarTitleVisible,backVisible:titleBarBackVisible,background:titleBarBackground,statusBarBackground:resolveStatusBarBackground(location.href,mode,titleBarBackground),textColor:titleBarTextColor}},initialLayerTitleBarState=url2=>{let mode=pageRequestsHiddenStatusBar(url2)?"hidden":pageRequestsHiddenTitleBar(url2)?"status-inset":pageRequestedTitleBarMode(url2,!1)??"normal",background=config2.titleBar?.backgroundColor??"#ffffff";return{mode,title:config2.label,titleVisible:!0,backVisible:!0,background,statusBarBackground:mode==="status-inset"?background:resolveStatusBarBackground(url2,mode,background),textColor:config2.titleBar?.textColor??"#111111"}},parseReportedTitleBarState=value=>{if(!value||typeof value!="object")return null;let state=value;return!["normal","overlay","status","status-inset","hidden"].includes(String(state.mode))||typeof state.title!="string"||typeof state.titleVisible!="boolean"||typeof state.backVisible!="boolean"||typeof state.background!="string"||typeof state.textColor!="string"?null:{...state,statusBarBackground:typeof state.statusBarBackground=="string"?state.statusBarBackground:state.mode==="normal"||state.mode==="status-inset"?String(state.background):"transparent"}},resolvedTitleBarState=layer=>layer?layer.titleBarState??initialLayerTitleBarState(layer.url):presentedRootTitleBarState??ownTitleBarState(),resolvedRootTitleBarState=(fallback=ownTitleBarState())=>presentedRootTitleBarState??(host.getRootFrame()?{...fallback,statusBarBackground:config2.titleBar?.backgroundColor??"#ffffff"}:fallback),renderNavigationBarView=(view,state)=>{let visible=state.mode==="normal"||state.mode==="overlay";view.root.style.display=visible?"block":"none",view.surface.style.visibility=visible?"visible":"hidden",view.surface.style.background=state.mode==="overlay"?"transparent":state.background,view.surface.style.borderBottom="none",view.surface.style.color=state.textColor,view.title.textContent=state.title,view.title.style.display=state.titleVisible?"flex":"none",view.back.style.display=state.backVisible?"flex":"none",view.back.style.color=state.textColor},topFullLayer=()=>{let layers=host.getLayers();for(let index=layers.length-1;index>=0;index-=1)if(!layers[index].overlay&&!layers[index].closing)return layers[index]},activeTitleBarState=()=>{let layer=topFullLayer();return layer?resolvedTitleBarState(layer):resolvedRootTitleBarState()},syncActiveSystemBars=()=>{let state=activeTitleBarState();if(systemStatusView){let visible=state.mode!=="hidden";systemStatusView.root.style.display=visible?"block":"none",systemStatusView.surface.style.visibility=visible?"visible":"hidden",systemStatusView.surface.style.background=state.statusBarBackground,systemStatusView.surface.style.color=state.textColor}systemBottomRoot&&systemBottomSurface&&(systemBottomRoot.style.display=safeAreaInsets.bottom>0?"block":"none",systemBottomSurface.style.color=state.textColor)},syncLayerViewport=(layer,state)=>{if(layer.overlay)return;if(!simulateSystemBars){layer.frame.style.top="0px",layer.frame.style.height="100%";return}let totalHeight=config2.statusBarHeight+(config2.titleBar?.navigationBarHeight??0),offset=state.mode==="normal"?totalHeight:state.mode==="status-inset"?config2.statusBarHeight:0;layer.frame.style.top=`${offset}px`,layer.frame.style.height=offset>0?`calc(100% - ${offset}px)`:"100%",layer.frame.style.opacity=state.mode==="status-inset"&&!layer.titleBarStateReady?"0":"1",layer.titleBarView&&renderNavigationBarView(layer.titleBarView,state),topFullLayer()===layer&&syncActiveSystemBars()},syncRootFrameViewport=state=>{let rootFrame=host.getRootFrame();if(!rootFrame)return;if(!simulateSystemBars){rootFrame.style.top="0px",rootFrame.style.height="100%";return}let totalHeight=config2.statusBarHeight+(config2.titleBar?.navigationBarHeight??0),offset=state.mode==="normal"?totalHeight:state.mode==="status-inset"?config2.statusBarHeight:0;rootFrame.style.top=`${offset}px`,rootFrame.style.height=offset>0?`calc(100% - ${offset}px)`:"100%",rootFrame.style.opacity=state.mode==="status-inset"&&presentedRootTitleBarState===null&&!rootFrame.hasAttribute("data-mearl-webview-ready")?"0":"1"},syncSimulatedTitleBar=()=>{let ownState=ownTitleBarState();if(!isTop){if(isContainerFrame){if(!titleBarStateExplicit&&document.readyState==="loading")return;window.top?.postMessage({source:SRC,type:"titleBarState",state:ownState,explicit:titleBarStateExplicit},"*")}return}if(!titleBarRoot||!titleBarSpacer||!systemStatusView||!rootTitleBarView)return;let rootFrame=host.getRootFrame();!rootFrame&&host.getLayers().length===0&&host.getClosingLayerCount()===0&&(presentedRootTitleBarState=ownState);let state=resolvedRootTitleBarState(ownState);renderNavigationBarView(rootTitleBarView,state);let spacerHeight=state.mode==="normal"?config2.statusBarHeight+(config2.titleBar?.navigationBarHeight??0):state.mode==="status-inset"?config2.statusBarHeight:0;titleBarSpacer.style.display=!rootFrame&&spacerHeight>0?"block":"none",titleBarSpacer.style.height=`${spacerHeight}px`,titleBarSpacer.style.minHeight=`${spacerHeight}px`,syncRootFrameViewport(state),syncActiveSystemBars()},applyNavigationBarState=(api,params)=>{titleBarStateExplicit=!0;let p=params&&typeof params=="object"?params:{},displayValue=p.titlebar_display??p.titlebarDisplay??p.titleBarDisplay,display=typeof displayValue=="string"?displayValue.toLowerCase():"";api==="hideBackButton"&&(titleBarBackVisible=!1),api==="showBackButton"&&(titleBarBackVisible=!0),display==="hide"&&(titleBarMode="status"),display==="show"&&(titleBarMode="normal"),(p.isImmersive===!0||p.isTransparent===!0)&&(titleBarMode="overlay"),p.isImmersive===!1&&p.isTransparent===!1&&(titleBarMode="normal"),typeof p.isTitleVisible=="boolean"&&(titleBarTitleVisible=p.isTitleVisible),typeof p.title=="string"&&(document.title=p.title),typeof p.backgroundColor=="string"&&(titleBarBackground=p.backgroundColor,isTransparentColor(p.backgroundColor)&&(titleBarMode="overlay")),typeof p.barTextStyle=="string"&&(titleBarTextColor=p.barTextStyle==="white"?"#ffffff":"#111111"),syncSimulatedTitleBar()},applyStatusBarState=params=>{titleBarStateExplicit=!0;let p=params&&typeof params=="object"?params:{},style=typeof p.style=="string"?p.style.toLowerCase():"";style&&(titleBarTextColor=style==="white"||style.includes("light")?"#ffffff":"#111111"),syncSimulatedTitleBar()},createNavigationBarView=(placement,onBack)=>{let titleBar=config2.titleBar,root=document.createElement("div");root.setAttribute("data-mearl-app-titlebar",config2.profile),root.setAttribute("data-mearl-titlebar-owner",placement),root.style.cssText=`${placement==="root"?"position:fixed":"position:absolute"};left:0;right:0;top:${config2.statusBarHeight}px;height:${titleBar.navigationBarHeight}px;z-index:${placement==="root"?"2147482900":"2"};overflow:hidden;box-sizing:border-box;font-family:"PingFang SC",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;`;let shadow=root.attachShadow({mode:"open"});shadow.innerHTML=`<style>
|
|
1017
|
+
`,RECORDING_BINDING_NAME="__mtopRecordReport",cdpRecordingSessions=new Map,RECORDING_MAX_REQUESTS=500,RECORDING_MAX_ACTIONS=1e3;async function cdpRecordStart(session,_data){if(cdpRecordingSessions.has(session.targetId))throw new Error(`Already recording on target ${session.targetId}. Call record_stop before starting a new recording.`);let pageClient=(await resolveCdpDeviceShellPageEndpoint(session)).client,recordingSession={targetId:session.targetId,startTime:Date.now(),startUrl:"",actions:[],client:pageClient};try{await pageClient.sendCommand("Runtime.addBinding",{name:RECORDING_BINDING_NAME})}catch(err){throw new Error(`Failed to register recording binding: ${err?.message??err}. CDP target may not support Runtime domain.`,{cause:err})}let nextSeq=1,onBindingCalled=params=>{if(params?.name===RECORDING_BINDING_NAME)try{let action=JSON.parse(params.payload);action.seq=nextSeq++,recordingSession.actions.push(action),recordingSession.actions.length>RECORDING_MAX_ACTIONS&&recordingSession.actions.splice(0,recordingSession.actions.length-RECORDING_MAX_ACTIONS)}catch{}};recordingSession.removeBindingListener=pageClient.on("Runtime.bindingCalled",onBindingCalled);try{let result=await pageClient.sendCommand("Page.addScriptToEvaluateOnNewDocument",{source:RECORDING_INJECTED_SCRIPT});recordingSession.scriptIdentifier=result?.identifier}catch(err){throw recordingSession.removeBindingListener?.(),new Error(`Failed to register recording script: ${err?.message??err}.`,{cause:err})}try{let value=(await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:RECORDING_BOOTSTRAP_SCRIPT,returnByValue:!0})).result?.value??{};recordingSession.startUrl=value.startUrl??""}catch{recordingSession.startUrl=""}return cdpRecordingSessions.set(session.targetId,recordingSession),{recording:!0,tabId:session.targetId,startTime:recordingSession.startTime}}async function cdpRecordStop(session,_data){let recordingSession=cdpRecordingSessions.get(session.targetId);if(!recordingSession)return{wasRecording:!1,actions:[],requests:[],requestsTruncated:!1,duration:0,startUrl:"",endUrl:""};if(cdpRecordingSessions.delete(session.targetId),recordingSession.removeBindingListener?.(),recordingSession.scriptIdentifier)try{await recordingSession.client.sendCommand("Page.removeScriptToEvaluateOnNewDocument",{identifier:recordingSession.scriptIdentifier})}catch{}let endUrl="";try{endUrl=(await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:RECORDING_TEARDOWN_SCRIPT,returnByValue:!0})).result?.value?.endUrl??""}catch{}try{await recordingSession.client.sendCommand("Runtime.removeBinding",{name:RECORDING_BINDING_NAME})}catch{}let endTime=Date.now(),startTime=recordingSession.startTime,duration3=Math.round((endTime-startTime)/1e3),allRequests=session.buffers.requests.filter(r=>r.timestampMs>=startTime),requests=allRequests.length>RECORDING_MAX_REQUESTS?allRequests.slice(-RECORDING_MAX_REQUESTS):allRequests;return{wasRecording:!0,actions:annotateActionsWithRequests(recordingSession.actions,requests,endTime),requests:serializeRecordingRequests(requests),requestsTruncated:allRequests.length>RECORDING_MAX_REQUESTS,duration:duration3,startUrl:recordingSession.startUrl,endUrl}}async function releaseCdpRecordings(sessions){await Promise.allSettled(sessions.filter(session=>cdpRecordingSessions.has(session.targetId)).map(session=>cdpRecordStop(session,{})));for(let recordingSession of cdpRecordingSessions.values())recordingSession.removeBindingListener?.();cdpRecordingSessions.clear()}registerActions([{name:"record_start",session:"page",handler:cdpRecordStart},{name:"record_stop",session:"page",handler:cdpRecordStop}]);var WINDVANE="WindVane/8.7.0",WV_BRIDGE={global:"WindVane",style:"windvane"},MEGA_BRIDGE={global:"__megability_bridge__",style:"mega"},WV_NATIVE_BACK={event:"wvBackClickEvent",controlFunction:"_windvane_backControl"},FLIGGY_NATIVE_BACK={event:"WV.Back"},ALIPAY_NATIVE_BACK={event:"back"},FLIGGY_OVERLAY={enabledParam:"_fli_overlay",topRatioParam:"_fli_overlay_ratio",radiusParam:"_fli_overlay_radius",maskAlphaParam:"_fli_overlay_mask_alpha",tapCloseParam:"_fli_overlay_tap_close",tapCloseSelectors:["#qwen-titlebar .qwen-titlebar-icon-wrapper:last-child"],silentTapClose:!0,defaultTopRatio:.2,defaultRadius:0,defaultMaskAlpha:.3,defaultTapClose:!0},TAOBAO_OVERLAY={enabledParam:"useWebdialog",topRatioParam:"topRatio",heightRatioParam:"height_pct",radiusParam:"cornerRadius",maskAlphaParam:"maskAlpha",tapCloseParam:"tapEnable",tapCloseSelectors:["#qwen-titlebar .qwen-titlebar-icon-wrapper:last-child"],defaultTopRatio:.2,defaultRadius:6,defaultMaskAlpha:.5,defaultTapClose:!0},FLIGGY_IMAGE_PICKER={schemes:["page://ask_take_photo"],api:"mtop.trip.serverless.api.gateway",version:"2.0",fcId:"240417431173407785",fcGroup:"fl-images",uploadUrlFunction:"uploadByTokenUrl",prefix:"temp",region:"CN"},FLIGGY_LAYER_URL_PROXY={sourceHostPrefix:"edith.",pathPrefix:"/proxy/",targetHostSuffixes:["wapa.taobao.com"],defaultTargetHost:"market.wapa.taobao.com"},FLIGGY_ROOT_CONTAINER={statusBarHeightCookie:{name:"_fli_barHeight",domain:"taobao.com",path:"/"}},FLIGGY_TITLE_BAR_HIDDEN_PATHNAMES=["/app/trip/rx-home/pages/home","/app/trip/rx-trip-ai/pages/home"],FLIGGY_STATUS_BAR_BACKGROUND_COLORS={"/app/trip/rx-home/pages/home":"#fff","/app/trip/rx-trip-ai/pages/home":"#dbdbff"};function emptyActions(){return{open:[],close:[],title:[],navigationBar:[],statusBar:[],systemInfo:[],mtop:[],kvGet:[],kvSet:[],kvDelete:[],pageContext:[],responses:{},behaviors:{},noop:[],silent:[]}}function mergeActions(...maps){let out=emptyActions();for(let m of maps)out.open.push(...m.open),out.close.push(...m.close),out.title.push(...m.title),out.navigationBar.push(...m.navigationBar??[]),out.statusBar.push(...m.statusBar??[]),out.systemInfo.push(...m.systemInfo),out.mtop.push(...m.mtop),out.kvGet.push(...m.kvGet??[]),out.kvSet.push(...m.kvSet??[]),out.kvDelete.push(...m.kvDelete??[]),out.pageContext.push(...m.pageContext??[]),Object.assign(out.responses,m.responses??{}),Object.assign(out.behaviors,m.behaviors??{}),out.noop.push(...m.noop),out.silent.push(...m.silent??[]);return out}var APP_BRIDGE_BEHAVIORS=["navigate","closeAll","closeBackData","postMessage","notifySubscribe","notifyUnsubscribe","notifyPost","sharedFileRead","sharedFileWrite","sharedDataGet","sharedDataSet","legacyBroadcastCreate","legacyBroadcastPost","legacyBroadcastClose","memoryGet","memorySet","memoryDelete","availabilityMap","userInfo","networkInfo","geolocation","permission","prefetch","fptTrack","mtopStream","previewFile","toast","unsupportedNativeInput","payment","userTrack","calendar","networkQualityMonitor","beaconRequest"],APP_BRIDGE_BEHAVIOR_SET=new Set(APP_BRIDGE_BEHAVIORS),BRIDGE_ACTION_ARRAY_KEYS=["open","close","title","navigationBar","statusBar","systemInfo","mtop","kvGet","kvSet","kvDelete","pageContext","noop"];function isJsonValue(value,seen=new Set){if(value===null||typeof value=="string"||typeof value=="boolean")return!0;if(typeof value=="number")return Number.isFinite(value);if(typeof value!="object"||seen.has(value))return!1;seen.add(value);let valid=Array.isArray(value)?value.every(item=>isJsonValue(item,seen)):Object.values(value).every(item=>isJsonValue(item,seen));return seen.delete(value),valid}function validateAppBridgeConfig(value){if(!value||typeof value!="object"||Array.isArray(value))throw new Error("bridgeConfig must be an object");let root=value;if(Object.keys(root).some(key=>key!=="methods"))throw new Error('bridgeConfig only supports the "methods" field');if(!root.methods||typeof root.methods!="object"||Array.isArray(root.methods))throw new Error("bridgeConfig.methods must be an object");let entries=Object.entries(root.methods);if(entries.length>200)throw new Error("bridgeConfig supports at most 200 methods");let methods2={};for(let[method,rawConfig]of entries){if(!method.trim()||method.length>200)throw new Error("bridgeConfig method names must contain 1-200 characters");if(method==="__proto__"||method==="prototype"||method==="constructor")throw new Error(`bridgeConfig method name "${method}" is reserved`);if(!rawConfig||typeof rawConfig!="object"||Array.isArray(rawConfig))throw new Error(`bridgeConfig.methods.${method} must be an object`);let methodConfig=rawConfig,supportedKeys=new Set(["behavior","response","noop","silent"]);if(Object.keys(methodConfig).some(key=>!supportedKeys.has(key)))throw new Error(`bridgeConfig.methods.${method} contains an unsupported field`);if("behavior"in methodConfig&&typeof methodConfig.behavior!="string")throw new Error(`bridgeConfig.methods.${method}.behavior must be a string`);let hasBehavior=typeof methodConfig.behavior=="string",hasResponse=Object.prototype.hasOwnProperty.call(methodConfig,"response"),hasNoop=methodConfig.noop===!0;if(Number(hasBehavior)+Number(hasResponse)+Number(hasNoop)!==1)throw new Error(`bridgeConfig.methods.${method} must define exactly one of behavior, response, or noop=true`);if(hasBehavior&&!APP_BRIDGE_BEHAVIOR_SET.has(methodConfig.behavior))throw new Error(`bridgeConfig.methods.${method} has an unsupported behavior`);if(hasResponse&&!isJsonValue(methodConfig.response))throw new Error(`bridgeConfig.methods.${method}.response must be valid JSON data`);if("noop"in methodConfig&&methodConfig.noop!==!0)throw new Error(`bridgeConfig.methods.${method}.noop must be true when provided`);if("silent"in methodConfig&&typeof methodConfig.silent!="boolean")throw new Error(`bridgeConfig.methods.${method}.silent must be a boolean`);methods2[method]={...hasBehavior&&{behavior:methodConfig.behavior},...hasResponse&&{response:JSON.parse(JSON.stringify(methodConfig.response))},...hasNoop&&{noop:!0},...methodConfig.silent===!0&&{silent:!0}}}let normalized={methods:methods2};if(JSON.stringify(normalized).length>65536)throw new Error("bridgeConfig must not exceed 64 KiB");return normalized}function applyAppBridgeConfig(actions,config2){let out=mergeActions(actions);if(!config2)return out;let{methods:methods2}=validateAppBridgeConfig(config2);for(let[method,methodConfig]of Object.entries(methods2)){for(let key of BRIDGE_ACTION_ARRAY_KEYS){let values=out[key];values&&(out[key]=values.filter(value=>value!==method))}out.silent=(out.silent??[]).filter(value=>value!==method),delete out.responses?.[method],delete out.behaviors?.[method],methodConfig.behavior?out.behaviors[method]=methodConfig.behavior:Object.prototype.hasOwnProperty.call(methodConfig,"response")?out.responses[method]=methodConfig.response:methodConfig.noop&&out.noop.push(method),methodConfig.silent&&out.silent.push(method)}return out}var WV_ACTIONS={open:["WVNative.openWindow","Base.openBrowser","EtaoJsbridgeUtil.openWindow","TMBridge.pushWindow","Third.openThirdWeb"],close:["WebAppInterface.pop","Triver.pop","TMBridge.popWindow","EleWVHybridAPI.popWindow","Third.closeWebView"],title:["WebAppInterface.setCustomPageTitle"],navigationBar:["Triver.setNavigationBarStyle"],statusBar:["WebAppInterface.setStatusBarStyle","Application.setStatusBarStyle"],systemInfo:[],mtop:["MtopWVPlugin.send"],behaviors:{"WVNetwork.getNetworkType":"networkInfo","WVFile.read":"sharedFileRead","WVFile.write":"sharedFileWrite","SharedData.getSharedData":"sharedDataGet","SharedData.setSharedData":"sharedDataSet","WVBroadcast.createChannel":"legacyBroadcastCreate","WVBroadcast.postMessage":"legacyBroadcastPost","WVBroadcast.close":"legacyBroadcastClose"},noop:["WVNative.enableHookNativeBack","WVNative.forbidPanGesture","WVNative.setGestureBack","WVTBUserTrack.toUT","WVTBUserTrack.toUT2"],silent:["WVNetwork.getNetworkType","WVTBUserTrack.toUT","WVTBUserTrack.toUT2"]},COMMON_SCHEME_RULES=[{match:"page:",param:"params"},{match:"taobaotravel:",param:"params"},{match:"alipays://platformapi/starth5app",param:"url"},{match:"alipays://platformapi/startapp",param:"page"},{match:"eleme://web",param:"url"},{match:"amapuri://webview/",param:"url"}],FEIZHU_WECHAT_HOST_SUFFIXES=["feizhu.com"],WECHAT_SCHEME_RULES=[{match:"/pages/main/webview",hostSuffixes:FEIZHU_WECHAT_HOST_SUFFIXES,param:"url",useCurrentOrigin:!0},...COMMON_SCHEME_RULES],WECHAT_MINI_PROGRAM={paymentRoutes:[{pathname:"/pages/utils/common-pay/index",hostSuffixes:FEIZHU_WECHAT_HOST_SUFFIXES,paymentParamsParam:"signStr",successUrlParams:["backUrl","successUrl"],failureUrlParams:["unSuccessUrl","errorUrl"],successResultParam:"__paymentRes",forwardParams:["ttid"],useCurrentOrigin:!0}],nativeRoutes:[{pathname:"/pages/utils/webview-bridge/index",hostSuffixes:FEIZHU_WECHAT_HOST_SUFFIXES,actions:["navigateMiniProgram","subscribeMessage"]}],messageRules:[{type:"BACK_DATA",action:"stageBackData",hostSuffixes:FEIZHU_WECHAT_HOST_SUFFIXES},{type:"BACK_MINI_APP",action:"closeAll",hostSuffixes:FEIZHU_WECHAT_HOST_SUFFIXES}]},WECHAT_TITLE_BAR_HOST_STYLES=[{hostSuffix:"feizhu.com",titleBarBackgroundColor:"#ffe033",statusBarBackgroundColor:"#ffe033"}],FLIGGY_SCHEME_RULES=[{match:"fliggy://order/detail",targetPath:"/app/trip/rx-flight-detail/pages/index",targetHostPrefix:"market",targetParams:{titleBarHidden:"2"}},...COMMON_SCHEME_RULES],WV_ACTIVE_EVENTS=["WV.Event.APP.Active"],FLIGGY_AI_UI_NOOPS=["handleLiveActivity","ai_ask_scroll_position","ai_ask_input_status","ai_ask_set_keyboard_tags","ai_ask_h5_awaken_input","ai_ask_reset_input","ai_ask_hide_input","home_ai_page_scroll","ai_ask_hide_keyboard","ai_ask_clear_keyboard_tags","ai_ask_init_mask","ai_ask_hide_mask","ai_ask_transfer_to_wenwen","ai_ask_transfer_to_mask","close_loading_view","open_loading_view","set_ai_ask_container_status","to_set_notifaction","home_refresh","ai_ask_page_load_success","ai_ask_set_session_info","ai_ask_input_set_mention_url","ai_ask_input_set_scene","ai_float_brain_panel_back_to_top_panel_page","ai_float_brain_panel_set_tools"],APP_PROFILES={fliggy:{name:"fliggy",label:"éŖįĒ",appName:"LX",defaultAppVersion:"10.0.0",uaTokens:["AliTrip/{v}",WINDVANE],globals:{},bridges:[WV_BRIDGE,{global:"alitripBridge",style:"fliggy"},{global:"core",style:"fliggy"},{global:"methodChannel",style:"callback"}],activeEvents:WV_ACTIVE_EVENTS,actions:mergeActions(WV_ACTIONS,{...emptyActions(),open:["goto","ai_float_brain_panel_collapse_and_open_url"],close:[],title:["set_webview_title"],navigationBar:["set_ui"],statusBar:["set_status_bar_style"],systemInfo:["client_info","WVNativeDetector.getModelInfo"],kvGet:["get_kvcache"],kvSet:["set_kvcache"],kvDelete:["del_kvcache"],pageContext:["ai_float_brain_panel_get_page_context"],responses:{is_open_push:{is_open:!1},get_unread_message:{style:"POINT",count:0},get_v10_ab_info:{v10Version:!0},get_ai_ask_container_status:{status:"FULL"},ai_ask_get_keyboard_height:{height:0},get_idfa:{},get_caid:{},get_theme_conf:{},cppay_app_install:{result:""}},behaviors:{"page://goto":"navigate","page://close":"closeBackData",back:"closeBackData",user_info:"userInfo",ai_ask_get_memory_cache:"memoryGet",ai_ask_set_memory_cache:"memorySet",ai_ask_del_memory_cache:"memoryDelete",channelJudgeJsBridge:"availabilityMap",networktype:"networkInfo",network_quality_monitor:"networkQualityMonitor",request:"beaconRequest",store_calendar_event:"calendar",remove_calendar_event:"calendar",check_batch_calendar:"calendar",search_batch_calendar_events:"calendar",lbs:"geolocation",permission:"permission",cacheFetch:"prefetch",fptTrack:"fptTrack",toUT:"userTrack","WVTBUserTrack.toUT":"userTrack","WVTBUserTrack.toUT2":"userTrack",mtop_stream:"mtopStream",ai_ask_preview_file:"previewFile",toast:"toast",ai_ask_input_bridge:"unsupportedNativeInput",cppay:"payment",minipay:"payment",union_pay:"payment"},noop:["swipe_back","track_error_with_alarm","cacheUpdate","long_press_save_image",...FLIGGY_AI_UI_NOOPS],silent:["native://biz/mtop_normal_sign","toUT","get_idfa","get_caid","channelJudgeJsBridge","get_unread_message","get_v10_ab_info","lbs","networktype","network_quality_monitor","request","long_press_save_image","WVNativeDetector.getModelInfo","set_status_bar_style","get_theme_conf","cacheFetch","cppay_app_install","track_error_with_alarm",...FLIGGY_AI_UI_NOOPS]}),schemes:FLIGGY_SCHEME_RULES,imagePicker:FLIGGY_IMAGE_PICKER,layerUrlProxy:FLIGGY_LAYER_URL_PROXY,rootContainer:FLIGGY_ROOT_CONTAINER,titleBarHiddenPathnames:FLIGGY_TITLE_BAR_HIDDEN_PATHNAMES,statusBarBackgroundColors:FLIGGY_STATUS_BAR_BACKGROUND_COLORS,urlSyncHostSuffixes:["m.taobao.com","wapa.taobao.com"],overlay:FLIGGY_OVERLAY,popBeforeOpenParam:"_fli_popBeforeOpen",nativeBack:FLIGGY_NATIVE_BACK,forceH5Mtop:!0},taobao:{name:"taobao",label:"ææēæˇåŽ",appName:"TB",defaultAppVersion:"10.39.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE,MEGA_BRIDGE],activeEvents:WV_ACTIVE_EVENTS,actions:WV_ACTIONS,schemes:COMMON_SCHEME_RULES,overlay:TAOBAO_OVERLAY,nativeBack:WV_NATIVE_BACK},wechat:{name:"wechat",label:"垎äŋĄ",appName:"WeChat",defaultAppVersion:"8.0.58",uaFamily:"wechatMiniProgram",uaTokens:[],globals:{__wxjs_environment:"miniprogram"},bridges:[{global:"wx.miniProgram",style:"wechatMiniProgram",persistent:!0}],activeEvents:[],actions:{...emptyActions(),open:["navigateTo","redirectTo","switchTab","reLaunch"],close:["navigateBack"],behaviors:{postMessage:"postMessage"}},schemes:WECHAT_SCHEME_RULES,miniProgram:WECHAT_MINI_PROGRAM,titleBarHostStyles:WECHAT_TITLE_BAR_HOST_STYLES},tmall:{name:"tmall",label:"夊įĢ",appName:"TM",defaultAppVersion:"15.22.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE],activeEvents:WV_ACTIVE_EVENTS,actions:WV_ACTIONS,schemes:COMMON_SCHEME_RULES,nativeBack:WV_NATIVE_BACK},alipay:{name:"alipay",label:"æ¯äģåŽ",appName:"AP",defaultAppVersion:"10.6.0",uaTokens:["AlipayClient/{v}"],globals:{},bridges:[{global:"AlipayJSBridge",style:"alipay"}],activeEvents:[],actions:{open:["pushWindow","startApp"],close:["popWindow"],title:["setTitle"],navigationBar:["hideBackButton","showBackButton"],systemInfo:["getSystemInfo"],mtop:[],behaviors:{getNetworkType:"networkInfo",addNotifyListener:"notifySubscribe",removeNotifyListener:"notifyUnsubscribe",postNotification:"notifyPost"},noop:["postWebViewMessage","setGestureBack"],silent:["getNetworkType"]},schemes:COMMON_SCHEME_RULES,nativeBack:ALIPAY_NATIVE_BACK},koubei:{name:"koubei",label:"åŖįĸ",appName:"KB",defaultAppVersion:"9.5.0",uaTokens:["KoubeiClient/{v}"],globals:{},bridges:[{global:"AlipayJSBridge",style:"alipay"}],activeEvents:[],actions:{open:["pushWindow","startApp"],close:["popWindow"],title:["setTitle"],navigationBar:["hideBackButton","showBackButton"],systemInfo:["getSystemInfo"],mtop:[],behaviors:{getNetworkType:"networkInfo",addNotifyListener:"notifySubscribe",removeNotifyListener:"notifyUnsubscribe",postNotification:"notifyPost"},noop:["postWebViewMessage","setGestureBack"],silent:["getNetworkType"]},schemes:COMMON_SCHEME_RULES,nativeBack:ALIPAY_NATIVE_BACK},"taobao-tj":{name:"taobao-tj",label:"æˇåŽįšäģˇį",appName:"LT",defaultAppVersion:"10.32.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE],activeEvents:WV_ACTIVE_EVENTS,actions:WV_ACTIONS,schemes:COMMON_SCHEME_RULES,nativeBack:WV_NATIVE_BACK},"taobao-live":{name:"taobao-live",label:"æˇåŽį´æ",appName:"TAOBAOLIVEAPP",defaultAppVersion:"3.10.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE],activeEvents:WV_ACTIVE_EVENTS,actions:WV_ACTIONS,schemes:COMMON_SCHEME_RULES,nativeBack:WV_NATIVE_BACK},xianyu:{name:"xianyu",label:"é˛éąŧ",appName:"FM",defaultAppVersion:"7.15.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE],activeEvents:WV_ACTIVE_EVENTS,actions:WV_ACTIONS,schemes:COMMON_SCHEME_RULES,nativeBack:WV_NATIVE_BACK},etao:{name:"etao",label:"䏿ˇ",appName:"ET",defaultAppVersion:"9.27.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE],activeEvents:WV_ACTIVE_EVENTS,actions:WV_ACTIONS,schemes:COMMON_SCHEME_RULES,nativeBack:WV_NATIVE_BACK},eleme:{name:"eleme",label:"éĨŋäēäš",appName:"ELMC",defaultAppVersion:"11.12.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE],activeEvents:WV_ACTIVE_EVENTS,actions:WV_ACTIONS,schemes:COMMON_SCHEME_RULES,nativeBack:WV_NATIVE_BACK},damai:{name:"damai",label:"大éēĻ",appName:"DM",defaultAppVersion:"8.9.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE],activeEvents:WV_ACTIVE_EVENTS,actions:WV_ACTIONS,schemes:COMMON_SCHEME_RULES,nativeBack:WV_NATIVE_BACK},btrip:{name:"btrip",label:"éŋéåæ
",appName:"BLX",defaultAppVersion:"9.12.0",uaTokens:[WINDVANE],globals:{},bridges:[WV_BRIDGE,{global:"methodChannel",style:"btrip"}],activeEvents:WV_ACTIVE_EVENTS,actions:mergeActions(WV_ACTIONS,{...emptyActions(),open:["goto"],behaviors:{back:"closeBackData"}}),schemes:COMMON_SCHEME_RULES,nativeBack:WV_NATIVE_BACK},amap:{name:"amap",label:"éĢåžˇå°åž",appName:"amap",defaultAppVersion:"13.8.0",uaTokens:[],globals:{},bridges:[{global:"AmapApp.bridge",style:"amap"}],activeEvents:[],actions:{open:["loadSchema","infoH5JsAction"],close:[],title:["setWebViewTitle"],systemInfo:[],mtop:[],noop:["interceptNativeBackEvent"]},schemes:COMMON_SCHEME_RULES,nativeBack:{handler:"onNativeBackEvent"}},qianwen:{name:"qianwen",label:"åéŽ",appName:"TONGYI",defaultAppVersion:"3.20.0",uaTokens:[],globals:{},bridges:[{global:"ucapi",style:"invoke"}],activeEvents:[],actions:{open:["biz.openPageUrl","webdialog.show"],close:["biz.closeWebPage","webdialog.pop"],title:[],systemInfo:[],mtop:[],behaviors:{"base.postmessage":"postMessage","biz.popToRootWindow":"closeAll","biz.popToTopChatWindow":"closeAll"},noop:[]},schemes:COMMON_SCHEME_RULES,messageEvent:"QKEVT_OnReceiveMessage"},lingyou:{name:"lingyou",label:"įŋ游",appName:"hongtu",defaultAppVersion:"1.5.0",uaTokens:["hongtu/{v}"],globals:{},bridges:[{global:"WKWebViewJavascriptBridge",style:"callHandler"},{global:"WebViewJavascriptBridge",style:"callHandler"}],activeEvents:[],actions:{...emptyActions(),open:["jumpPage"],close:["closePage"],title:["setPageTitle"]},schemes:COMMON_SCHEME_RULES},didi:{name:"didi",label:"æģ´æģ´åēčĄ",appName:"didi.passenger",defaultAppVersion:"6.9.0",uaTokens:["didi.passenger/{v}"],globals:{},bridges:[{global:"didiBridge",style:"didi"},{global:"Fusion",style:"didi"}],activeEvents:[],actions:{...emptyActions(),open:["openPage"],close:["closePage"]},schemes:COMMON_SCHEME_RULES},easybike:{name:"easybike",label:"æå°į¨čŊĻ",appName:"easybike",defaultAppVersion:"9.0.0",uaTokens:["app=easybike;"],globals:{},bridges:[{global:"webkit.messageHandlers.callNative",style:"easybikeNative"},{global:"AppFunctions",style:"easybikeNative"}],activeEvents:[],actions:mergeActions(WV_ACTIONS,{...emptyActions(),close:["business/hitch.closeWebView"]}),schemes:COMMON_SCHEME_RULES}};function buildAppProfileUa(profile,options={}){let os11=options.os??(options.devicePreset?DEVICE_PRESETS[options.devicePreset]?.appProfileOs:void 0)??"ios",version2=options.appVersion??profile.defaultAppVersion,deviceModel=options.deviceModel??(options.devicePreset?DEVICE_PRESETS[options.devicePreset]?.appProfileModel:void 0)??"Pixel 11";if(profile.uaFamily==="wechatMiniProgram")return os11==="android"?`Mozilla/5.0 (Linux; Android 17; ${deviceModel}; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/152.0.0.0 Mobile MicroMessenger/${version2} WeChat/arm64 NetType/WIFI Language/zh_CN miniProgram`:`Mozilla/5.0 (iPhone; CPU iPhone OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/${version2} NetType/WIFI Language/zh_CN miniProgram`;let tokens=profile.uaTokens.map(t=>t.replaceAll("{v}",version2)).filter(Boolean),tail=tokens.length>0?` ${tokens.join(" ")}`:"";return os11==="android"?`Mozilla/5.0 (Linux; Android 17; ${deviceModel}) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/152.0.0.0 Mobile Safari/537.36 AliApp(${profile.appName}/${version2})${tail}`:`Mozilla/5.0 (iPhone; CPU iPhone OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) AliApp(${profile.appName}/${version2})${tail}`}function resolveAppProfile(name,options={}){let profile=APP_PROFILES[name];if(!profile)throw new Error(`Unknown app profile "${name}". Available: ${Object.keys(APP_PROFILES).join(", ")}`);let os11=options.os??(options.devicePreset?DEVICE_PRESETS[options.devicePreset]?.appProfileOs:void 0)??"ios",version2=options.appVersion??profile.defaultAppVersion,recommendedPreset=os11==="android"?"pixel-11":"iphone-17-pro",devicePreset=options.devicePreset??recommendedPreset,emulation=resolveEmulationConfig({enabled:!0,preset:devicePreset,orientation:options.orientation}),deviceModel=options.deviceModel??DEVICE_PRESETS[devicePreset].appProfileModel,globals={...profile.globals,__APP_NAME__:profile.appName,__APP_VERSION__:version2,__FLI_DEVICE_MODEL__:deviceModel,__DEVICE_MODEL__:deviceModel},ua=buildAppProfileUa(profile,{...options,os:os11,deviceModel});return{profile:profile.name,label:profile.label,ua,injected:{profile:profile.name,label:profile.label,globals,bridges:profile.bridges,activeEvents:profile.activeEvents,maxTouchPoints:5,statusBarHeight:emulation.safeAreaInsets.top,safeAreaInsets:emulation.safeAreaInsets,deviceAppearance:{preset:devicePreset,orientation:emulation.orientation,cutout:emulation.appearance.cutout},language:"zh-Hans",userAgent:ua,navigatorPlatform:os11==="android"?"Linux armv8l":"iPhone",platform:os11==="android"?"Android":"iOS",systemVersion:os11==="android"?"17":"26.0",clientType:os11==="android"?"android":"iphone",actions:applyAppBridgeConfig(profile.actions,options.bridgeConfig),schemes:profile.schemes,...profile.miniProgram&&{miniProgram:profile.miniProgram},...profile.imagePicker&&{imagePicker:profile.imagePicker},...profile.overlay&&{overlay:profile.overlay},...profile.popBeforeOpenParam&&{popBeforeOpenParam:profile.popBeforeOpenParam},...profile.messageEvent&&{messageEvent:profile.messageEvent},...profile.nativeBack&&{nativeBack:profile.nativeBack},...profile.layerUrlProxy&&{layerUrlProxy:profile.layerUrlProxy},...profile.urlSyncHostSuffixes&&{urlSyncHostSuffixes:profile.urlSyncHostSuffixes},...profile.forceH5Mtop&&{forceH5Mtop:!0},simulateSystemBars:!1,rootContainer:{enabled:!1,...profile.rootContainer?.statusBarHeightCookie&&{initialCookies:[{...profile.rootContainer.statusBarHeightCookie,value:String(emulation.safeAreaInsets.top)}]}},titleBar:{navigationBarHeight:os11==="android"?48:44,backgroundColor:"#ffffff",textColor:"#0f131a",...profile.titleBarHiddenPathnames&&{hiddenPathnames:profile.titleBarHiddenPathnames},...profile.statusBarBackgroundColors&&{statusBarBackgroundColors:profile.statusBarBackgroundColors},...profile.titleBarHostStyles&&{hostStyles:profile.titleBarHostStyles}}},recommendedPreset}}function installAppProfileEnvironment(config2){let w=window;if(w.__mearlAppProfile__)return null;w.__mearlAppProfile__=config2.profile;let SRC="mearl-app-bridge",TAG=`[AppBridge:${config2.label}]`,ROOT_FRAME_NAME="__mearl_root__",LAYER_FRAME_NAME="__mearl_layer__",isTop=window===window.top,isRootFrame=!isTop&&window.name===ROOT_FRAME_NAME,isLayerFrame=!isTop&&window.name===LAYER_FRAME_NAME,isContainerFrame=isTop||isRootFrame||isLayerFrame,usesRootContainer=isTop&&config2.rootContainer?.enabled===!0,simulateSystemBars=config2.simulateSystemBars!==!1,safeAreaInsets=config2.safeAreaInsets??{top:config2.statusBarHeight,right:0,bottom:0,left:0},log3=(...args)=>console.info(TAG,...args);for(let[key,value]of Object.entries(config2.globals))try{w[key]=value}catch{}typeof w.__STATUS_BAR_HEIGHT__!="number"&&(w.__STATUS_BAR_HEIGHT__=config2.statusBarHeight),typeof w.__SAFE_AREA_INSET_BOTTOM__!="number"&&(w.__SAFE_AREA_INSET_BOTTOM__=safeAreaInsets.bottom);let applySafeAreaCssVariables=()=>{let root=document.documentElement;if(!root)return!1;try{return root.style.setProperty("--safe-area-inset-top",`${safeAreaInsets.top}px`),root.style.setProperty("--safe-area-inset-right",`${safeAreaInsets.right}px`),root.style.setProperty("--safe-area-inset-bottom",`${safeAreaInsets.bottom}px`),root.style.setProperty("--safe-area-inset-left",`${safeAreaInsets.left}px`),!0}catch{return!1}};if(!applySafeAreaCssVariables()){let observer=new MutationObserver(()=>{applySafeAreaCssVariables()&&observer.disconnect()});observer.observe(document,{childList:!0})}if(config2.forceH5Mtop){let downstreamMtopParamsHandler=w.MTOP_PARAMS_HANDLER,forceH5Mtop=params=>{let resolved=params;if(typeof downstreamMtopParamsHandler=="function")try{resolved=downstreamMtopParamsHandler.call(window,params)??params}catch{resolved=params}return{...resolved&&typeof resolved=="object"?resolved:{},useNative:!1}};try{Object.defineProperty(w,"MTOP_PARAMS_HANDLER",{configurable:!0,get:()=>forceH5Mtop,set:handler=>{handler!==forceH5Mtop&&(downstreamMtopParamsHandler=handler)}})}catch{w.MTOP_PARAMS_HANDLER=forceH5Mtop}}for(let[key,value]of[["userAgent",config2.userAgent],["platform",config2.navigatorPlatform],["vendor","Apple Computer, Inc."],["appVersion",config2.userAgent.replace(/^Mozilla\//,"")]])try{Object.defineProperty(navigator,key,{get:()=>value,configurable:!0})}catch{}try{Object.defineProperty(navigator,"maxTouchPoints",{get:()=>config2.maxTouchPoints})}catch{}return{w,SRC,TAG,ROOT_FRAME_NAME,LAYER_FRAME_NAME,isTop,isRootFrame,isLayerFrame,isContainerFrame,usesRootContainer,simulateSystemBars,safeAreaInsets,log:log3}}function installAppProfileSystemBars(config2,environment,host){let{SRC,isTop,isContainerFrame,simulateSystemBars,safeAreaInsets}=environment,externalDeviceChrome=config2.externalDeviceChrome===!0,titleBarMode="auto",titleBarRoot=null,titleBarSpacer=null,systemStatusView=null,systemBottomRoot=null,systemBottomSurface=null,rootTitleBarView=null,titleBarTitleVisible=!0,titleBarBackVisible=!0,titleBarBackground=config2.titleBar?.backgroundColor??"#ffffff",titleBarTextColor=config2.titleBar?.textColor??"#111111",titleBarStateExplicit=!1,presentedRootTitleBarState=null,normalizeProxyPathPrefix=prefix=>{let withLeadingSlash=prefix.startsWith("/")?prefix:`/${prefix}`;return withLeadingSlash.endsWith("/")?withLeadingSlash:`${withLeadingSlash}/`},matchesProxyTarget=(hostname3,suffixes)=>suffixes.some(suffix=>hostname3===suffix||hostname3.endsWith(`.${suffix}`)),normalizePathname=pathname=>{let withLeadingSlash=pathname.startsWith("/")?pathname:`/${pathname}`;return withLeadingSlash.length>1&&withLeadingSlash.endsWith("/")?withLeadingSlash.slice(0,-1):withLeadingSlash},businessPathname=href=>{try{let current=new URL(href,location.href),proxy=config2.layerUrlProxy;if(!proxy)return normalizePathname(current.pathname);let prefix=normalizeProxyPathPrefix(proxy.pathPrefix);if(!current.pathname.startsWith(prefix))return normalizePathname(current.pathname);let rest=current.pathname.slice(prefix.length),slash=rest.indexOf("/"),hostName=slash===-1?rest:rest.slice(0,slash),pathname=slash===-1?"/":rest.slice(slash),hostname3=new URL(`${current.protocol}//${hostName}`).hostname;return matchesProxyTarget(hostname3,proxy.targetHostSuffixes)?normalizePathname(pathname):normalizePathname(current.pathname)}catch{return null}},matchesConfiguredPathname=(href,pathnames)=>{let pathname=businessPathname(href);return pathname!==null&&pathnames.some(configuredPathname=>normalizePathname(configuredPathname)===pathname)},configuredHostStyle=(href=location.href)=>{try{let hostname3=new URL(href,location.href).hostname.toLowerCase();return(config2.titleBar?.hostStyles??[]).find(rule=>{let suffix=rule.hostSuffix.trim().replace(/^\.+/,"").toLowerCase();return suffix!==""&&(hostname3===suffix||hostname3.endsWith(`.${suffix}`))})}catch{return}},configuredTitleBarBackground=(href,fallback)=>configuredHostStyle(href)?.titleBarBackgroundColor??fallback,isTruthyParam=value=>value==="1"||value?.toLowerCase()==="true"||value?.toUpperCase()==="YES",isTransparentColor=value=>{let normalized=value.replace(/\s/g,"").toLowerCase();return normalized==="transparent"||normalized==="#0000"||normalized==="#00000000"||normalized==="rgba(0,0,0,0)"},pageRequestedTitleBarMode=(href=location.href,includeMeta=!0)=>{try{let params=new URL(href,location.href).searchParams,webviewOptions=new URLSearchParams(params.get("__webview_options__")??""),option=key=>params.get(key)??webviewOptions.get(key);if(config2.profile==="fliggy"){let hidden=params.get("titleBarHidden");if(hidden==="1")return"status-inset";if(hidden==="2")return"status"}if(config2.profile==="taobao"&&option("disableNav")?.toUpperCase()==="YES")return isTruthyParam(option("status_bar_transparent"))?"status":"status-inset";if(config2.profile==="alipay"||config2.profile==="koubei"){if(option("showTitleBar")?.toUpperCase()==="NO")return"status-inset";let transparentTitle=option("transparentTitle")?.toLowerCase();if(transparentTitle&&["always","auto","custom"].includes(transparentTitle))return"overlay"}let overlayParam=config2.overlay?.enabledParam;return overlayParam&&isTruthyParam(params.get(overlayParam))||includeMeta&&document.getElementById("WV.Meta.Nav.HideNavBar")?.getAttribute("value")==="HideStatusBar"?"status":null}catch{return null}},pageRequestsHiddenTitleBar=(href=location.href)=>matchesConfiguredPathname(href,config2.titleBar?.hiddenPathnames??[]),configuredStatusBarBackground=(href=location.href)=>{let colors=config2.titleBar?.statusBarBackgroundColors??{},pathname=businessPathname(href);return pathname===null?null:Object.entries(colors).find(([configuredPathname])=>normalizePathname(configuredPathname)===pathname)?.[1]??configuredHostStyle(href)?.statusBarBackgroundColor??null},pageRequestsHiddenStatusBar=(href=location.href)=>{try{let params=new URL(href,location.href).searchParams;return isTruthyParam(params.get("statusBarHidden"))||isTruthyParam(params.get("hideStatusBar"))?!0:/(?:^|&)showStatusBar=NO(?:&|$)/i.test(params.get("__webview_options__")??"")}catch{return!1}},resolveTitleBarMode=(href,fallback,includeMeta)=>{if(titleBarMode!=="auto")return titleBarMode;if(pageRequestsHiddenStatusBar(href))return"hidden";if(pageRequestsHiddenTitleBar(href))return"status-inset";let requestedMode=pageRequestedTitleBarMode(href,includeMeta);return requestedMode||fallback},resolveStatusBarBackground=(href,mode,navigationBarBackground)=>configuredStatusBarBackground(href)??(mode==="normal"||mode==="status-inset"?navigationBarBackground:"transparent"),ownTitleBarState=()=>{let mode=resolveTitleBarMode(location.href,"normal",!0),background=configuredTitleBarBackground(location.href,titleBarBackground);return{mode,title:document.title||config2.label,titleVisible:titleBarTitleVisible,backVisible:titleBarBackVisible,background,statusBarBackground:resolveStatusBarBackground(location.href,mode,background),textColor:titleBarTextColor}},initialLayerTitleBarState=url2=>{let mode=pageRequestsHiddenStatusBar(url2)?"hidden":pageRequestsHiddenTitleBar(url2)?"status-inset":pageRequestedTitleBarMode(url2,!1)??"normal",background=configuredTitleBarBackground(url2,config2.titleBar?.backgroundColor??"#ffffff");return{mode,title:config2.label,titleVisible:!0,backVisible:!0,background,statusBarBackground:mode==="status-inset"?background:resolveStatusBarBackground(url2,mode,background),textColor:config2.titleBar?.textColor??"#111111"}},parseReportedTitleBarState=value=>{if(!value||typeof value!="object")return null;let state=value;return!["normal","overlay","status","status-inset","hidden"].includes(String(state.mode))||typeof state.title!="string"||typeof state.titleVisible!="boolean"||typeof state.backVisible!="boolean"||typeof state.background!="string"||typeof state.textColor!="string"?null:{...state,statusBarBackground:typeof state.statusBarBackground=="string"?state.statusBarBackground:state.mode==="normal"||state.mode==="status-inset"?String(state.background):"transparent"}},resolvedTitleBarState=layer=>layer?layer.titleBarState??initialLayerTitleBarState(layer.url):presentedRootTitleBarState??ownTitleBarState(),resolvedRootTitleBarState=(fallback=ownTitleBarState())=>presentedRootTitleBarState??(host.getRootFrame()?{...fallback,statusBarBackground:configuredHostStyle(location.href)?.statusBarBackgroundColor??config2.titleBar?.backgroundColor??"#ffffff"}:fallback),renderNavigationBarView=(view,state)=>{let visible=state.mode==="normal"||state.mode==="overlay";view.root.style.display=visible?"block":"none",view.surface.style.visibility=visible?"visible":"hidden",view.surface.style.background=state.mode==="overlay"?"transparent":state.background,view.surface.style.borderBottom="none",view.surface.style.color=state.textColor,view.title.textContent=state.title,view.title.style.display=state.titleVisible?"flex":"none",view.back.style.display=state.backVisible?"flex":"none",view.back.style.color=state.textColor},topFullLayer=()=>{let layers=host.getLayers();for(let index=layers.length-1;index>=0;index-=1)if(!layers[index].overlay&&!layers[index].closing)return layers[index]},activeTitleBarState=()=>{let layer=topFullLayer();return layer?resolvedTitleBarState(layer):resolvedRootTitleBarState()},syncActiveSystemBars=()=>{let state=activeTitleBarState();if(externalDeviceChrome&&isTop&&window.postMessage({source:"mearl-app-profile-runtime",type:"device-chrome-state",state:{statusBarVisible:state.mode!=="hidden",statusBarBackground:state.statusBarBackground,textColor:state.textColor,bridgeConfig:{profile:config2.profile,actions:config2.actions}}},"*"),systemStatusView){let visible=state.mode!=="hidden";systemStatusView.root.style.display=visible?"block":"none",systemStatusView.surface.style.visibility=visible?"visible":"hidden",systemStatusView.surface.style.background=state.statusBarBackground,systemStatusView.surface.style.color=state.textColor}systemBottomRoot&&systemBottomSurface&&(systemBottomRoot.style.display=safeAreaInsets.bottom>0?"block":"none",systemBottomSurface.style.color=state.textColor)},syncLayerViewport=(layer,state)=>{if(layer.overlay)return;if(!simulateSystemBars){layer.frame.style.top="0px",layer.frame.style.height="100%";return}let totalHeight=config2.statusBarHeight+(config2.titleBar?.navigationBarHeight??0),offset=state.mode==="normal"?totalHeight:state.mode==="status-inset"?config2.statusBarHeight:0;layer.frame.style.top=`${offset}px`,layer.frame.style.height=offset>0?`calc(100% - ${offset}px)`:"100%",layer.frame.setAttribute("data-mearl-app-viewport-mode",state.mode),layer.frame.style.setProperty("--mearl-app-navigation-bar-height",`${config2.titleBar?.navigationBarHeight??0}px`),layer.frame.style.opacity=state.mode==="status-inset"&&!layer.titleBarStateReady?"0":"1",layer.titleBarView&&renderNavigationBarView(layer.titleBarView,state),topFullLayer()===layer&&syncActiveSystemBars()},syncRootFrameViewport=state=>{let rootFrame=host.getRootFrame();if(!rootFrame)return;if(!simulateSystemBars){rootFrame.style.top="0px",rootFrame.style.height="100%";return}let totalHeight=config2.statusBarHeight+(config2.titleBar?.navigationBarHeight??0),offset=state.mode==="normal"?totalHeight:state.mode==="status-inset"?config2.statusBarHeight:0;rootFrame.style.top=`${offset}px`,rootFrame.style.height=offset>0?`calc(100% - ${offset}px)`:"100%",rootFrame.setAttribute("data-mearl-app-viewport-mode",state.mode),rootFrame.style.setProperty("--mearl-app-navigation-bar-height",`${config2.titleBar?.navigationBarHeight??0}px`),rootFrame.style.opacity=state.mode==="status-inset"&&presentedRootTitleBarState===null&&!rootFrame.hasAttribute("data-mearl-webview-ready")?"0":"1"},syncSimulatedTitleBar=()=>{let ownState=ownTitleBarState();if(!isTop){if(isContainerFrame){if(!titleBarStateExplicit&&document.readyState==="loading")return;window.top?.postMessage({source:SRC,type:"titleBarState",state:ownState,explicit:titleBarStateExplicit},"*")}return}if(!titleBarRoot||!titleBarSpacer||!rootTitleBarView)return;let rootFrame=host.getRootFrame();!rootFrame&&host.getLayers().length===0&&host.getClosingLayerCount()===0&&(presentedRootTitleBarState=ownState);let state=resolvedRootTitleBarState(ownState);renderNavigationBarView(rootTitleBarView,state);let spacerHeight=state.mode==="normal"?config2.statusBarHeight+(config2.titleBar?.navigationBarHeight??0):state.mode==="status-inset"?config2.statusBarHeight:0;titleBarSpacer.style.display=!rootFrame&&spacerHeight>0?"block":"none",titleBarSpacer.style.height=`${spacerHeight}px`,titleBarSpacer.style.minHeight=`${spacerHeight}px`,syncRootFrameViewport(state),syncActiveSystemBars()},applyNavigationBarState=(api,params)=>{titleBarStateExplicit=!0;let p=params&&typeof params=="object"?params:{},displayValue=p.titlebar_display??p.titlebarDisplay??p.titleBarDisplay,display=typeof displayValue=="string"?displayValue.toLowerCase():"";api==="hideBackButton"&&(titleBarBackVisible=!1),api==="showBackButton"&&(titleBarBackVisible=!0),display==="hide"&&(titleBarMode="status"),display==="show"&&(titleBarMode="normal"),(p.isImmersive===!0||p.isTransparent===!0)&&(titleBarMode="overlay"),p.isImmersive===!1&&p.isTransparent===!1&&(titleBarMode="normal"),typeof p.isTitleVisible=="boolean"&&(titleBarTitleVisible=p.isTitleVisible),typeof p.title=="string"&&(document.title=p.title),typeof p.backgroundColor=="string"&&(titleBarBackground=p.backgroundColor,isTransparentColor(p.backgroundColor)&&(titleBarMode="overlay")),typeof p.barTextStyle=="string"&&(titleBarTextColor=p.barTextStyle==="white"?"#ffffff":"#111111"),syncSimulatedTitleBar()},applyStatusBarState=params=>{titleBarStateExplicit=!0;let p=params&&typeof params=="object"?params:{},style=typeof p.style=="string"?p.style.toLowerCase():"";style&&(titleBarTextColor=style==="white"||style.includes("light")?"#ffffff":"#111111"),syncSimulatedTitleBar()},createNavigationBarView=(placement,onBack)=>{let titleBar=config2.titleBar,root=document.createElement("div");root.setAttribute("data-mearl-app-titlebar",config2.profile),root.setAttribute("data-mearl-titlebar-owner",placement),root.style.cssText=`${placement==="root"?"position:fixed":"position:absolute"};left:0;right:0;top:${config2.statusBarHeight}px;height:${titleBar.navigationBarHeight}px;z-index:${placement==="root"?"2147482900":"2"};overflow:hidden;box-sizing:border-box;font-family:"PingFang SC",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;`;let shadow=root.attachShadow({mode:"open"});shadow.innerHTML=`<style>
|
|
746
1018
|
:host{all:initial}#surface{position:relative;width:100%;height:100%;box-sizing:border-box;color:#0f131a;-webkit-font-smoothing:antialiased;text-rendering:geometricPrecision}
|
|
747
1019
|
#nav{height:100%;position:relative;display:grid;align-items:start}#back{appearance:none;border:0;background:transparent;position:absolute;left:9px;top:0;width:28px;height:42px;display:flex;align-items:center;justify-content:center;padding:0;color:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent}
|
|
748
1020
|
#back svg{width:24px;height:24px;fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}#title{position:absolute;left:80px;right:80px;top:0;height:42px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center;font-size:18px;font-weight:700;line-height:22px}
|
|
749
|
-
</style><div id="surface"><div id="nav"><button id="back" type="button" aria-label="čŋå"><svg viewBox="0 0 28 28" aria-hidden="true"><path d="M19.5 3.5 9 14l10.5 10.5"/></svg></button><div id="title"></div></div></div>`;let surface=shadow.getElementById("surface"),title=shadow.getElementById("title"),back=shadow.getElementById("back");return back.addEventListener("click",onBack),{root,surface,title,back}},createStatusBarView=()=>{let root=document.createElement("div");root.setAttribute("data-mearl-app-statusbar",config2.profile),root.style.cssText=`position:fixed;left:0;right:0;top:0;height:${config2.statusBarHeight}px;z-index:2147483600;overflow:visible;box-sizing:border-box;pointer-events:none;`;let shadow=root.attachShadow({mode:"open"}),deviceModel=config2.globals.__DEVICE_MODEL__??"",
|
|
750
|
-
:host{all:initial}
|
|
751
|
-
</style><div id="surface" data-platform="${config2.platform.toLowerCase()}" data-cutout="${String(hasDynamicIsland)}"><div id="status"><span id="time"></span><span id="device-cutout" aria-hidden="true"></span><span id="indicators" aria-hidden="true"><svg id="signal" viewBox="0 0 18 12"><rect x="0" y="8" width="3" height="4" rx="1"/><rect x="5" y="6" width="3" height="6" rx="1"/><rect x="10" y="3" width="3" height="9" rx="1"/><rect x="15" y="0" width="3" height="12" rx="1"/></svg><svg id="wifi" viewBox="1 3.8 22 17.2"><path d="M2 8.82a15 15 0 0 1 20 0"/><path d="M5 12.859a10 10 0 0 1 14 0"/><path d="M8.5 16.429a5 5 0 0 1 7 0"/><path d="M12 20h.01"/></svg><svg id="battery" viewBox="0 0 28 13"><rect id="battery-outline" x=".65" y=".65" width="23" height="11.7" rx="3.1"/><rect id="battery-level" x="2.35" y="2.35" width="19.6" height="8.3" rx="1.7"/><path id="battery-cap" d="M25 4.1c1.1.35 1.7 1.15 1.7 2.4s-.6 2.05-1.7 2.4z"/></svg></span></div></div>`;let surface=shadow.getElementById("surface"),time3=shadow.getElementById("time"),updateTime=()=>{let now=new Date;time3&&(time3.textContent=`${String(now.getHours()).padStart(2,"0")}:${String(now.getMinutes()).padStart(2,"0")}`)};return updateTime(),{root,surface,timeTimer:window.setInterval(updateTime,3e4)}},install=()=>{let titleBar=config2.titleBar;if(!titleBar||!isContainerFrame||!simulateSystemBars)return;let observeState=()=>{new MutationObserver(syncSimulatedTitleBar).observe(document.head??document.documentElement,{subtree:!0,childList:!0,characterData:!0,attributes:!0,attributeFilter:["content","value"]}),window.addEventListener("popstate",syncSimulatedTitleBar),window.addEventListener("hashchange",syncSimulatedTitleBar),document.readyState==="loading"&&document.addEventListener("DOMContentLoaded",syncSimulatedTitleBar,{once:!0});try{let pushState=history.pushState.bind(history),replaceState=history.replaceState.bind(history);history.pushState=function(...args){pushState(...args),syncSimulatedTitleBar()},history.replaceState=function(...args){replaceState(...args),syncSimulatedTitleBar()}}catch{}};if(!isTop){observeState(),syncSimulatedTitleBar();return}let mount=()=>{if(titleBarRoot||!document.body)return;let totalHeight=config2.statusBarHeight+titleBar.navigationBarHeight,navigationView=createNavigationBarView("root",host.requestNativeBack),statusView=createStatusBarView(),spacer=document.createElement("div");if(spacer.setAttribute("data-mearl-app-titlebar-spacer",""),spacer.style.cssText=`display:block;width:100%;height:${totalHeight}px;min-height:${totalHeight}px;flex:none;`,document.body.insertBefore(spacer,document.body.firstChild),document.body.append(navigationView.root,statusView.root),safeAreaInsets.bottom>0){let bottomRoot=document.createElement("div");bottomRoot.setAttribute("data-mearl-app-system-bottom",config2.profile),bottomRoot.style.cssText=`position:fixed;left:0;right:0;bottom:0;height:${safeAreaInsets.bottom}px;z-index:2147483600;box-sizing:border-box;pointer-events:none;color:#111111;`;let bottomShadow=bottomRoot.attachShadow({mode:"open"});bottomShadow.innerHTML=`<style>:host{all:initial}#surface{appearance:none;border:0;padding:0;width:166px;max-width:100%;height:24px;position:absolute;left:50%;bottom:0;transform:translateX(-50%);display:block;box-sizing:border-box;pointer-events:auto;color:#111;background:transparent;cursor:pointer;-webkit-tap-highlight-color:transparent}#surface:focus-visible{outline:2px solid #2563eb;outline-offset:-2px}#indicator{position:absolute;left:50%;bottom:8px;transform:translateX(-50%);width:134px;height:5px;border-radius:999px;background:currentColor;opacity:.92;transition:transform 120ms ease,opacity 120ms ease}#surface:hover #indicator{opacity:1;transform:translateX(-50%) scaleX(1.05)}#surface[data-platform="android"] #indicator{bottom:6px;width:108px;height:4px;opacity:.82}</style><button id="surface" type="button" aria-label="æåŧæĄĨæ¨Ąæé
įŊŽ" title="æĄĨæ¨Ąæé
įŊŽ" data-platform="${config2.platform.toLowerCase()}"><span id="indicator" aria-hidden="true"></span></button>`,document.body.appendChild(bottomRoot),systemBottomRoot=bottomRoot,systemBottomSurface=bottomShadow.getElementById("surface"),systemBottomSurface?.addEventListener("click",()=>{window.postMessage({source:SRC,type:"showBridgeConfig",profile:config2.profile,actions:config2.actions},"*")})}rootTitleBarView=navigationView,systemStatusView=statusView,titleBarRoot=navigationView.root,titleBarSpacer=spacer,syncSimulatedTitleBar(),observeState()};document.body?mount():document.addEventListener("DOMContentLoaded",mount,{once:!0})},service={initialLayerTitleBarState,resolvedTitleBarState,parseReportedTitleBarState,setPresentedRootTitleBarState:state=>{presentedRootTitleBarState=state,syncSimulatedTitleBar()},markStateExplicit:()=>{titleBarStateExplicit=!0},applyNavigationBarState,applyStatusBarState,createNavigationBarView,destroyNavigationBarView:view=>view?.root.remove(),syncLayerViewport,syncActiveSystemBars,syncSimulatedTitleBar};return install(),service}function installAppProfilePageTransport(config2,environment){let{SRC,TAG,log:log3}=environment,appToast=null,appToastHideTimer=null,appToastRemoveTimer=null;function showAppToast(params){let p=params&&typeof params=="object"?params:{},messageValue=[p.message,p.msg,p.content,p.text].find(value=>typeof value=="string"&&value.trim().length>0);if(typeof messageValue!="string")return"missing message";let durationValue=Number(p.milliseconds??p.duration),duration3=Number.isFinite(durationValue)&&durationValue>0?durationValue:2e3,hideAfter=Math.min(6e4,Math.max(300,Math.round(duration3)));appToastHideTimer!==null&&window.clearTimeout(appToastHideTimer),appToastRemoveTimer!==null&&window.clearTimeout(appToastRemoveTimer);let toast=appToast?.isConnected===!0?appToast:document.createElement("div");return toast!==appToast&&(appToast=toast,toast.setAttribute("data-mearl-app-toast",""),toast.setAttribute("role","status"),toast.setAttribute("aria-live","polite"),Object.assign(toast.style,{position:"fixed",left:"50%",top:"50%",zIndex:"2147483647",maxWidth:"calc(100vw - 64px)",boxSizing:"border-box",padding:"14px 20px",borderRadius:"12px",background:"rgba(20, 20, 20, 0.88)",color:"#ffffff",fontFamily:'-apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif',fontSize:"16px",fontWeight:"400",lineHeight:"24px",textAlign:"center",whiteSpace:"pre-wrap",overflowWrap:"anywhere",pointerEvents:"none",opacity:"0",transform:"translate(-50%, -50%) scale(0.96)",transition:"opacity 180ms ease, transform 180ms ease"}),(document.body??document.documentElement).appendChild(toast)),toast.textContent=messageValue,toast.style.opacity="0",toast.style.transform="translate(-50%, -50%) scale(0.96)",toast.offsetWidth,toast.style.opacity="1",toast.style.transform="translate(-50%, -50%) scale(1)",appToastHideTimer=window.setTimeout(()=>{appToastHideTimer=null,toast.style.opacity="0",toast.style.transform="translate(-50%, -50%) scale(0.96)",appToastRemoveTimer=window.setTimeout(()=>{appToastRemoveTimer=null,appToast===toast&&(appToast=null),toast.remove()},180)},hideAfter),null}let bridgeRequestSeq=0,pendingMtop={},pendingMtopStreams={},pendingUserInfo={};function callMtop(params,succ,fail){let id=++bridgeRequestSeq;pendingMtop[id]={succ,fail};let post=params.post,rawTimeout=params.timeout??params.timer,timeout=typeof rawTimeout=="number"?rawTimeout:typeof rawTimeout=="string"&&rawTimeout.trim()!==""?Number(rawTimeout):void 0,payload={...params,data:params.data!==void 0?params.data:params.param??{},method:params.method??(post===!0||post===1||post==="1"||post==="true"?"POST":"GET"),env:params.env??(/(^|\.)wapa\.taobao\.com$/i.test(location.hostname)?"pre":"online"),...Number.isFinite(timeout)&&{timeout}};window.postMessage({source:SRC,type:"mtop",requestId:id,payload},"*"),log3("mtop äģŖå â",params.api)}function callMtopAsync(params){return new Promise((resolve3,reject)=>callMtop(params,resolve3,reject))}function callMtopStream(params,succ,fail){let sessionId=typeof params.id=="string"?params.id:String(params.id??""),request=params.request&&typeof params.request=="object"?params.request:null;if(!sessionId||!request||typeof request.api!="string"){fail?.("invalid mtop_stream params");return}let requestId=++bridgeRequestSeq;pendingMtopStreams[requestId]={sessionId},window.postMessage({source:SRC,type:"mtopStream",requestId,payload:{...request,timeout:params.timeout,method:params.method??request.method,env:/(^|\.)wapa\.taobao\.com$/i.test(location.hostname)?"pre":"online"}},"*"),succ?.({}),log3("mtop æĩåŧäģŖå â",request.api)}function callUserInfo(fallback,succ){if(fallback.userId){succ?.(fallback);return}let requestId=++bridgeRequestSeq,timer=setTimeout(()=>{let pending=pendingUserInfo[requestId];pending&&(delete pendingUserInfo[requestId],pending.succ?.(pending.fallback))},1e3);pendingUserInfo[requestId]={fallback,succ,timer},window.postMessage({source:SRC,type:"userInfo",requestId},"*")}function emitMtopStreamEvent(sessionId,eventType,data){let detail=data&&typeof data=="object"?{...data,eventType}:{data,eventType};document.dispatchEvent(new CustomEvent(`mtop_stream${sessionId}`,{detail}))}function createUploadId(){try{if(typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch{}return`${Date.now()}-${Math.random().toString(36).slice(2)}`}function pickDirectUploadTarget(response){if(!response||typeof response!="object")return null;let data=response.data;if(data?.success===!1)return null;let result=data?.result,target=Array.isArray(result?.urls)?result.urls[0]:void 0;if(!target||typeof target!="object")return null;let item=target;if(typeof item.put!="string"||!item.put||typeof item.get!="string"||!item.get)return null;let rawHeaders=item.putHeaders&&typeof item.putHeaders=="object"?item.putHeaders:{},putHeaders=Object.fromEntries(Object.entries(rawHeaders).map(([key,value])=>[key,String(value)]));return{put:item.put,get:item.get,putHeaders}}async function uploadImage(file2){let uploader=config2.imagePicker;if(!uploader)throw new Error("åžįä¸äŧ čŊåæĒé
įŊŽ");let env=/(^|\.)wapa\.taobao\.com$/i.test(location.hostname)?"pre":"online",response=await callMtopAsync({api:uploader.api,v:uploader.version,method:"POST",env,timeout:6e4,data:{fcId:uploader.fcId,fcGroup:uploader.fcGroup,fcName:uploader.uploadUrlFunction,fcData:JSON.stringify({requestType:"url",mimes:[file2.type||"image/jpeg"],prefix:uploader.prefix,region:uploader.region,uploadNumber:1}),fcConfig:JSON.stringify({timeout:6e4,disasterRecover:!0})}}),target=pickDirectUploadTarget(response);if(!target)throw new Error("čˇååžįä¸äŧ å°åå¤ąč´Ĩ");let uploadUrl=`${target.put}${target.put.includes("?")?"&":"?"}getAvatar=1`,uploadResponse=await fetch(uploadUrl,{method:"PUT",headers:target.putHeaders,body:file2});if(uploadResponse.status!==200)throw new Error(`åžįį´äŧ å¤ąč´Ĩ: HTTP ${uploadResponse.status}`);return target.get}function openImagePicker(callbackCommandFn){let input=document.createElement("input");input.type="file",input.accept="image/*",input.style.display="none";let settled=!1,finish=()=>{settled=!0,input.remove()};input.addEventListener("cancel",finish,{once:!0}),input.addEventListener("change",()=>{let file2=input.files?.[0];if(!file2){finish();return}if(!file2.type.startsWith("image/")){finish(),console.error(TAG,"äģ
æ¯æéæŠåžįæäģļ");return}uploadImage(file2).then(pic=>{typeof callbackCommandFn=="function"&&callbackCommandFn({pic,uuid:createUploadId(),timeStamp:Date.now()}),log3("åžįéæŠåšļä¸äŧ åŽæ:",pic)}).catch(error48=>console.error(TAG,"åžįä¸äŧ å¤ąč´Ĩ:",error48)).finally(finish)},{once:!0}),(document.body??document.documentElement).appendChild(input),input.click(),window.addEventListener("focus",()=>{setTimeout(()=>{!settled&&!input.files?.length&&finish()},1e3)},{once:!0})}function showPaymentDialog(api,params,succeed,failed){let overlay=document.createElement("div");overlay.setAttribute("data-mearl-payment-dialog","true"),Object.assign(overlay.style,{position:"fixed",inset:"0",zIndex:"2147483647",display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.5)"});let card=document.createElement("div");Object.assign(card.style,{background:"#fff",borderRadius:"12px",padding:"24px",width:"300px",textAlign:"center",fontFamily:"system-ui, sans-serif"});let title=document.createElement("div");Object.assign(title.style,{fontSize:"17px",fontWeight:"600",marginBottom:"8px"}),title.textContent="æ¯äģįĄŽčŽ¤";let desc=document.createElement("div");Object.assign(desc.style,{fontSize:"14px",color:"#666",marginBottom:"20px"}),desc.textContent=`æ¨Ąæ ${api} æ¯äģīŧč¯ˇéæŠæäŊ`;let btnRow=document.createElement("div");Object.assign(btnRow.style,{display:"flex",gap:"12px"});let btnBase=(text,bg,color,action)=>{let btn=document.createElement("button");return btn.textContent=text,btn.setAttribute("data-mearl-action",action),Object.assign(btn.style,{flex:"1",padding:"10px 0",border:"none",borderRadius:"8px",fontSize:"15px",fontWeight:"500",cursor:"pointer",background:bg,color}),btn},confirmBtn=btnBase("åŽææ¯äģ","#1677ff","#fff","payment-confirm"),cancelBtn=btnBase("åæļæ¯äģ","#f5f5f5","#333","payment-cancel"),cleanup=()=>{overlay.remove()};confirmBtn.addEventListener("click",()=>{cleanup(),log3("፿ˇåŽææ¯äģ",api),succeed({ResultStatus:"9000",resultStatus:"9000"})}),cancelBtn.addEventListener("click",()=>{cleanup(),log3("፿ˇåæļæ¯äģ",api),failed({ResultStatus:"6001",resultStatus:"6001"})}),btnRow.appendChild(cancelBtn),btnRow.appendChild(confirmBtn),card.appendChild(title),card.appendChild(desc),card.appendChild(btnRow),overlay.appendChild(card),(document.body??document.documentElement).appendChild(overlay)}function handleMessage(msg){if(msg.source==="mearl-content"&&msg.type==="APP_BRIDGE_MTOP_RESPONSE"){let pending=pendingMtop[msg.requestId];if(!pending)return!0;delete pendingMtop[msg.requestId];let result=msg.result;return result?.success?pending.succ?.(result.response):pending.fail?.(result?.error??"mtop delegate failed"),!0}if(msg.source==="mearl-content"&&msg.type==="APP_BRIDGE_USER_INFO_RESPONSE"){let requestId=msg.requestId,pending=pendingUserInfo[requestId];if(!pending)return!0;delete pendingUserInfo[requestId],clearTimeout(pending.timer);let result=msg.result,response=result?.success&&result.response&&typeof result.response=="object"?result.response:{};return pending.succ?.({...pending.fallback,...response}),!0}if(msg.source==="mearl-content"&&msg.type==="APP_BRIDGE_MTOP_STREAM_EVENT"){let requestId=msg.requestId,pending=pendingMtopStreams[requestId];if(!pending)return!0;let eventType=msg.eventType;return emitMtopStreamEvent(pending.sessionId,eventType,msg.data),(eventType==="onFinish"||eventType==="onError")&&delete pendingMtopStreams[requestId],!0}return!1}return{showAppToast,callMtop,callMtopStream,callUserInfo,openImagePicker,showPaymentDialog,handleMessage}}function installAppProfileBridgeProtocol(config2,environment,host){let{w,SRC,TAG,isTop,log:log3}=environment,{pageTransport,systemBars,requestOpen,requestClose,requestCloseAll,requestContainerData}=host,{showAppToast,callMtop,callMtopStream,callUserInfo,openImagePicker,showPaymentDialog}=pageTransport,{applyNavigationBarState,applyStatusBarState,syncSimulatedTitleBar}=systemBars,NOT_IMPLEMENTED_PAYLOAD=JSON.stringify({ret:["HY_FAILED"],msg:"not implemented"}),FPT_STORAGE_KEY=`__mearl_app_fpt__:${config2.profile}`,CALENDAR_STORAGE_KEY=`__mearl_app_calendar_events__:${config2.profile}`,unsupportedNativeInputNotified=!1,stopNetworkQualityMonitor=null,simulatedPageHidden=!1,simulatedVisibilityInstalled=!1,notificationListeners=new Map,megaListenerSeq=0,megaBroadcastListeners=new Map,megaLifeCycleListeners=new Set,megaPageCloseListeners=new Set,megaSystemBackListener=null,megaKVMutationVersion=0,MEGA_KV_TOTAL_SIZE=5*1024*1024,MEGA_KV_STORAGE_KEY=`__mearl_mega_kv__:${config2.profile}`;function readMegaKVStorage(){let storage=new Map;try{let parsed=JSON.parse(localStorage.getItem(MEGA_KV_STORAGE_KEY)??"{}");if(!parsed||typeof parsed!="object"||Array.isArray(parsed))return storage;for(let[bizId,rawEntries]of Object.entries(parsed)){if(!rawEntries||typeof rawEntries!="object"||Array.isArray(rawEntries))continue;let entries=new Map;for(let[key,value]of Object.entries(rawEntries))typeof value=="string"&&entries.set(key,value);storage.set(bizId,entries)}}catch{}return storage}let megaKVStorage=readMegaKVStorage();function megaKVSnapshot(){let snapshot={};for(let[bizId,values]of megaKVStorage)snapshot[bizId]=Object.fromEntries(values);return snapshot}function persistMegaKVStorage(){try{localStorage.setItem(MEGA_KV_STORAGE_KEY,JSON.stringify(megaKVSnapshot()))}catch{}}function replaceMegaKVStorage(value){if(!(!value||typeof value!="object"||Array.isArray(value))){megaKVStorage.clear();for(let[bizId,rawEntries]of Object.entries(value)){if(!rawEntries||typeof rawEntries!="object"||Array.isArray(rawEntries))continue;let entries=new Map;for(let[key,entryValue]of Object.entries(rawEntries))typeof entryValue=="string"&&entries.set(key,entryValue);megaKVStorage.set(bizId,entries)}persistMegaKVStorage()}}function applyMegaKVMutation(payload){let operation=typeof payload.operation=="string"?payload.operation:"",bizId=typeof payload.bizId=="string"?payload.bizId:"",key=typeof payload.key=="string"?payload.key:"";if(bizId){if(operation==="set"&&key&&typeof payload.value=="string"){let entries=megaKVStorage.get(bizId)??new Map;entries.set(key,payload.value),megaKVStorage.set(bizId,entries)}else if(operation==="remove"&&key){let entries=megaKVStorage.get(bizId);entries?.delete(key),entries?.size===0&&megaKVStorage.delete(bizId)}else if(operation==="clear")megaKVStorage.delete(bizId);else return;megaKVMutationVersion+=1,persistMegaKVStorage()}}function emitMegaCallback(callback,value){callback&&setTimeout(()=>callback(value),0)}function megaBroadcastBizId(value){return typeof value=="string"&&value?value:"__MEGA_GLOBAL_MESSAGE__"}function dispatchMegaBroadcast(payload){let bizId=megaBroadcastBizId(payload.bizId),eventName=typeof payload.eventName=="string"?payload.eventName:"";if(eventName)for(let listener of Array.from(megaBroadcastListeners.values()))listener.bizId!==bizId||listener.eventName!==eventName||(listener.once&&megaBroadcastListeners.delete(listener.id),emitMegaCallback(listener.callback,{statusCode:1,type:"onEvent",data:{detail:payload.detail}}),listener.once&&emitMegaCallback(listener.callback,{statusCode:99,type:"finish"}))}let documentPrototype=typeof Document=="function"?Document.prototype:null,nativeHiddenDescriptor=documentPrototype?Object.getOwnPropertyDescriptor(documentPrototype,"hidden"):void 0,nativeVisibilityDescriptor=documentPrototype?Object.getOwnPropertyDescriptor(documentPrototype,"visibilityState"):void 0;function installSimulatedVisibilityState(){if(!simulatedVisibilityInstalled){simulatedVisibilityInstalled=!0;try{Object.defineProperty(document,"hidden",{configurable:!0,get:()=>simulatedPageHidden||!!(nativeHiddenDescriptor?.get?.call(document)??!1)}),Object.defineProperty(document,"visibilityState",{configurable:!0,get:()=>simulatedPageHidden?"hidden":nativeVisibilityDescriptor?.get?.call(document)??"visible"})}catch{}}}function dispatchPageTransitionEvent(type){try{let event=typeof PageTransitionEvent=="function"?new PageTransitionEvent(type,{persisted:!1}):new Event(type);window.dispatchEvent(event)}catch{}}function dispatchActiveEvents(){for(let name of config2.activeEvents)try{document.dispatchEvent(new Event(name))}catch{}}function handlePageVisibility(hidden){if(hidden===simulatedPageHidden)return;installSimulatedVisibilityState(),simulatedPageHidden=hidden;let lifeCycleType=hidden?"onPageDisappear":"onPageAppear";for(let callback of megaLifeCycleListeners)emitMegaCallback(callback,{statusCode:1,type:lifeCycleType,data:{pageId:location.href}});try{document.dispatchEvent(new Event("visibilitychange"))}catch{}if(hidden){try{window.dispatchEvent(new Event("blur"))}catch{}dispatchPageTransitionEvent("pagehide");return}dispatchPageTransitionEvent("pageshow");try{window.dispatchEvent(new Event("focus"))}catch{}dispatchActiveEvents()}function resolveWindowFunction(path23){let parts=path23.split(".").filter(Boolean),owner=w;for(let index=0;index<parts.length-1;index+=1){let next=owner[parts[index]];if(!next||typeof next!="object")return null;owner=next}let fn=owner[parts[parts.length-1]];return typeof fn=="function"?fn.bind(owner):null}function handleNativeBack(){let megaHandled=!1;for(let callback of megaPageCloseListeners)megaHandled=!0,emitMegaCallback(callback,{statusCode:1,type:"onClose",data:{}});if(megaSystemBackListener&&(megaHandled=!0,emitMegaCallback(megaSystemBackListener,{statusCode:1,type:"onSuccess",data:{}})),megaHandled)return!0;let nativeBack=config2.nativeBack;if(!nativeBack)return!1;if(nativeBack.handler){let handler=resolveWindowFunction(nativeBack.handler);if(!handler)return!1;try{return handler(),!0}catch{return!1}}let controlled=!1;if(nativeBack.controlFunction){let control=resolveWindowFunction(nativeBack.controlFunction);if(!control)return!1;try{controlled=control()===!0}catch{return!1}if(!controlled)return!1}if(!nativeBack.event)return controlled;try{let event=new Event(nativeBack.event,{cancelable:!0});return document.dispatchEvent(event),controlled||event.defaultPrevented}catch{return controlled}}function handleAppMessage(message){if(!message||typeof message!="object")return;let payload=message;if(payload.kind==="megaBroadcast"){dispatchMegaBroadcast(payload);return}if(payload.kind==="megaKVStorage"){applyMegaKVMutation(payload);return}if(payload.kind==="legacyBroadcast"&&typeof payload.instanceId=="string"){try{let event=new CustomEvent(`Broadcast.Message.${payload.instanceId}`,{detail:payload.message});Object.defineProperty(event,"param",{configurable:!0,value:payload.message}),document.dispatchEvent(event)}catch{}return}if(payload.kind==="notification"&&typeof payload.name=="string"){let listener=notificationListeners.get(payload.name);listener&&setTimeout(()=>listener(payload.data),0);return}if(!(payload.kind!=="message"||!config2.messageEvent))try{document.dispatchEvent(new CustomEvent(config2.messageEvent,{detail:{data:payload.data}}))}catch{}}function sendAppMessage(message){if(isTop){handleAppMessage(message);return}window.top?.postMessage({source:SRC,type:"appMessageToOpener",message},"*")}function applyRuntimeResponses(responses){let current=config2.actions.responses??{};for(let[api,response]of Object.entries(responses))!response||typeof response!="object"||Array.isArray(response)||(current[api]=response);config2.actions.responses=current}function parseFpt(value){let entries=[],normalized=value.trim();if(!normalized)return entries;let pattern=/([0-9A-Za-z._-]+)\(([0-9A-Za-z._-]+)\)/g,consumed="";for(let match of normalized.matchAll(pattern))consumed+=match[0],entries.push([match[1],match[2]]);return consumed===normalized?entries:[]}function setFptEntry(entries,key,value){entries.delete(key),entries.set(key,value)}function readInitialFptEntries(){let entries=new Map;try{for(let[key,value]of parseFpt(sessionStorage.getItem(FPT_STORAGE_KEY)??""))setFptEntry(entries,key,value)}catch{}try{let currentFpt=new URL(location.href).searchParams.get("fpt")??"";for(let[key,value]of parseFpt(currentFpt))setFptEntry(entries,key,value)}catch{}return entries}let fptEntries=readInitialFptEntries();function serializeFpt(entries){return Array.from(entries,([key,value])=>`${key}(${value})`).join("")}function persistFpt(){try{let value=serializeFpt(fptEntries);value?sessionStorage.setItem(FPT_STORAGE_KEY,value):sessionStorage.removeItem(FPT_STORAGE_KEY)}catch{}}function decorateUrlWithFpt(rawUrl){if(fptEntries.size===0)return rawUrl;try{let url2=new URL(rawUrl,location.href);if(url2.protocol!=="http:"&&url2.protocol!=="https:")return rawUrl;let merged=new Map(fptEntries);for(let[key,value]of parseFpt(url2.searchParams.get("fpt")??""))setFptEntry(merged,key,value);return url2.searchParams.set("fpt",serializeFpt(merged)),url2.href}catch{return rawUrl}}function classify(api){let a=config2.actions;return a.open.includes(api)?"open":a.close.includes(api)?"close":a.title.includes(api)?"title":a.navigationBar?.includes(api)?"navigationBar":a.statusBar?.includes(api)?"statusBar":a.systemInfo.includes(api)?"systemInfo":a.mtop.includes(api)?"mtop":a.kvGet?.includes(api)?"kvGet":a.kvSet?.includes(api)?"kvSet":a.kvDelete?.includes(api)?"kvDelete":a.pageContext?.includes(api)?"pageContext":a.responses&&Object.prototype.hasOwnProperty.call(a.responses,api)?"response":a.behaviors&&Object.prototype.hasOwnProperty.call(a.behaviors,api)?a.behaviors[api]:a.noop.includes(api)?"noop":"unknown"}function pickUrl(params){if(!params||typeof params!="object")return null;let p=params,candidates=[p.url,p.data?.url,p.param?.url,p.value?.params?.url];for(let c of candidates)if(typeof c=="string"&&c)return c;return null}function pickCloseData(params){if(params&&typeof params=="object"){let p=params;if("data"in p&&p.data!==void 0)return p.data;if(Object.keys(p).length>0)return p}}function decodeCookieValue2(raw){let value=raw;for(let i=0;i<2;i+=1)try{let decoded=decodeURIComponent(value);if(decoded===value)break;value=decoded}catch{break}return value.replace(/\\u([0-9a-f]{4})/gi,(_match,hex3)=>String.fromCharCode(Number.parseInt(hex3,16)))}function readCookie(name){let prefix=`${name}=`,pair=document.cookie.split(";").map(value=>value.trim()).find(value=>value.startsWith(prefix));return pair?decodeCookieValue2(pair.slice(prefix.length)):""}function readUserCookie(name){let pageUserCookie=w.userCookie;if(!pageUserCookie||typeof pageUserCookie!="object")return"";let value=pageUserCookie[name];return typeof value=="string"?decodeCookieValue2(value):""}function readFirstUserCookie(names){for(let name of names){let value=readCookie(name)||readUserCookie(name);if(value&&value!=="null")return value}return""}let cbSeq=0,callbacks={};function stashCallback(fn){if(typeof fn!="function")return 0;let id=++cbSeq;return callbacks[id]=fn,id}function extractQuery(url2,param){let q=url2.indexOf("?");if(q===-1)return null;for(let pair of url2.slice(q+1).split("&")){let eq=pair.indexOf("=");if(eq>0&&pair.slice(0,eq)===param)return pair.slice(eq+1)}return null}function resolveSchemeValue(raw,depth){if(depth>3)return null;let value=raw;try{value=decodeURIComponent(raw)}catch{}if(value.startsWith("{"))try{let found=pickUrl(JSON.parse(value));if(!found)return null;value=found}catch{return null}if(/^https?:/i.test(value))return value;if(/^[a-z][a-z0-9+.-]*:/i.test(value))return mapScheme(value,depth+1);let nestedUrl=extractQuery(value,"url");return nestedUrl?resolveSchemeValue(nestedUrl,depth+1):null}function mapScheme(url2,depth=0){if(depth>3)return null;let lower=url2.toLowerCase();for(let rule of config2.schemes){if(!lower.startsWith(rule.match))continue;if(rule.targetPath){let suffix=url2.slice(rule.match.length);if(suffix&&!suffix.startsWith("?")&&!suffix.startsWith("#"))continue;try{let source=new URL(url2),origin=location.origin;if(rule.targetHostPrefix){let hostname3=location.hostname.toLowerCase(),domainSuffix=hostname3==="wapa.taobao.com"||hostname3.endsWith(".wapa.taobao.com")?"wapa.taobao.com":hostname3==="m.taobao.com"||hostname3.endsWith(".m.taobao.com")?"m.taobao.com":"";domainSuffix&&(origin=`https://${rule.targetHostPrefix}.${domainSuffix}`)}let target=new URL(rule.targetPath,`${origin}/`);target.search=source.search,target.hash=source.hash;for(let[key,value]of Object.entries(rule.targetParams??{}))target.searchParams.has(key)||target.searchParams.set(key,value);return target.href}catch{return null}}if(!rule.param)continue;let raw=extractQuery(url2,rule.param);return raw?resolveSchemeValue(raw,depth):null}return null}function matchesImagePickerScheme(url2){let lower=url2.toLowerCase();return config2.imagePicker?.schemes.some(scheme=>lower.startsWith(scheme))===!0}function handleMaybeScheme(url2){if(typeof url2!="string"||!url2||!/^[a-z][a-z0-9+.-]*:/i.test(url2)||/^(https?|about|blob|data|javascript):/i.test(url2))return!1;let mapped=mapScheme(url2);return mapped?(log3("scheme æ å°ä¸ē H5 open:",url2,"â",mapped),requestOpen(decorateUrlWithFpt(mapped),0,!1)):log3("å¤é¨ scheme 厞æĻæĒīŧįæē襨į°ä¸ēå¤į̝īŧ:",url2),!0}function handleResume(msg){let{data,storageId,callbackId,final,gotoEvent}=msg;if(gotoEvent&&dispatchGotoEvent(data),callbackId&&callbacks[callbackId]){try{callbacks[callbackId]({backdata:data})}catch(e){console.error(TAG,"callbackCommand æ§čĄå¤ąč´Ĩ",e)}final&&delete callbacks[callbackId]}if(data&&typeof data=="object"&&storageId)try{let d={...data};d.__$data=!0,d.__$storageId=String(storageId),localStorage.setItem("XPI_BACK_LISTENER_DATA_STORAGE",JSON.stringify(d))}catch{}simulatedPageHidden?handlePageVisibility(!1):dispatchActiveEvents()}function dispatchGotoEvent(data){if(data!==void 0)try{document.dispatchEvent(new CustomEvent("WV.GotoEvent",{detail:{data}}))}catch{}}function sendUserTrack(params){if(!params||typeof params!="object")return;let p=params,logkey=typeof p.logkey=="string"?p.logkey:"",gmkey=typeof p.gmkey=="string"?p.gmkey:typeof p.event=="string"?p.event:"",gokey=typeof p.gokey=="string"?p.gokey:"";if(!/^\/[0-9A-Za-z._/-]+$/.test(logkey)||!/^[0-9A-Za-z_-]+$/.test(gmkey))return;let pageWindow=w,aplus=pageWindow.goldlog??pageWindow.aplus;if(typeof aplus?.send!="function")return;let configuredHost=aplus.getMetaInfo?.("aplus-rhost-g"),host2=(typeof configuredHost=="string"?configuredHost:"gm.mmstat.com").replace(/^https?:\/\//i,"").replace(/^\/\//,"").split("/")[0];if(!(!host2||!/^[0-9A-Za-z.-]+$/.test(host2)))try{aplus.send(`//${host2}${logkey}`,`gmkey=${encodeURIComponent(gmkey)}&gokey=${gokey}&ts=${Date.now()}`,"GET")}catch{}}function readNetworkState(){let connection=navigator.connection;return navigator.onLine?connection?.type==="wifi"?"wifi":connection?.effectiveType??"unknown":"fail"}function networkTypeNumber(state){return{wifi:2,"slow-2g":3,"2g":3,"3g":4,"4g":5,"5g":6,fail:7}[state]??0}function calendarTimestamp(value){if(typeof value=="number"&&Number.isFinite(value))return value;if(typeof value!="string"||!value.trim())return null;let numeric=Number(value);if(Number.isFinite(numeric)&&numeric>0)return numeric;let parsed=Date.parse(value);return Number.isFinite(parsed)?parsed:null}function calendarEventFromParams(params){let p=params&&typeof params=="object"?params:{},stringValue=(...values)=>values.find(value=>typeof value=="string")??"";return{title:stringValue(p.calendar_title,p.title),startTime:calendarTimestamp(p.calendar_start_ms??p.start_time??p.calendar_start_datetime),endTime:calendarTimestamp(p.calendar_end_ms??p.end_time??p.calendar_end_datetime),url:stringValue(p.calendar_url,p.url),note:stringValue(p.calendar_note,p.note),location:stringValue(p.calendar_location,p.location)}}function readCalendarEvents(){try{let parsed=JSON.parse(localStorage.getItem(CALENDAR_STORAGE_KEY)??"[]");return Array.isArray(parsed)?parsed.filter(event=>event!==null&&typeof event=="object"&&typeof event.title=="string"):[]}catch{return[]}}function writeCalendarEvents(events){try{return localStorage.setItem(CALENDAR_STORAGE_KEY,JSON.stringify(events)),!0}catch{return!1}}function sameCalendarEvent(stored,candidate){return candidate.url?stored.url===candidate.url:!!candidate.title&&stored.title===candidate.title&&(candidate.startTime===null||stored.startTime===candidate.startTime)&&(candidate.endTime===null||stored.endTime===candidate.endTime)}function calendarEventResponse(event){return{title:event.title,start_time:event.startTime,end_time:event.endTime,url:event.url,note:event.note,location:event.location}}function dispatch(api,params,onSuccess,onFailure,callbackCommandFn){let succeed=value=>{onSuccess&&setTimeout(()=>onSuccess(value),0)},failed=reason=>{onFailure&&setTimeout(()=>onFailure(reason),0)},kind=classify(api),silent=config2.actions.silent?.includes(api)===!0;if(silent||log3("æĄĨč°į¨",api,`(${kind})`,params??""),kind==="open"||kind==="navigate"){let p=params&&typeof params=="object"?params:{},navigationData=p.data&&typeof p.data=="object"?p.data:void 0;if(kind==="navigate"&&navigationData?.type==="back"){isTop?requestCloseAll(navigationData.data,!0)||dispatchGotoEvent(navigationData.data):window.top?.postMessage({source:SRC,type:"closeAll",data:navigationData.data,gotoEvent:!0},"*"),succeed({});return}let url2=pickUrl(params);if(!url2){failed("missing url");return}if(matchesImagePickerScheme(url2)){openImagePicker(callbackCommandFn),succeed({});return}let wd=p.useWebdialog===!0||p.useWebdialog==="true"||p.useWebdialog===1||p.useWebdialog==="1";requestOpen(decorateUrlWithFpt(url2),stashCallback(callbackCommandFn),wd,p),succeed({});return}if(kind==="closeAll"){isTop?requestCloseAll(void 0):window.top?.postMessage({source:SRC,type:"closeAll"},"*"),succeed({});return}if(kind==="closeBackData"){let p=params&&typeof params=="object"?params:{};requestClose(Object.prototype.hasOwnProperty.call(p,"backdata")?p.backdata:pickCloseData(p)),succeed({});return}if(kind==="close"){requestClose(pickCloseData(params)),succeed({});return}if(kind==="postMessage"){let p=params&&typeof params=="object"?params:{};sendAppMessage({kind:"message",data:p.data??p}),succeed({});return}if(kind==="notifySubscribe"){let p=params&&typeof params=="object"?params:{};if(typeof p.name!="string"||!p.name){failed("missing notification name");return}onSuccess&¬ificationListeners.set(p.name,onSuccess);return}if(kind==="notifyUnsubscribe"){let p=params&&typeof params=="object"?params:{};typeof p.name=="string"&¬ificationListeners.delete(p.name),succeed({});return}if(kind==="notifyPost"){let p=params&&typeof params=="object"?params:{};if(typeof p.name!="string"||!p.name){failed("missing notification name");return}sendAppMessage({kind:"notification",name:p.name,data:p.data}),succeed({});return}if(kind==="sharedFileRead"||kind==="sharedFileWrite"||kind==="sharedDataGet"||kind==="sharedDataSet"){requestContainerData(kind,params&&typeof params=="object"?params:{},succeed,failed);return}if(kind==="legacyBroadcastCreate"||kind==="legacyBroadcastPost"||kind==="legacyBroadcastClose"){requestContainerData(kind,params&&typeof params=="object"?params:{},succeed,failed);return}if(kind==="title"){let title=params&&typeof params=="object"?params.title??params.name:void 0;if(typeof title=="string"&&title){systemBars.markStateExplicit();try{document.title=title,syncSimulatedTitleBar()}catch{}isTop||window.top?.postMessage({source:SRC,type:"title",title},"*")}succeed({});return}if(kind==="navigationBar"){applyNavigationBarState(api,params),succeed({});return}if(kind==="statusBar"){applyStatusBarState(params),succeed({});return}if(kind==="systemInfo"){let model=config2.globals.__DEVICE_MODEL__||"iPhone";succeed({language:config2.language,model,systemVersion:config2.systemVersion,statusBarHeight:config2.statusBarHeight,platform:config2.platform,brand:config2.platform==="iOS"?"Apple":"Android",client_version:config2.globals.__APP_VERSION__??"",client_type:config2.clientType});return}if(kind==="mtop"){callMtop(params??{},onSuccess,onFailure);return}if(kind==="mtopStream"){callMtopStream(params??{},succeed,failed);return}if(kind==="kvGet"||kind==="kvSet"||kind==="kvDelete"){let p=params&&typeof params=="object"?params:{},key=typeof p.key=="string"?p.key:"";if(!key){failed("missing key");return}try{let storageKey=`__mearl_app_kv__:${key}`;if(kind==="kvGet"){let stored=localStorage.getItem(storageKey);stored!==null?succeed(stored):failed(JSON.stringify({ret:["HY_FAILED"],msg:"key not found"}))}else if(kind==="kvSet"){let value=typeof p.value=="string"?p.value:p.value===void 0?"":JSON.stringify(p.value);localStorage.setItem(storageKey,value),succeed({})}else localStorage.removeItem(storageKey),succeed({})}catch{failed(JSON.stringify({ret:["HY_FAILED"],msg:"kv storage unavailable"}))}return}if(kind==="pageContext"){succeed({pageContext:void 0});return}if(kind==="memoryGet"||kind==="memorySet"||kind==="memoryDelete"){let p=params&&typeof params=="object"?params:{},key=typeof p.key=="string"?p.key:"";if(!key){failed({error_message:"missing key"});return}try{let storageKey=`__mearl_app_memory__:${key}`;if(kind==="memoryGet"){let value=sessionStorage.getItem(storageKey);succeed(value===null?{}:{value})}else if(kind==="memorySet"){let value=typeof p.value=="string"?p.value:p.value===void 0?"":JSON.stringify(p.value);sessionStorage.setItem(storageKey,value),succeed({key,success:!0})}else sessionStorage.removeItem(storageKey),succeed({key,success:!0})}catch{failed({error_message:"memory cache unavailable"})}return}if(kind==="availabilityMap"){let p=params&&typeof params=="object"?params:{},channels=Array.isArray(p.data)?p.data.filter(value=>typeof value=="string"):[];succeed({res:"success",data:Object.fromEntries(channels.map(channel=>[channel,!1]))});return}if(kind==="userInfo"){let userId=readFirstUserCookie(["unb"]),userName=readFirstUserCookie(["_w_tb_nick","_nk_","snk","tracknick"]);callUserInfo({...userId&&{userId},...userName&&{userName}},succeed);return}if(kind==="networkInfo"){let state=readNetworkState();if(api==="WVNetwork.getNetworkType"){succeed({type:{wifi:"WIFI","slow-2g":"2G","2g":"2G","3g":"3G","4g":"4G"}[state]??"UNKNOWN"});return}if(config2.profile==="alipay"||config2.profile==="koubei"){succeed({networkAvailable:state!=="fail",networkType:{wifi:"WIFI","slow-2g":"2G","2g":"2G","3g":"3G","4g":"4G",fail:"NOTREACHABLE"}[state]??"UNKNOWN"});return}let type=networkTypeNumber(state);succeed({type,state:state==="slow-2g"?"2g":state});return}if(kind==="networkQualityMonitor"){let p=params&&typeof params=="object"?params:{},action=typeof p.action=="string"?p.action:"";if(action==="add_notify_network_quality"){if(!stopNetworkQualityMonitor){let notify=()=>{try{document.dispatchEvent(new CustomEvent("WV.NETWORK_TYPE_CHANGED",{detail:{new_network_type:networkTypeNumber(readNetworkState())}}))}catch{}},connection=navigator.connection;window.addEventListener("online",notify),window.addEventListener("offline",notify),connection?.addEventListener?.("change",notify),stopNetworkQualityMonitor=()=>{window.removeEventListener("online",notify),window.removeEventListener("offline",notify),connection?.removeEventListener?.("change",notify)}}succeed({});return}if(action==="remove_notify_network_quality"){stopNetworkQualityMonitor?.(),stopNetworkQualityMonitor=null,succeed({});return}failed({error_message:"unsupported network quality monitor action"});return}if(kind==="beaconRequest"){let url2=pickUrl(params);if(!url2){failed({error_message:"missing url"});return}try{let resolved=new URL(url2,location.href);if(resolved.protocol!=="http:"&&resolved.protocol!=="https:"){failed({error_message:"unsupported request protocol"});return}let image=new Image;image.referrerPolicy="no-referrer-when-downgrade",image.src=resolved.href,succeed({})}catch{failed({error_message:"invalid url"})}return}if(kind==="calendar"){let p=params&&typeof params=="object"?params:{},events=readCalendarEvents();if(api==="store_calendar_event"){let event=calendarEventFromParams(p);if(!event.title||event.startTime===null){failed({error_message:"calendar title and start time are required"});return}let next=events.filter(stored=>!sameCalendarEvent(stored,event));if(next.push(event),!writeCalendarEvents(next)){failed({error_message:"calendar storage unavailable"});return}succeed({success:!0});return}if(api==="remove_calendar_event"){let candidate=calendarEventFromParams(p),next=events.filter(stored=>!sameCalendarEvent(stored,candidate));if(!writeCalendarEvents(next)){failed({error_message:"calendar storage unavailable"});return}succeed({success:!0,removed:events.length-next.length});return}if(api==="check_batch_calendar"){let batch=Array.isArray(p.batch)?p.batch:[];succeed({batch:batch.map(item=>{let candidate=calendarEventFromParams(item);return{...item&&typeof item=="object"?item:{},success:events.some(stored=>sameCalendarEvent(stored,candidate))}})});return}let urls=Array.isArray(p.urls)?p.urls.filter(value=>typeof value=="string"):typeof p.url=="string"?[p.url]:[],titles=Array.isArray(p.calendar_titles)?p.calendar_titles.filter(value=>typeof value=="string"):typeof p.calendar_title=="string"?[p.calendar_title]:[],matched=events.filter(event=>(urls.length===0||urls.includes(event.url))&&(titles.length===0||titles.includes(event.title)));succeed({events:matched.map(calendarEventResponse)});return}if(kind==="geolocation"){if(!navigator.geolocation){failed({errorCode:2,errorMsg:"geolocation unavailable"});return}let locate=()=>navigator.geolocation.getCurrentPosition(position=>{let{latitude,longitude,accuracy,altitude,altitudeAccuracy,heading,speed}=position.coords;succeed({latitude,longitude,accuracy,altitude,altitudeAccuracy,heading,speed,timestamp:position.timestamp})},error48=>failed({errorCode:error48.code,errorMsg:error48.message}),{enableHighAccuracy:!1,timeout:1e4,maximumAge:3e5});navigator.permissions?.query?navigator.permissions.query({name:"geolocation"}).then(status=>{status.state==="granted"?locate():failed({errorCode:1,errorMsg:"location permission not granted"})}).catch(locate):locate();return}if(kind==="permission"){let p=params&&typeof params=="object"?params:{},action=typeof p.action=="string"?p.action:"",permission=typeof p.permission=="string"?p.permission:"",permissionFailed=message=>failed({error_code:-1,error_message:message});if(permission==="album"||permission==="MODIFY_AUDIO_SETTINGS"){action==="check"||action==="request"?succeed({}):permissionFailed("unsupported permission action");return}let browserPermission=permission==="mic"?"microphone":permission==="camera"?"camera":permission==="lbs"?"geolocation":"";if(!browserPermission){permissionFailed("unsupported permission");return}if(action==="check"&&navigator.permissions?.query){navigator.permissions.query({name:browserPermission}).then(status=>{status.state==="granted"?succeed({}):permissionFailed("permission not granted")}).catch(()=>permissionFailed("permission check failed"));return}if(action==="request"&&(permission==="mic"||permission==="camera")){if(!navigator.mediaDevices?.getUserMedia){permissionFailed("media permission unavailable");return}navigator.mediaDevices.getUserMedia({audio:permission==="mic",video:permission==="camera"}).then(stream=>{for(let track of stream.getTracks())track.stop();succeed({})}).catch(()=>permissionFailed("permission denied"));return}if(action==="request"&&permission==="lbs"&&navigator.geolocation){navigator.geolocation.getCurrentPosition(()=>succeed({}),()=>permissionFailed("permission denied"),{timeout:1e4});return}permissionFailed("unsupported permission action");return}if(kind==="prefetch"){let p=params&&typeof params=="object"?params:{},url2=typeof p.url=="string"?p.url:"";if(!url2){failed({code:-1,errorMsg:"url is empty"});return}let resolvedUrl;try{resolvedUrl=new URL(url2,location.href).href}catch{failed({code:-1,errorMsg:"invalid url"});return}if(!Array.from(document.querySelectorAll('link[rel="prefetch"]')).some(link=>link.href===resolvedUrl)){let link=document.createElement("link");link.rel="prefetch",link.href=url2,(document.head??document.documentElement).appendChild(link)}succeed({});return}if(kind==="fptTrack"){let p=params&&typeof params=="object"?params:{},action=typeof p.action=="string"?p.action:"",actionParams=p.params&&typeof p.params=="object"?p.params:{},key=typeof actionParams.key=="string"?actionParams.key:"";if(action==="setFpt"){let value=typeof actionParams.value=="string"?actionParams.value:"";if(!key||!value||!/^[0-9A-Za-z._-]+$/.test(key)||!/^[0-9A-Za-z._-]+$/.test(value)||`${key}(${value})`.length>100){failed({error_message:"invalid fpt key or value"});return}setFptEntry(fptEntries,key,value),persistFpt()}else action==="deleteFpt"&&key&&(fptEntries.delete(key),persistFpt());succeed({});return}if(kind==="previewFile"){let p=params&&typeof params=="object"?params:{},fileUrl=typeof p.file_url=="string"?p.file_url:"",remoteUrl=typeof p.file_remote_url=="string"?p.file_remote_url:"",url2=(fileUrl.startsWith("http")?fileUrl:remoteUrl)||fileUrl||remoteUrl;url2?(requestOpen(url2,0,!1),succeed({})):failed({code:-1,errorMsg:"file_url is empty"});return}if(kind==="toast"){let error48=showAppToast(params);error48?failed({error_message:error48}):succeed({});return}if(kind==="unsupportedNativeInput"){let containerType="";try{containerType=new URL(location.href).searchParams.get("containerType")??""}catch{}!unsupportedNativeInputNotified&&(containerType==="h5_dx"||containerType==="flutter_h5")&&(unsupportedNativeInputNotified=!0,showAppToast({message:"åŊåéĄĩéĸäŊŋį¨åįčžå
ĨæĄīŧ蝎į§ģé¤ URL ä¸į containerType åæ°äģĨæŖå¸¸æäŊ",milliseconds:4e3})),succeed({});return}if(kind==="payment"){log3("æĄĨč°į¨æ¯äģīŧįåž
፿ˇįĄŽčޤ",api,params),showPaymentDialog(api,params,succeed,failed);return}if(kind==="userTrack"){sendUserTrack(params),succeed({});return}if(kind==="response"){succeed(config2.actions.responses?.[api]);return}if(kind==="noop"){succeed({});return}silent||log3("æĒčĻįæĄĨæšæŗīŧåč° failureīŧéĄĩéĸåēå°čĩ° H5 å
åēīŧ:",api),failed(NOT_IMPLEMENTED_PAYLOAD)}let MEGA_SUPPORTED_APIS={stdPop:["showWeex2","showWeex","showH5","changeSize","close"],broadcast:["addEventListener","dispatchEvent","removeEventListener"],kvStorage:["setItem","getItem","removeItem","getAllKeys","clear","getCurrentInfo","getCurrentInfoAndKeys"],LifeCycle:["addPageLifeCycleListener","removePageLifeCycleListener"],Container:["interceptPageClose","disableInterceptPageClose"],navigator:["openURL","close","replace","setSystemBackBlockListener","removeSystemBackBlockListener"],NavBar:["setTitle"],Router:["popPage"]};function isMegaApiSupported(ability,api){return typeof ability=="string"&&typeof api=="string"&&MEGA_SUPPORTED_APIS[ability]?.includes(api)===!0}function megaParams(value){return value&&typeof value=="object"&&!Array.isArray(value)?value:{}}function megaError(callback,statusCode,message){emitMegaCallback(callback,{statusCode,type:"result",data:{errorMessage:typeof message=="string"?message:String(message??"")}})}function cloneMegaDetail(value){if(value===void 0)return{success:!0,value:void 0};try{return{success:!0,value:JSON.parse(JSON.stringify(value))}}catch{return{success:!1}}}function megaSuccess(data={}){return{statusCode:0,type:"result",data}}function megaFailure(message){return{statusCode:500,type:"result",data:{errorMessage:message}}}function megaKVParams(params){return{bizId:typeof params.bizID=="string"?params.bizID:typeof params.bizId=="string"?params.bizId:"",key:typeof params.key=="string"?params.key:"",value:typeof params.value=="string"?params.value:null}}function megaStringByteLength(value){try{return typeof TextEncoder=="function"?new TextEncoder().encode(value).length:value.length}catch{return value.length}}function megaKVUsedSize(entries){let size=0;for(let value of entries.values())size+=megaStringByteLength(value);return size}function reportMegaKVMutation(operation,bizId,key="",value,onSuccess,onFailure){requestContainerData("megaKVMutation",{operation,bizId,key,...value===void 0?{}:{value}},()=>onSuccess?.(),reason=>{log3("KVStorage 厚å¨åæĨå¤ąč´Ĩ:",reason),onFailure?.(reason)})}function completeMegaKVMutation(operation,bizId,key,value,synchronous,callback){let result=megaSuccess();return reportMegaKVMutation(operation,bizId,key,value,synchronous?void 0:()=>emitMegaCallback(callback,result),synchronous?void 0:reason=>emitMegaCallback(callback,megaFailure(String(reason??"container sync failed")))),synchronous?result:null}function executeMegaKVStorage(api,params,synchronous,callback){let{bizId,key,value}=megaKVParams(params);if(!bizId)return megaFailure("missing bizID");let entries=megaKVStorage.get(bizId)??new Map;if(api==="setItem"){if(!key)return megaFailure("missing key");if(value===null||value==="")return megaFailure("missing value");let previousSize=megaStringByteLength(entries.get(key)??"");return megaKVUsedSize(entries)-previousSize+megaStringByteLength(value)>MEGA_KV_TOTAL_SIZE?megaFailure("KVStorage quota exceeded"):(entries.set(key,value),megaKVStorage.set(bizId,entries),megaKVMutationVersion+=1,persistMegaKVStorage(),completeMegaKVMutation("set",bizId,key,value,synchronous,callback))}if(api==="getItem"){if(!key)return megaFailure("missing key");let result=entries.get(key)??"";return megaSuccess(synchronous?{result}:result)}if(api==="removeItem")return key?(entries.delete(key),entries.size===0&&megaKVStorage.delete(bizId),megaKVMutationVersion+=1,persistMegaKVStorage(),completeMegaKVMutation("remove",bizId,key,void 0,synchronous,callback)):megaFailure("missing key");if(api==="getAllKeys"){let result=Array.from(entries.keys());return megaSuccess(synchronous?{result}:result)}if(api==="clear")return megaKVStorage.delete(bizId),megaKVMutationVersion+=1,persistMegaKVStorage(),completeMegaKVMutation("clear",bizId,"",void 0,synchronous,callback);if(api==="getCurrentInfo"||api==="getCurrentInfoAndKeys"){let data={totalSize:MEGA_KV_TOTAL_SIZE,freeSize:Math.max(MEGA_KV_TOTAL_SIZE-megaKVUsedSize(entries),0)};return api==="getCurrentInfoAndKeys"&&(data.keys=Array.from(entries.keys())),megaSuccess(data)}return{statusCode:405,type:"result",data:{}}}function handleMegaLifeCycle(api,callback){if(api==="addPageLifeCycleListener"){callback&&megaLifeCycleListeners.add(callback),emitMegaCallback(callback,megaSuccess());return}if(api==="removePageLifeCycleListener"){let listeners=Array.from(megaLifeCycleListeners);megaLifeCycleListeners.clear(),emitMegaCallback(callback,megaSuccess());for(let listener of listeners)emitMegaCallback(listener,{statusCode:99,type:"finish",data:{}});return}megaError(callback,405,`LifeCycle.${api} is not supported`)}function handleMegaContainer(api,callback){if(api==="interceptPageClose"){callback&&megaPageCloseListeners.add(callback),emitMegaCallback(callback,megaSuccess());return}if(api==="disableInterceptPageClose"){let listeners=Array.from(megaPageCloseListeners);megaPageCloseListeners.clear(),emitMegaCallback(callback,megaSuccess());for(let listener of listeners)emitMegaCallback(listener,{statusCode:99,type:"finish",data:{}});return}megaError(callback,405,`Container.${api} is not supported`)}function megaNavigationUrl(params){let rawUrl=pickUrl(params);if(!rawUrl)return null;if(!params.extQuery||typeof params.extQuery!="object"||Array.isArray(params.extQuery))return rawUrl;try{let target=new URL(rawUrl,location.href);for(let[key,value]of Object.entries(params.extQuery))value!=null&&target.searchParams.set(key,String(value));return target.href}catch{return rawUrl}}function handleMegaNavigator(api,params,callback){if(api==="openURL"||api==="replace"){let url2=megaNavigationUrl(params);if(!url2){megaError(callback,500,"missing url");return}let callbackId=api==="openURL"&&callback?stashCallback(value=>{let backdata=value&&typeof value=="object"?value.backdata:void 0;emitMegaCallback(callback,{statusCode:1,type:"onResult",data:{result:!0,...backdata===void 0?{}:{data:backdata}}}),emitMegaCallback(callback,{statusCode:99,type:"finish",data:{}})}):0;requestOpen(url2,callbackId,!1,{...params,...api==="replace"?{__mearlReplace:!0}:{}}),emitMegaCallback(callback,megaSuccess());return}if(api==="close"){emitMegaCallback(callback,megaSuccess()),requestClose(void 0);return}if(api==="setSystemBackBlockListener"){megaSystemBackListener&&megaSystemBackListener!==callback&&emitMegaCallback(megaSystemBackListener,{statusCode:99,type:"finish",data:{}}),megaSystemBackListener=callback??null,emitMegaCallback(callback,megaSuccess());return}if(api==="removeSystemBackBlockListener"){let listener=megaSystemBackListener;megaSystemBackListener=null,emitMegaCallback(callback,megaSuccess()),listener&&emitMegaCallback(listener,{statusCode:99,type:"finish",data:{}});return}megaError(callback,405,`navigator.${api} is not supported`)}function handleMegaNavBar(api,params,callback){if(api!=="setTitle"){megaError(callback,405,`NavBar.${api} is not supported`);return}applyNavigationBarState(api,params),emitMegaCallback(callback,megaSuccess())}function handleMegaRouter(api,callback){if(api!=="popPage"){megaError(callback,405,`Router.${api} is not supported`);return}emitMegaCallback(callback,megaSuccess()),requestClose(void 0)}function handleMegaStdPop(api,params,callback){if(api==="showH5"||api==="showWeex2"||api==="showWeex"){let url2=pickUrl(params),popId=typeof params.popId=="string"?params.popId.trim():"";if(!url2||!popId){megaError(callback,500,url2?"missing popId":"missing url");return}let callbackId=stashCallback(value=>{let result=value&&typeof value=="object"&&"backdata"in value?value.backdata:void 0;emitMegaCallback(callback,{statusCode:1,type:"onClose",data:result}),emitMegaCallback(callback,{statusCode:99,type:"finish"})});requestOpen(url2,callbackId,!0,{...params,__mearlMegaPopId:popId}),emitMegaCallback(callback,{statusCode:0,type:"result",data:{}});return}if(api==="close"){let popId=typeof params.popId=="string"?params.popId.trim():"";if(!popId){megaError(callback,500,"missing popId");return}let cloned=cloneMegaDetail(params.result);if(!cloned.success){megaError(callback,500,"result is not serializable");return}requestContainerData("megaPopClose",{popId,result:cloned.value},()=>emitMegaCallback(callback,{statusCode:0,type:"result",data:{}}),reason=>megaError(callback,500,reason));return}if(api==="changeSize"){let popId=typeof params.popId=="string"?params.popId.trim():"";if(!popId){megaError(callback,500,"missing popId");return}requestContainerData("megaPopResize",{...params,popId},()=>emitMegaCallback(callback,{statusCode:0,type:"result",data:{}}),reason=>megaError(callback,500,reason));return}megaError(callback,405,`stdPop.${api} is not supported`)}function handleMegaBroadcast(api,params,callback){let bizId=megaBroadcastBizId(params.bizId),eventName=typeof params.eventName=="string"?params.eventName.trim():"";if(!eventName){megaError(callback,500,"missing eventName");return}if(api==="addEventListener"){if(!callback)return;let id=`mearl-mega-listener-${++megaListenerSeq}`;megaBroadcastListeners.set(id,{id,bizId,eventName,once:params.once===!0,callback}),emitMegaCallback(callback,{statusCode:0,type:"result",data:{}}),emitMegaCallback(callback,{statusCode:1,type:"onAdd",data:{listenerId:id}});return}if(api==="dispatchEvent"){let detail=cloneMegaDetail(params.detail);if(!detail.success){megaError(callback,500,"detail is not serializable");return}requestContainerData("megaBroadcast",{message:{kind:"megaBroadcast",bizId,eventName,detail:detail.value}},()=>emitMegaCallback(callback,{statusCode:0,type:"result",data:{}}),reason=>megaError(callback,500,reason));return}if(api==="removeEventListener"){let listenerId=typeof params.listenerId=="string"?params.listenerId:"",removed=[];for(let listener of Array.from(megaBroadcastListeners.values()))listener.bizId!==bizId||listener.eventName!==eventName||listenerId&&listener.id!==listenerId||(megaBroadcastListeners.delete(listener.id),removed.push(listener));emitMegaCallback(callback,{statusCode:0,type:"result",data:{}});for(let listener of removed)emitMegaCallback(listener.callback,{statusCode:99,type:"finish"});return}megaError(callback,405,`broadcast.${api} is not supported`)}function makeMegaBridge(){return{asyncCall:(ability,api,rawParams,callback)=>{let params=megaParams(rawParams);if(ability==="ability"&&api==="available"){emitMegaCallback(callback,{statusCode:0,type:isMegaApiSupported(params.ability,params.api)?"YES":"NO",data:{}});return}if(ability==="ability"&&api==="batchFinishTrace"){emitMegaCallback(callback,{statusCode:0,type:"result",data:{}});return}if(!isMegaApiSupported(ability,api)){megaError(callback,405,`${ability}.${api} is not supported`);return}if(ability==="stdPop")handleMegaStdPop(api,params,callback);else if(ability==="broadcast")handleMegaBroadcast(api,params,callback);else if(ability==="kvStorage"){let result=executeMegaKVStorage(api,params,!1,callback);result&&emitMegaCallback(callback,result)}else ability==="LifeCycle"?handleMegaLifeCycle(api,callback):ability==="Container"?handleMegaContainer(api,callback):ability==="navigator"?handleMegaNavigator(api,params,callback):ability==="NavBar"?handleMegaNavBar(api,params,callback):handleMegaRouter(api,callback)},syncCall:(ability,api,rawParams)=>{let params=megaParams(rawParams);return ability==="ability"&&api==="available"?{statusCode:0,type:isMegaApiSupported(params.ability,params.api)?"YES":"NO",data:{}}:ability==="kvStorage"&&isMegaApiSupported(ability,api)?executeMegaKVStorage(api,params,!0)??megaFailure("container sync pending"):{statusCode:405,type:"result",data:{}}}}}function makeBridge(style){if(style==="mega")return makeMegaBridge();if(style==="easybikeNative"){let callNative=rawPayload=>{let payload;try{payload=typeof rawPayload=="string"?JSON.parse(rawPayload):rawPayload??{}}catch{return}let classMap=typeof payload.classMap=="string"?payload.classMap:"",method=typeof payload.method=="string"?payload.method:"",callbackId=typeof payload.callbackId=="string"||typeof payload.callbackId=="number"?String(payload.callbackId):"",params;try{params=typeof payload.params=="string"?payload.params?JSON.parse(payload.params):{}:payload.params??{}}catch{params={}}let complete=(code,data,msg="")=>{let callback=resolveWindowFunction("callBack");callbackId&&callback&&callback({callbackId,code,data,msg})};dispatch(`${classMap}.${method}`,params,value=>complete(0,value),error48=>complete(1,void 0,typeof error48=="string"?error48:String(error48??"")))};return{postMessage:callNative,callNative}}if(style==="windvane")return{isAvailable:!0,version:"8.7.0",call:(cls,method,params,succ,fail)=>dispatch(`${cls}.${method}`,params,succ,fail)};if(style==="fliggy"||style==="alipay"||style==="callback"){let bridge={call:(api,params,succ,fail)=>{typeof params=="function"&&(fail=succ,succ=params,params=void 0);let p=params&&typeof params=="object"?params:{},successFn=succ??(typeof p.success_callback=="function"?p.success_callback:void 0)??(typeof p.successCallback=="function"?p.successCallback:void 0),failureFn=fail??(typeof p.fail_callback=="function"?p.fail_callback:void 0)??(typeof p.failure_callback=="function"?p.failure_callback:void 0)??(typeof p.failCallback=="function"?p.failCallback:void 0)??(typeof p.failureCallback=="function"?p.failureCallback:void 0);dispatch(api,p,res=>successFn?.(res),err=>{failureFn?failureFn(err):successFn?.({error:err})},p.callbackCommand??p.callback_command)},pushBack:(prefixOrApi,apiOrParams,paramsOrSucc,succ)=>{let api=prefixOrApi,params=apiOrParams,success2=paramsOrSucc;typeof apiOrParams=="string"&&(api=apiOrParams,params=paramsOrSucc,success2=succ);let p=params??{},successFn=(typeof success2=="function"?success2:void 0)??(typeof p.successCallback=="function"?p.successCallback:void 0);return dispatch(api,p,res=>successFn?.(res),void 0,p.callbackCommand??p.callback_command),bridge},sendUriScheme:uri=>(handleMaybeScheme(uri),bridge)};if(style==="fliggy"){let normalizedAppName=(config2.globals.__APP_NAME__??"").toUpperCase(),os11=config2.clientType==="iphone"?"ios":"android",isAliApp=name=>normalizedAppName===name.toUpperCase();Object.assign(bridge,{version:"1.0.21",device:{os:os11,OS:config2.platform,type:os11,version:config2.systemVersion,model:config2.globals.__DEVICE_MODEL__??""},platform:os11,isAliApp,isTmall:isAliApp("TM"),isTaobao:isAliApp("TB"),isAlipay:isAliApp("AP"),isAlitrip:isAliApp("LX"),isKoubei:isAliApp("KB"),isElm:isAliApp("ELMC"),isGaode:isAliApp("amap"),isUC:/UCBrowser/i.test(config2.userAgent),isWeibo:/Weibo/i.test(config2.userAgent),isWeixin:/MicroMessenger/i.test(config2.userAgent),isWindVane:config2.bridges.some(item=>item.style==="windvane"),isAlipayClient:/AlipayClient/i.test(config2.userAgent)})}return bridge}if(style==="btrip")return{call:(api,params)=>dispatch(api,params??{},void 0,void 0)};if(style==="invoke")return{invoke:(api,params)=>{let p=params??{};dispatch(api,p,p.success,p.fail)}};if(style==="callHandler")return{callHandler:(api,params)=>dispatch(api,params??{},void 0,void 0)};if(style==="amap")return{ready:cb=>cb?.(),send:(msg,cb)=>{let m=msg??{};dispatch(typeof m.action=="string"?m.action:"",m,res=>cb?.(res),err=>cb?.({error:err}))}};if(style==="didi")return{openPage:params=>dispatch("openPage",params??{},void 0,void 0),closePage:params=>dispatch("closePage",params??{},void 0,void 0)};if(style==="wechatMiniProgram"){let invoke2=(api,params)=>{let p=params&&typeof params=="object"?params:{};dispatch(api,p,value=>{p.success?.(value),p.complete?.(value)},error48=>{p.fail?.(error48),p.complete?.(error48)})};return{navigateTo:params=>invoke2("navigateTo",params),redirectTo:params=>invoke2("redirectTo",params),switchTab:params=>invoke2("switchTab",params),reLaunch:params=>invoke2("reLaunch",params),navigateBack:params=>invoke2("navigateBack",params),postMessage:params=>invoke2("postMessage",params),getEnv:callback=>{callback&&setTimeout(()=>callback({miniprogram:!0}),0)}}}return{}}function setGlobal(path23,value){let parts=path23.split("."),obj=w;for(let i=0;i<parts.length-1;i++){let cur=obj[parts[i]];(!cur||typeof cur!="object")&&(obj[parts[i]]={}),obj=obj[parts[i]]}obj[parts[parts.length-1]]=value}if(config2.bridges.some(spec=>spec.style==="mega")){let hydrationVersion=megaKVMutationVersion;requestContainerData("megaKVSnapshot",{},value=>{let entries=value&&typeof value=="object"?value.entries:void 0;megaKVMutationVersion===hydrationVersion&&replaceMegaKVStorage(entries)},()=>{})}for(let spec of config2.bridges)try{setGlobal(spec.global,makeBridge(spec.style))}catch(e){console.error(TAG,"æĄĨåŽčŖ
å¤ąč´Ĩ:",spec.global,e)}return{mapScheme,handleMaybeScheme,handleAppMessage,handleNativeBack,handleResume,handlePageVisibility,applyRuntimeResponses}}function installAppProfileContainerStack(config2,environment,links){let{SRC,TAG,simulateSystemBars,ROOT_FRAME_NAME,LAYER_FRAME_NAME,isTop,isRootFrame,isLayerFrame,isContainerFrame,usesRootContainer,log:log3}=environment,{pageTransport}=links,initialLayerTitleBarState=url2=>links.getSystemBars().initialLayerTitleBarState(url2),resolvedTitleBarState=layer=>links.getSystemBars().resolvedTitleBarState(layer),parseReportedTitleBarState=value=>links.getSystemBars().parseReportedTitleBarState(value),createSimulatedNavigationBarView=(placement,onBack)=>links.getSystemBars().createNavigationBarView(placement,onBack),destroySimulatedNavigationBarView=view=>links.getSystemBars().destroyNavigationBarView(view),syncLayerViewport=(layer,state)=>links.getSystemBars().syncLayerViewport(layer,state),syncActiveSystemBars=()=>links.getSystemBars().syncActiveSystemBars(),syncSimulatedTitleBar=()=>links.getSystemBars().syncSimulatedTitleBar(),rootContainerActive=!1,rootFrame=null,rootBusinessUrl=location.href,webViewEnvironmentRequestSeq=0,simulatedPageHidden=!1,runtimeResponses=null;function syncSimulatorStateToWindow(target){target&&(runtimeResponses&&target.postMessage({source:SRC,type:"runtimeResponses",profile:config2.profile,responses:runtimeResponses},"*"),simulatedPageHidden&&target.postMessage({source:SRC,type:"simulatorVisibility",hidden:!0},"*"))}function startPreparedWebViewNavigation(frame,target,canCommit,registerCleanup){let insets=config2.safeAreaInsets??{top:config2.statusBarHeight,right:0,bottom:0,left:0};if(!usesRootContainer||!Object.values(insets).some(value=>value>0)){canCommit()&&(frame.src=target);return}let requestId=++webViewEnvironmentRequestSeq,settled=!1,fallbackTimer=0,cleanup=()=>{settled||(settled=!0,clearTimeout(fallbackTimer),window.removeEventListener("message",handleResponse),registerCleanup?.(null))},commitNavigation=fallbackReason=>{cleanup(),fallbackReason&&console.warn(TAG,"WebView į¯åĸå夿ĒåŽæīŧéįē§æäē¤å¯ŧčĒ",{target,requestId,reason:fallbackReason}),canCommit()&&(frame.src=target)},handleResponse=event=>{if(event.source!==window||event.data?.source!=="mearl-content"||event.data?.type!=="APP_BRIDGE_PREPARE_WEBVIEW_RESPONSE"||event.data?.requestId!==requestId)return;let result=event.data.result;result?.success===!0?commitNavigation():commitNavigation(String(result?.error??"unknown preparation failure"))};registerCleanup?.(cleanup),window.addEventListener("message",handleResponse),fallbackTimer=setTimeout(()=>commitNavigation("preparation timed out after 500ms"),500);try{window.postMessage({source:SRC,type:"prepareWebView",requestId},"*")}catch(error48){commitNavigation(error48 instanceof Error?error48.message:String(error48))}}function installRootContainer(){if(!usesRootContainer||!/^https?:$/i.test(location.protocol))return;let shellRoot,frame;try{for(let cookie of config2.rootContainer?.initialCookies??[]){if(!cookie.name)continue;let parts=[`${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`,`Path=${cookie.path??"/"}`];cookie.domain&&parts.push(`Domain=${cookie.domain}`),document.cookie=parts.join("; ")}shellRoot=document.createElement("html");let shellHead=document.createElement("head"),charset=document.createElement("meta"),viewport=document.createElement("meta"),title=document.createElement("title"),shellBody=document.createElement("body");frame=document.createElement("iframe"),shellRoot.setAttribute("data-mearl-app-shell",""),shellBody.setAttribute("data-mearl-app-shell",""),charset.setAttribute("charset","utf-8"),viewport.name="viewport",viewport.content="width=device-width,initial-scale=1,viewport-fit=cover",shellHead.append(charset,viewport,title),shellRoot.append(shellHead,shellBody),shellRoot.style.cssText="width:100%;height:100%;margin:0;overflow:hidden;background:#fff;",shellBody.style.cssText="width:100%;height:100%;margin:0;overflow:hidden;background:#fff;",frame.name=ROOT_FRAME_NAME,frame.setAttribute("data-mearl-root-webview",config2.profile),frame.style.cssText="position:fixed;left:0;right:0;top:0;bottom:0;width:100%;height:100%;border:0;display:block;background:#fff;z-index:0;opacity:1;",frame.addEventListener("load",()=>{let committedSrc=frame.getAttribute("src");!committedSrc||committedSrc==="about:blank"||(syncSimulatorStateToWindow(frame.contentWindow),requestAnimationFrame(()=>{rootFrame!==frame||!frame.isConnected||(frame.setAttribute("data-mearl-webview-ready",""),syncSimulatedTitleBar())}))}),shellBody.appendChild(frame);let currentRoot=document.documentElement;currentRoot?document.replaceChild(shellRoot,currentRoot):document.appendChild(shellRoot)}catch(error48){console.warn(TAG,"æ š WebView 厚å¨ååģēå¤ąč´ĨīŧäŋįåŊåéĄĩéĸ",error48),rootFrame=null;return}rootFrame=frame,rootContainerActive=!0;try{typeof window.stop=="function"&&window.stop()}catch(error48){console.warn(TAG,"åæĸå¤åąææĄŖå čŊŊå¤ąč´Ĩīŧįģ§įģå¯å¨æ š WebView",error48)}try{startPreparedWebViewNavigation(frame,rootBusinessUrl,()=>rootFrame===frame&&frame.isConnected)}catch(error48){console.warn(TAG,"æ š WebView į¯åĸåå¤å¯å¨å¤ąč´Ĩīŧį´æĨæäē¤ä¸åĄå¯ŧčĒ",error48),rootFrame===frame&&frame.isConnected&&(frame.src=rootBusinessUrl)}}installRootContainer();function normalizeProxyPathPrefix(prefix){let withLeadingSlash=prefix.startsWith("/")?prefix:`/${prefix}`;return withLeadingSlash.endsWith("/")?withLeadingSlash:`${withLeadingSlash}/`}function matchesProxyTarget(hostname3,suffixes){return suffixes.some(suffix=>hostname3===suffix||hostname3.endsWith(`.${suffix}`))}function mapLayerFrameUrl(url2){let proxy=config2.layerUrlProxy;if(!proxy||!location.hostname.startsWith(proxy.sourceHostPrefix))return url2;try{let target=new URL(url2,location.href);if(!/^https?:$/.test(target.protocol))return url2;let prefix=normalizeProxyPathPrefix(proxy.pathPrefix);if(target.hostname===location.hostname){if(target.pathname.startsWith(prefix))return url2;let derivedHost=location.pathname.startsWith(prefix)?location.pathname.slice(prefix.length).split("/")[0]:proxy.defaultTargetHost;return!derivedHost||!matchesProxyTarget(derivedHost,proxy.targetHostSuffixes)?url2:`${location.origin}${prefix}${derivedHost}${target.pathname}${target.search}${target.hash}`}return matchesProxyTarget(target.hostname,proxy.targetHostSuffixes)?`${location.origin}${prefix}${target.host}${target.pathname}${target.search}${target.hash}`:url2}catch{return url2}}function restoreLayerBusinessUrl(url2){let proxy=config2.layerUrlProxy;if(!proxy)return url2;try{let current=new URL(url2,location.href),prefix=normalizeProxyPathPrefix(proxy.pathPrefix);if(current.origin!==location.origin||!current.pathname.startsWith(prefix))return url2;let rest=current.pathname.slice(prefix.length),slash=rest.indexOf("/"),host=slash===-1?rest:rest.slice(0,slash);if(!host)return url2;let hostname3=new URL(`${current.protocol}//${host}`).hostname;if(!matchesProxyTarget(hostname3,proxy.targetHostSuffixes))return url2;let pathname=slash===-1?"/":rest.slice(slash);return`${current.protocol}//${host}${pathname}${current.search}${current.hash}`}catch{return url2}}let ANIM_MS=config2.animationMs??300;function boolParam(value,fallback){return value===!0||value===1||value==="1"||value==="true"?!0:value===!1||value===0||value==="0"||value==="false"?!1:value===""?!0:fallback}function numberParam(value,fallback,min,max){let parsed=typeof value=="number"?value:Number(value);return Number.isFinite(parsed)?Math.min(Math.max(parsed,min),max):fallback}function resolveOverlayPresentation(url2,params,explicitWebdialog){let query=null;try{query=new URL(url2,location.href).searchParams}catch{}let records=[],addRecord=value=>{value&&typeof value=="object"&&!Array.isArray(value)&&records.push(value)};addRecord(params?.pageParams),addRecord(params?.page_params),addRecord(params?.popConfig),addRecord(params?.data),addRecord(params?.param),addRecord(params);let read=key=>{for(let record2 of records)if(Object.prototype.hasOwnProperty.call(record2,key))return record2[key];return query?.has(key)?query.get(key):void 0},protocol=config2.overlay;if(!explicitWebdialog&&(!protocol||!boolParam(read(protocol.enabledParam),!1)))return null;let configuredTopRatio=protocol?read(protocol.topRatioParam):void 0,configuredHeightRatio=protocol?.heightRatioParam?read(protocol.heightRatioParam):void 0,configuredMaxHeight=read("maxHeight")??configuredHeightRatio,defaultTopRatio=protocol?.defaultTopRatio??.2;return{topRatio:configuredTopRatio!==void 0?numberParam(configuredTopRatio,defaultTopRatio,0,1):configuredMaxHeight!==void 0?1-numberParam(configuredMaxHeight,1-defaultTopRatio,0,1):defaultTopRatio,widthRatio:numberParam(read("maxWidth"),1,0,1),radius:numberParam((protocol?read(protocol.radiusParam):void 0)??read("cornerRadius"),protocol?.defaultRadius??0,0,50),maskAlpha:numberParam(protocol?read(protocol.maskAlphaParam):void 0,protocol?.defaultMaskAlpha??.3,0,1),tapClose:boolParam((protocol?read(protocol.tapCloseParam):void 0)??read("tapEnable"),protocol?.defaultTapClose??!0)}}function requestsPopBeforeOpen(url2,params){if(params?.__mearlReplace===!0)return!0;let key=config2.popBeforeOpenParam;if(!key)return!1;let records=[params?.pageParams,params?.page_params,params?.data,params?.param,params];for(let value of records){if(!value||typeof value!="object"||Array.isArray(value))continue;let record2=value;if(Object.prototype.hasOwnProperty.call(record2,key))return boolParam(record2[key],!1)}try{let query=new URL(url2,location.href).searchParams;return query.has(key)&&boolParam(query.get(key),!1)}catch{return!1}}let layers=[],forwardStack=[],layerSeq=0,enteringLayerCount=0,closingLayerCount=0,explicitLayerTitleBarStates=new Map,rootScrollStyles=null,pendingClose=null,nativeBackRequestSeq=0,pendingNativeBack=null,containerDataRequestSeq=0,containerDataCallbacks=new Map,sharedFiles=new Map,sharedData=new Map,legacyBroadcastChannels=new Set,MEGA_KV_STORAGE_KEY=`__mearl_mega_kv__:${config2.profile}`;function readMegaKVStorage(){let storage=new Map;try{let parsed=JSON.parse(localStorage.getItem(MEGA_KV_STORAGE_KEY)??"{}");if(!parsed||typeof parsed!="object"||Array.isArray(parsed))return storage;for(let[bizId,rawEntries]of Object.entries(parsed)){if(!rawEntries||typeof rawEntries!="object"||Array.isArray(rawEntries))continue;let entries=new Map;for(let[key,value]of Object.entries(rawEntries))typeof value=="string"&&entries.set(key,value);storage.set(bizId,entries)}}catch{}return storage}let megaKVStorage=readMegaKVStorage();function megaKVSnapshot(){let snapshot={};for(let[bizId,values]of megaKVStorage)snapshot[bizId]=Object.fromEntries(values);return snapshot}function persistMegaKVStorage(){try{localStorage.setItem(MEGA_KV_STORAGE_KEY,JSON.stringify(megaKVSnapshot()))}catch{}}let PENDING_CLOSE_TIMEOUT_MS=400,pendingRootHistoryDepth=null;function clearPendingClose(){pendingClose&&(clearTimeout(pendingClose.timer),pendingClose=null)}function clearPendingNativeBack(){pendingNativeBack&&(clearTimeout(pendingNativeBack.timer),pendingNativeBack=null)}function clearPendingRootHistoryDepth(){pendingRootHistoryDepth&&(clearTimeout(pendingRootHistoryDepth.timer),pendingRootHistoryDepth=null)}function armPendingClose(data,retries){clearPendingClose();let timer=setTimeout(()=>{pendingClose=null,log3("close æĒįå° popstateīŧį´æĨå
ŗæ éĄļå
åē"),closeToDepth(Math.max(layers.length-1,0),data,!0)},PENDING_CLOSE_TIMEOUT_MS);pendingClose={data,retries,timer},history.back()}function parseStorageId(url2){try{return new URL(url2,location.href).searchParams.get("__storage_id")}catch{return null}}function titleBarStateCacheKey(url2){try{let parsed=new URL(url2,location.href);return parsed.hash="",parsed.href}catch{return url2}}function cacheExplicitTitleBarState(layer,state){explicitLayerTitleBarStates.set(titleBarStateCacheKey(layer.entryUrl),state),explicitLayerTitleBarStates.set(titleBarStateCacheKey(layer.url),state)}function readDepth(state){if(state&&typeof state=="object"){let d=state.__mearl_layer__;if(typeof d=="number")return d}return null}function mapUrlForSync(url2){let suffixes=config2.urlSyncHostSuffixes??[];try{let u=new URL(url2,location.href);if(!/^https?:$/.test(u.protocol)||!(suffixes.length===0||suffixes.some(s=>u.host===s||u.host.endsWith(`.${s}`))))return;let proxy=config2.layerUrlProxy;return proxy&&location.hostname.startsWith(proxy.sourceHostPrefix)&&matchesProxyTarget(u.hostname,proxy.targetHostSuffixes)?`${normalizeProxyPathPrefix(proxy.pathPrefix)}${u.host}${u.pathname}${u.search}${u.hash}`:u.pathname+u.search+u.hash}catch{return}}function createLayerEl(overlay,id){let el=document.createElement("div");el.setAttribute("data-mearl-layer",String(id)),el.style.cssText=`position:fixed;inset:0;z-index:${2147483e3+id%100*2};`;let frame=document.createElement("iframe");if(frame.name=LAYER_FRAME_NAME,frame.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-modals allow-downloads allow-popups"),frame.style.cssText="position:absolute;inset:0;width:100%;height:100%;border:0;display:block;background:#fff;z-index:0;opacity:1;",overlay){el.style.pointerEvents="none";let mask=document.createElement("div");mask.style.cssText=`position:absolute;inset:0;background:rgba(0,0,0,${overlay.maskAlpha});opacity:0;pointer-events:auto;`;let sheet=document.createElement("div"),width=overlay.widthRatio*100,left=(1-overlay.widthRatio)/2*100;return sheet.style.cssText=`position:absolute;left:${left}%;right:auto;bottom:0;width:${width}%;height:${(1-overlay.topRatio)*100}%;background:#fff;border-radius:${overlay.radius}px ${overlay.radius}px 0 0;overflow:hidden;pointer-events:auto;`,sheet.appendChild(frame),el.appendChild(mask),el.appendChild(sheet),{el,frame,animEl:sheet,mask}}return el.style.background="#fff",el.appendChild(frame),{el,frame,animEl:el,mask:null}}function setLayerInteractive(layer,interactive){layer.frame.style.pointerEvents=interactive?"":"none",layer.titleBarView&&(layer.titleBarView.root.style.pointerEvents=interactive?"":"none"),interactive?(layer.frame.removeAttribute("inert"),layer.frame.removeAttribute("aria-hidden"),layer.frame.removeAttribute("tabindex")):(layer.frame.setAttribute("inert",""),layer.frame.setAttribute("aria-hidden","true"),layer.frame.setAttribute("tabindex","-1"),layer.frame.blur()),layer.overlay?(layer.el.style.pointerEvents="none",layer.animEl.style.pointerEvents=interactive?"auto":"none",layer.mask&&(layer.mask.style.pointerEvents=interactive?"auto":"none")):layer.el.style.pointerEvents=interactive?"":"none"}function setRootFrameInteractive(interactive){rootFrame&&(rootFrame.style.pointerEvents=interactive?"":"none",interactive?(rootFrame.removeAttribute("inert"),rootFrame.removeAttribute("aria-hidden"),rootFrame.removeAttribute("tabindex")):(rootFrame.setAttribute("inert",""),rootFrame.setAttribute("aria-hidden","true"),rootFrame.setAttribute("tabindex","-1"),rootFrame.blur()))}function blockClosingLayerInteractions(layer){setLayerInteractive(layer,!1),layer.el.style.pointerEvents="auto"}function syncRootScrollLock(locked){let body=document.body;if(locked&&!rootScrollStyles){rootScrollStyles={html:document.documentElement.style.overflow,body:body?.style.overflow??null},document.documentElement.style.overflow="hidden",body&&(body.style.overflow="hidden");return}!locked&&rootScrollStyles&&(document.documentElement.style.overflow=rootScrollStyles.html,body&&rootScrollStyles.body!==null&&(body.style.overflow=rootScrollStyles.body),rootScrollStyles=null)}function syncLayerInteractivity(){let activeLayer=closingLayerCount===0&&enteringLayerCount===0?layers[layers.length-1]:void 0;for(let layer of layers)setLayerInteractive(layer,layer===activeLayer),!activeLayer&&layer===layers[layers.length-1]&&(layer.el.style.pointerEvents="auto");setRootFrameInteractive(layers.length===0&&enteringLayerCount===0&&closingLayerCount===0),syncRootScrollLock(layers.length>0||enteringLayerCount>0||closingLayerCount>0)}function finishLayerEntry(layer){layer.entering&&(layer.entering=!1,layer.enterTimer!==null&&clearTimeout(layer.enterTimer),layer.enterTimer=null,layer.enterTransitionEnd&&(layer.animEl.removeEventListener("transitionend",layer.enterTransitionEnd),layer.enterTransitionEnd=null),enteringLayerCount=Math.max(enteringLayerCount-1,0),syncLayerInteractivity())}function animateIn(layer){let t=layer.animEl;if(t.style.transform=layer.overlay?"translateY(100%)":"translateX(100%)",t.offsetWidth,t.style.transition=`transform ${ANIM_MS}ms ease`,t.style.transform="translate(0px, 0px)",layer.mask&&(layer.mask.style.transition=`opacity ${ANIM_MS}ms ease`,layer.mask.style.opacity="1"),ANIM_MS<=0){finishLayerEntry(layer);return}layer.enterTransitionEnd=event=>{event.target===t&&event.propertyName==="transform"&&finishLayerEntry(layer)},t.addEventListener("transitionend",layer.enterTransitionEnd),layer.enterTimer=setTimeout(()=>finishLayerEntry(layer),ANIM_MS+60)}function animateOut(layer,done){let t=layer.animEl;if(ANIM_MS<=0){t.style.transform=layer.overlay?"translateY(100%)":"translateX(100%)",layer.mask&&(layer.mask.style.opacity="0"),setTimeout(done,0);return}let settled=!1,fallbackTimer=0,finish=()=>{settled||(settled=!0,t.removeEventListener("transitionend",onTransitionEnd),clearTimeout(fallbackTimer),done())},onTransitionEnd=event=>{event.target===t&&event.propertyName==="transform"&&finish()};t.addEventListener("transitionend",onTransitionEnd),t.style.transition=`transform ${ANIM_MS}ms ease`,t.style.transform=layer.overlay?"translateY(100%)":"translateX(100%)",layer.mask&&(layer.mask.style.opacity="0"),fallbackTimer=setTimeout(finish,ANIM_MS+60)}function startLayerNavigation(layer,target){startPreparedWebViewNavigation(layer.frame,target,()=>!layer.closing&&layer.el.isConnected,cleanup=>{layer.navigationPreparationCleanup=cleanup})}function setPageVisibility(target,hidden){if(target===window){links.getBridgeProtocol().handlePageVisibility(hidden);return}try{target.postMessage({source:SRC,type:"simulatorVisibility",hidden},"*")}catch{}}function openLayer(url2,callbackId,overlay,openerWin,pushHistory,popId=null){clearPendingClose();let target=url2;if(!/^https?:/i.test(target)){let mapped=links.getBridgeProtocol().mapScheme(target);if(!mapped)return log3("open å¤ąč´Ĩīŧscheme æĒæ å°:",url2),null;target=mapped}location.protocol==="https:"&&target.startsWith("http:")&&(target="https:"+target.slice(5));let presentation=overlay??resolveOverlayPresentation(target,void 0,!1);log3("open â",presentation?"(webdialog) ":"",target);let parts=createLayerEl(presentation,++layerSeq),restoredTitleBarState=explicitLayerTitleBarStates.get(titleBarStateCacheKey(target)),layer={id:layerSeq,win:parts.frame.contentWindow,frame:parts.frame,entryUrl:target,url:target,overlay:presentation,openerWin,callbackId,storageId:parseStorageId(target),popId,el:parts.el,animEl:parts.animEl,mask:parts.mask,entering:!0,enterTimer:null,enterTransitionEnd:null,closing:!1,navigationPreparationCleanup:null,titleBarState:restoredTitleBarState??initialLayerTitleBarState(target),titleBarStateExplicit:restoredTitleBarState!==void 0,titleBarStateReady:restoredTitleBarState!==void 0,titleBarView:null};if(popId&&layer.el.setAttribute("data-mearl-pop-id",popId),layer.mask&&presentation?.tapClose&&layer.mask.addEventListener("click",()=>requestOverlayClose(layer)),!presentation&&simulateSystemBars&&config2.titleBar&&(layer.titleBarView=createSimulatedNavigationBarView("layer",()=>requestNativeBack()),layer.titleBarView.root.setAttribute("data-mearl-layer-titlebar",String(layer.id)),parts.el.appendChild(layer.titleBarView.root)),layers.push(layer),setPageVisibility(openerWin,!0),enteringLayerCount+=1,syncLayerViewport(layer,layer.titleBarState),syncLayerInteractivity(),parts.frame.addEventListener("load",()=>{layer.win=parts.frame.contentWindow,parts.frame.name=LAYER_FRAME_NAME;let committedSrc=parts.frame.getAttribute("src");!committedSrc||committedSrc==="about:blank"||(syncSimulatorStateToWindow(parts.frame.contentWindow),requestAnimationFrame(()=>{layer.titleBarStateReady||layer.closing||!layer.el.isConnected||(layer.titleBarStateReady=!0,syncLayerViewport(layer,resolvedTitleBarState(layer)))}))}),(document.body??document.documentElement).appendChild(parts.el),layer.win=parts.frame.contentWindow,startLayerNavigation(layer,mapLayerFrameUrl(target)),animateIn(layer),pushHistory){forwardStack.length=0;try{history.pushState({__mearl_layer__:layers.length},"",mapUrlForSync(target))}catch{}}return layer}function replaceLayer(sourceLayer,url2,callbackId,overlay,popId=null){if(sourceLayer.closing||layers[layers.length-1]!==sourceLayer){openLayer(url2,callbackId,overlay,sourceLayer.win??window,!0,popId);return}let replacement=openLayer(url2,callbackId,overlay,sourceLayer.openerWin,!1,popId);if(!replacement)return;sourceLayer.navigationPreparationCleanup?.(),sourceLayer.navigationPreparationCleanup=null,sourceLayer.entering&&(sourceLayer.entering=!1,enteringLayerCount=Math.max(enteringLayerCount-1,0),sourceLayer.enterTimer!==null&&clearTimeout(sourceLayer.enterTimer),sourceLayer.enterTransitionEnd&&sourceLayer.animEl.removeEventListener("transitionend",sourceLayer.enterTransitionEnd));let sourceIndex=layers.indexOf(sourceLayer);sourceIndex>=0&&layers.splice(sourceIndex,1),destroySimulatedNavigationBarView(sourceLayer.titleBarView),sourceLayer.el.remove(),forwardStack.length=0,syncLayerInteractivity(),syncActiveSystemBars();try{history.replaceState({__mearl_layer__:layers.length},"",mapUrlForSync(replacement.url))}catch{}}function closeLayer(layer,data,final,gotoEvent=!1,resumeOpener=!0){if(layer.closing)return;layer.navigationPreparationCleanup?.(),layer.navigationPreparationCleanup=null,layer.entering&&(layer.entering=!1,enteringLayerCount=Math.max(enteringLayerCount-1,0),layer.enterTimer!==null&&clearTimeout(layer.enterTimer),layer.enterTimer=null,layer.enterTransitionEnd&&(layer.animEl.removeEventListener("transitionend",layer.enterTransitionEnd),layer.enterTransitionEnd=null)),layer.closing=!0;let idx=layers.indexOf(layer);idx>=0&&layers.splice(idx,1),closingLayerCount+=1,blockClosingLayerInteractions(layer),syncLayerInteractivity(),syncActiveSystemBars(),final?forwardStack.length=0:forwardStack.push({url:layer.url,overlay:layer.overlay,openerWin:layer.openerWin,callbackId:layer.callbackId,storageId:layer.storageId,popId:layer.popId}),log3("close â",layer.url,data===void 0?"":data),animateOut(layer,()=>{if(destroySimulatedNavigationBarView(layer.titleBarView),layer.el.remove(),closingLayerCount=Math.max(closingLayerCount-1,0),syncLayerInteractivity(),syncActiveSystemBars(),!!resumeOpener)if(layer.openerWin===window)links.getBridgeProtocol().handleResume({data,storageId:layer.storageId,callbackId:layer.callbackId,final,gotoEvent});else try{layer.openerWin.postMessage({source:SRC,type:"resume",data,storageId:layer.storageId,callbackId:layer.callbackId,final,gotoEvent},"*")}catch{}})}function closeToDepth(depth,data,final){for(;layers.length>depth;){let revealsTarget=layers.length===depth+1;closeLayer(layers[layers.length-1],revealsTarget?data:void 0,final,!1,revealsTarget)}}function closeAllLayers(data,gotoEvent=!1){let depth=layers.length;for(;layers.length>0;){let isRootmostLayer=layers.length===1;closeLayer(layers[layers.length-1],isRootmostLayer?data:void 0,!0,isRootmostLayer&&gotoEvent,isRootmostLayer)}if(depth>0)try{history.go(-depth)}catch{}return depth>0}function requestOverlayClose(layer){if(!(layer.closing||layers[layers.length-1]!==layer)){for(let selector of config2.overlay?.tapCloseSelectors??[])try{let control=layer.frame.contentDocument?.querySelector(selector);if(typeof control?.click!="function")continue;control.click();return}catch{}requestCloseOnTop(void 0)}}function forwardToDepth(depth){for(;layers.length<depth&&forwardStack.length>0;){let entry=forwardStack.pop();openLayer(entry.url,entry.callbackId,entry.overlay,entry.openerWin,!1,entry.popId)}}function requestCloseOnTop(data){if(layers.length===0){history.back();return}if(rootContainerActive){clearPendingRootHistoryDepth(),closeLayer(layers[layers.length-1],data,!0);let depth=layers.length,timer=setTimeout(()=>{pendingRootHistoryDepth=null,console.warn(TAG,"WebView 厞åēæ īŧäŊæĩč§å¨å垿Ēå¨éĸææļé´å
åæĨ",{depth})},PENDING_CLOSE_TIMEOUT_MS);pendingRootHistoryDepth={depth,timer},history.back();return}armPendingClose(data,8)}function isActiveBusinessWindow(target){let topLayer=layers[layers.length-1];return topLayer?topLayer.frame.contentWindow===target:rootFrame?rootFrame.contentWindow===target:target===window}function finishNativeBack(requestId,target,handled){pendingNativeBack?.requestId!==requestId||pendingNativeBack.target!==target||(clearPendingNativeBack(),!handled&&isActiveBusinessWindow(target)&&requestCloseOnTop(void 0))}function requestNativeBack(){if(!isTop||pendingNativeBack)return;let target=layers[layers.length-1]?.frame.contentWindow??rootFrame?.contentWindow??window;if(!target||target===window){links.getBridgeProtocol().handleNativeBack()||requestCloseOnTop(void 0);return}let requestId=++nativeBackRequestSeq,timer=setTimeout(()=>finishNativeBack(requestId,target,!1),120);pendingNativeBack={requestId,target,timer};try{target.postMessage({source:SRC,type:"nativeBack",requestId},"*")}catch{finishNativeBack(requestId,target,!1)}}function layerForWindow(source){if(source)for(let layer of layers){if(layer.win===source)return layer;let currentWindow=layer.frame.contentWindow;if(currentWindow&¤tWindow===source)return layer.win=currentWindow,layer}}if(isTop){if(!rootContainerActive){let rawPushState=history.pushState.bind(history),rawReplaceState=history.replaceState.bind(history),withDepth=state=>state==null?{__mearl_layer__:layers.length}:typeof state=="object"&&!Array.isArray(state)?{...state,__mearl_layer__:layers.length}:state;try{history.pushState=function(...args){rawPushState(withDepth(args[0]),args[1],args[2])},history.replaceState=function(...args){rawReplaceState(withDepth(args[0]),args[1],args[2])}}catch{}}try{readDepth(history.state)===null&&history.replaceState({__mearl_layer__:0},"")}catch{}window.addEventListener("popstate",e=>{let depth=readDepth(e.state);if(rootContainerActive){if(pendingRootHistoryDepth){let expectedDepth=pendingRootHistoryDepth.depth;if(clearPendingRootHistoryDepth(),depth===expectedDepth)return;console.warn(TAG,"æĩč§å¨å垿ˇąåēĻä¸ WebView åēæ äēåĄä¸ä¸č´",{expectedDepth,actualDepth:depth})}if(depth===null)return;depth<layers.length?closeToDepth(depth,void 0,!1):depth>layers.length&&forwardToDepth(depth);return}if(pendingClose){if(depth!==null&&depth<layers.length){let{data}=pendingClose;clearPendingClose(),closeToDepth(depth,data,!0)}else if(pendingClose.retries>0)armPendingClose(pendingClose.data,pendingClose.retries-1);else{let{data}=pendingClose;clearPendingClose(),closeToDepth(layers.length-1,data,!0)}return}depth!==null&&(depth<layers.length?closeToDepth(depth,void 0,!1):depth>layers.length&&forwardToDepth(depth))})}function broadcastAppMessage(message){links.getBridgeProtocol().handleAppMessage(message);let targets=[rootFrame?.contentWindow??null,...layers.filter(layer=>!layer.closing).map(layer=>layer.frame.contentWindow)];for(let target of targets)if(!(!target||target===window))try{target.postMessage({source:SRC,type:"appMessage",message},"*")}catch{}}function closeMegaPop(popId,data){let index=layers.findIndex(layer=>layer.popId===popId&&!layer.closing);if(index<0)return!1;let closingDepth=layers.length-index;closeToDepth(index,data,!0);try{history.go(-closingDepth)}catch{}return!0}function resizeMegaPop(popId,params){let layer=layers.find(candidate=>candidate.popId===popId&&!candidate.closing);if(!layer?.overlay)return!1;if(params.maxHeight!==void 0){let maxHeight=numberParam(params.maxHeight,1-layer.overlay.topRatio,0,1);layer.overlay.topRatio=1-maxHeight,layer.animEl.style.height=`${maxHeight*100}%`}if(params.maxWidth!==void 0){let maxWidth=numberParam(params.maxWidth,1,0,1);layer.overlay.widthRatio=maxWidth,layer.animEl.style.width=`${maxWidth*100}%`,layer.animEl.style.left=`${(1-maxWidth)/2*100}%`,layer.animEl.style.right="auto"}return params.animated===!0&&(layer.animEl.style.transition="height 200ms ease, width 200ms ease, left 200ms ease"),!0}function executeContainerData(action,params){if(action==="sharedFileRead"||action==="sharedFileWrite"){let fileName=typeof params.fileName=="string"?params.fileName:"";if(!fileName)return{success:!1,value:"missing fileName"};if(action==="sharedFileRead")return{success:!0,value:{data:sharedFiles.get(fileName)??""}};let data=typeof params.data=="string"?params.data:String(params.data??"");return sharedFiles.set(fileName,data),{success:!0,value:{}}}if(action==="sharedDataGet"){let keys=Array.isArray(params.keys)?params.keys.filter(key=>typeof key=="string"):[],data={};for(let key of keys)sharedData.has(key)&&(data[key]=sharedData.get(key));return{success:!0,value:{data}}}if(action==="sharedDataSet"){if(!params.data||typeof params.data!="object"||Array.isArray(params.data))return{success:!1,value:"missing shared data"};for(let[key,value]of Object.entries(params.data))value==null?sharedData.delete(key):sharedData.set(key,value);return{success:!0,value:{}}}if(action==="megaBroadcast")return!params.message||typeof params.message!="object"||Array.isArray(params.message)?{success:!1,value:"missing broadcast message"}:(broadcastAppMessage(params.message),{success:!0,value:{}});if(action==="megaKVSnapshot")return{success:!0,value:{entries:megaKVSnapshot()}};if(action==="megaKVMutation"){let operation=typeof params.operation=="string"?params.operation:"",bizId=typeof params.bizId=="string"?params.bizId:"";if(!bizId)return{success:!1,value:"missing bizID"};let key=typeof params.key=="string"?params.key:"";if((operation==="set"||operation==="remove")&&!key)return{success:!1,value:"missing key"};if(operation==="set"){if(typeof params.value!="string")return{success:!1,value:"missing value"};let entries=megaKVStorage.get(bizId)??new Map;entries.set(key,params.value),megaKVStorage.set(bizId,entries)}else if(operation==="remove"){let entries=megaKVStorage.get(bizId);entries?.delete(key),entries?.size===0&&megaKVStorage.delete(bizId)}else if(operation==="clear")megaKVStorage.delete(bizId);else return{success:!1,value:"unsupported KVStorage operation"};return persistMegaKVStorage(),broadcastAppMessage({kind:"megaKVStorage",operation,bizId,key,value:params.value}),{success:!0,value:{}}}if(action==="legacyBroadcastCreate"){let instanceId=typeof params.instanceId=="string"?params.instanceId:"";return instanceId?(legacyBroadcastChannels.add(instanceId),{success:!0,value:{}}):{success:!1,value:"missing instanceId"}}if(action==="legacyBroadcastPost"){let instanceId=typeof params.instanceId=="string"?params.instanceId:"";return instanceId?legacyBroadcastChannels.has(instanceId)?(broadcastAppMessage({kind:"legacyBroadcast",instanceId,message:params.message}),{success:!0,value:{}}):{success:!1,value:"broadcast channel not found"}:{success:!1,value:"missing instanceId"}}if(action==="legacyBroadcastClose"){let instanceId=typeof params.instanceId=="string"?params.instanceId:"";return instanceId?(legacyBroadcastChannels.delete(instanceId),{success:!0,value:{}}):{success:!1,value:"missing instanceId"}}if(action==="megaPopClose"){let popId=typeof params.popId=="string"?params.popId:"";return popId?closeMegaPop(popId,params.result)?{success:!0,value:{}}:{success:!1,value:"popId not found"}:{success:!1,value:"missing popId"}}if(action==="megaPopResize"){let popId=typeof params.popId=="string"?params.popId:"";return popId?resizeMegaPop(popId,params)?{success:!0,value:{}}:{success:!1,value:"popId not found"}:{success:!1,value:"missing popId"}}return{success:!1,value:"unsupported container data action"}}function requestContainerData(action,params,onSuccess,onFailure){if(isTop){let result=executeContainerData(action,params);setTimeout(()=>result.success?onSuccess(result.value):onFailure(result.value),0);return}let requestId=++containerDataRequestSeq;containerDataCallbacks.set(requestId,{success:onSuccess,failure:onFailure});try{window.top?.postMessage({source:SRC,type:"containerDataRequest",requestId,action,params},"*")}catch(error48){containerDataCallbacks.delete(requestId),onFailure(error48 instanceof Error?error48.message:String(error48))}}function requestOpen(url2,callbackId,webdialog,params){let overlay=resolveOverlayPresentation(url2,params,webdialog),popBeforeOpen=requestsPopBeforeOpen(url2,params),popId=typeof params?.__mearlMegaPopId=="string"?params.__mearlMegaPopId:null;isTop?openLayer(url2,callbackId,overlay,window,!0,popId):window.top?.postMessage({source:SRC,type:"open",url:url2,callbackId,overlay,popBeforeOpen,popId},"*")}function requestClose(data){let payload;try{payload=data===void 0?void 0:JSON.parse(JSON.stringify(data))}catch{payload=void 0}isTop?requestCloseOnTop(payload):window.top?.postMessage({source:SRC,type:"close",data:payload},"*")}if(window.addEventListener("message",event=>{let msg=event.data;if(!(!msg||typeof msg!="object")){if(msg.source==="mearl-content"&&(msg.type==="APP_BRIDGE_SIMULATOR_VISIBILITY"||msg.type==="APP_BRIDGE_RUNTIME_RESPONSES")){if(!isTop||event.source!==window)return;if(msg.type==="APP_BRIDGE_SIMULATOR_VISIBILITY"&&typeof msg.hidden=="boolean"){simulatedPageHidden=msg.hidden,links.getBridgeProtocol().handlePageVisibility(msg.hidden);let lifecycleMessage={source:SRC,type:"simulatorVisibility",hidden:msg.hidden};rootFrame?.contentWindow?.postMessage(lifecycleMessage,"*");for(let layer of layers)layer.closing||layer.frame.contentWindow?.postMessage(lifecycleMessage,"*")}else if(msg.type==="APP_BRIDGE_RUNTIME_RESPONSES"&&msg.profile===config2.profile&&msg.responses&&typeof msg.responses=="object"&&!Array.isArray(msg.responses)){let responses=msg.responses;runtimeResponses={...runtimeResponses??{},...responses},links.getBridgeProtocol().applyRuntimeResponses(responses);let configMessage={source:SRC,type:"runtimeResponses",profile:config2.profile,responses};rootFrame?.contentWindow?.postMessage(configMessage,"*");for(let layer of layers)layer.closing||layer.frame.contentWindow?.postMessage(configMessage,"*")}return}if(msg.source===SRC){if(isTop){let sourceLayer=layerForWindow(event.source),sourceIsRoot=!!(rootFrame?.contentWindow&&rootFrame.contentWindow===event.source);if(!sourceLayer&&!sourceIsRoot)return;if(msg.type==="open"&&typeof msg.url=="string"){let rawOverlay=msg.overlay&&typeof msg.overlay=="object"?msg.overlay:void 0,overlay=rawOverlay?{topRatio:numberParam(rawOverlay.topRatio,.2,0,1),widthRatio:numberParam(rawOverlay.widthRatio,1,0,1),radius:numberParam(rawOverlay.radius,0,0,50),maskAlpha:numberParam(rawOverlay.maskAlpha,.3,0,1),tapClose:boolParam(rawOverlay.tapClose,!0)}:resolveOverlayPresentation(msg.url,void 0,!1),callbackId=typeof msg.callbackId=="number"?msg.callbackId:0,popId=typeof msg.popId=="string"&&msg.popId?msg.popId:null;msg.popBeforeOpen===!0&&sourceLayer?replaceLayer(sourceLayer,msg.url,callbackId,overlay,popId):openLayer(msg.url,callbackId,overlay,event.source??window,!0,popId)}else if(msg.type==="close")requestCloseOnTop(msg.data);else if(msg.type==="closeAll"){let gotoEvent=msg.gotoEvent===!0;if(gotoEvent&&sourceIsRoot&&layers.length===0&&msg.data!==void 0)try{event.source.postMessage({source:SRC,type:"resume",data:msg.data,storageId:null,callbackId:0,final:!0,gotoEvent:!0},"*")}catch{}else closeAllLayers(msg.data,gotoEvent)}else if(msg.type==="appMessageToOpener"&&sourceLayer){let target=sourceLayer.openerWin;if(target===window)links.getBridgeProtocol().handleAppMessage(msg.message);else try{target.postMessage({source:SRC,type:"appMessage",message:msg.message},"*")}catch{}}else if(msg.type==="containerDataRequest"&&typeof msg.requestId=="number"&&typeof msg.action=="string"&&msg.params&&typeof msg.params=="object"&&!Array.isArray(msg.params)&&event.source){let result=executeContainerData(msg.action,msg.params);try{event.source.postMessage({source:SRC,type:"containerDataResponse",requestId:msg.requestId,success:result.success,value:result.value},"*")}catch{}}else if(msg.type==="nativeBackResult"&&typeof msg.requestId=="number"&&typeof msg.handled=="boolean"&&event.source)finishNativeBack(msg.requestId,event.source,msg.handled);else if(msg.type==="urlChanged"&&typeof msg.url=="string"){let topLayer=layers[layers.length-1];if(sourceIsRoot&&!topLayer){rootBusinessUrl=msg.url;let mapped=mapUrlForSync(msg.url);if(mapped)try{history.replaceState({__mearl_layer__:0},"",mapped)}catch{}}else if(topLayer&&!topLayer.closing&&sourceLayer===topLayer){topLayer.url=msg.url,topLayer.titleBarStateExplicit&&topLayer.titleBarState&&cacheExplicitTitleBarState(topLayer,topLayer.titleBarState);let mapped=mapUrlForSync(msg.url);if(mapped)try{history.replaceState({__mearl_layer__:layers.length},"",mapped)}catch{}}}else if(msg.type==="title"&&typeof msg.title=="string"){let topLayer=layers[layers.length-1];if(sourceIsRoot&&!topLayer)try{document.title=msg.title,syncSimulatedTitleBar()}catch{}else if(topLayer&&sourceLayer===topLayer){document.title=msg.title;let state=resolvedTitleBarState(topLayer);topLayer.titleBarState={...state,title:msg.title},syncLayerViewport(topLayer,topLayer.titleBarState)}}else if(msg.type==="titleBarState"){let state=parseReportedTitleBarState(msg.state);if(state&&sourceIsRoot)links.getSystemBars().setPresentedRootTitleBarState(state);else if(state&&sourceLayer){let explicit=msg.explicit===!0;sourceLayer.titleBarStateReady=!0,explicit?(sourceLayer.titleBarState=state,sourceLayer.titleBarStateExplicit=!0,cacheExplicitTitleBarState(sourceLayer,state)):sourceLayer.titleBarStateExplicit||(sourceLayer.titleBarState=state);let resolvedState=sourceLayer.titleBarState??state;syncLayerViewport(sourceLayer,resolvedState)}}}else if(msg.type==="simulatorVisibility"&&typeof msg.hidden=="boolean"){if(event.source!==window.top)return;links.getBridgeProtocol().handlePageVisibility(msg.hidden)}else if(msg.type==="appMessage"){if(event.source!==window.top)return;links.getBridgeProtocol().handleAppMessage(msg.message)}else if(msg.type==="nativeBack"&&typeof msg.requestId=="number"){if(event.source!==window.top)return;let handled=links.getBridgeProtocol().handleNativeBack();window.top?.postMessage({source:SRC,type:"nativeBackResult",requestId:msg.requestId,handled},"*")}else if(msg.type==="containerDataResponse"&&typeof msg.requestId=="number"){if(event.source!==window.top)return;let callback=containerDataCallbacks.get(msg.requestId);if(!callback)return;containerDataCallbacks.delete(msg.requestId),msg.success===!0?callback.success(msg.value):callback.failure(msg.value)}else if(msg.type==="runtimeResponses"&&msg.profile===config2.profile&&msg.responses&&typeof msg.responses=="object"&&!Array.isArray(msg.responses)){if(event.source!==window.top)return;links.getBridgeProtocol().applyRuntimeResponses(msg.responses)}else if(msg.type==="resume"){if(event.source!==window.top)return;links.getBridgeProtocol().handleResume({data:msg.data,storageId:msg.storageId??null,callbackId:typeof msg.callbackId=="number"?msg.callbackId:0,final:msg.final===!0,gotoEvent:msg.gotoEvent===!0})}else event.source!==window.top&&window.top?.postMessage(msg,"*");return}pageTransport.handleMessage(msg)}}),!isTop&&isContainerFrame){let reportUrl=()=>{try{window.top?.postMessage({source:SRC,type:"urlChanged",url:restoreLayerBusinessUrl(location.href)},"*")}catch{}};try{let origPushState=history.pushState.bind(history),origReplaceState=history.replaceState.bind(history);history.pushState=function(...args){origPushState(...args),reportUrl()},history.replaceState=function(...args){origReplaceState(...args),reportUrl()},window.addEventListener("popstate",reportUrl),window.addEventListener("hashchange",reportUrl)}catch{}}if(isContainerFrame){let requestProxyLocationOpen=url2=>{if(links.getBridgeProtocol().handleMaybeScheme(url2))return!0;try{let current=new URL(restoreLayerBusinessUrl(location.href)),target=new URL(url2,current);return!/^https?:$/.test(target.protocol)||target.origin===current.origin&&target.pathname===current.pathname&&target.search===current.search?!1:(requestOpen(target.href,0,!1),!0)}catch{return!1}};Object.defineProperty(window,"__PROXY_LOCATION__",{value:{get href(){return location.href},set href(url2){requestProxyLocationOpen(url2)||(location.href=mapLayerFrameUrl(url2))},replace(url2){links.getBridgeProtocol().handleMaybeScheme(url2)||location.replace(mapLayerFrameUrl(url2))},assign(url2){requestProxyLocationOpen(url2)||location.assign(mapLayerFrameUrl(url2))}},writable:!1,configurable:!0})}if(isContainerFrame){document.addEventListener("click",event=>{let el=event.target;for(;el&&el.tagName!=="A";)el=el.parentElement;if(!el)return;let href=el.getAttribute("href");if(href){if(links.getBridgeProtocol().handleMaybeScheme(href)){event.preventDefault(),event.stopPropagation();return}/^https?:/i.test(href)&&el.getAttribute("target")==="_blank"&&(event.preventDefault(),event.stopPropagation(),requestOpen(href,0,!1))}},!0);let origOpen=window.open;window.open=function(url2,target,features){let urlStr=typeof url2=="string"?url2:url2 instanceof URL?url2.href:"";return links.getBridgeProtocol().handleMaybeScheme(urlStr)?null:/^https?:/i.test(urlStr)?(requestOpen(urlStr,0,!1),null):origOpen?origOpen.call(window,url2,target,features):null};try{let proto=Location.prototype,origAssign=proto.assign,origReplace=proto.replace;origAssign&&(proto.assign=function(url2){if(links.getBridgeProtocol().handleMaybeScheme(url2))return;let upgraded=location.protocol==="https:"&&url2.startsWith("http:")?"https:"+url2.slice(5):url2;origAssign.call(this,upgraded)}),origReplace&&(proto.replace=function(url2){if(links.getBridgeProtocol().handleMaybeScheme(url2))return;let upgraded=location.protocol==="https:"&&url2.startsWith("http:")?"https:"+url2.slice(5):url2;origReplace.call(this,upgraded)})}catch{}}return log3("厚å¨į¯åĸåˇ˛å°ąįģĒ",isTop?"(top)":isRootFrame?"(root)":isLayerFrame?"(layer)":"(iframeīŧäģ
æĄĨ)"),{getRootFrame:()=>rootFrame,getLayers:()=>layers,getClosingLayerCount:()=>closingLayerCount,requestOpen,requestClose,requestNativeBack,requestContainerData,closeAllLayers}}var APP_PROFILE_RUNTIME_FACTORIES={environment:installAppProfileEnvironment,containerStack:installAppProfileContainerStack,bridgeProtocol:installAppProfileBridgeProtocol,pageTransport:installAppProfilePageTransport,systemBars:installAppProfileSystemBars};function buildAppProfileRuntimeCallSource(configExpression){return`(${installAppProfileRuntime.toString()})(${configExpression},{environment:${installAppProfileEnvironment.toString()},pageTransport:${installAppProfilePageTransport.toString()},containerStack:${installAppProfileContainerStack.toString()},systemBars:${installAppProfileSystemBars.toString()},bridgeProtocol:${installAppProfileBridgeProtocol.toString()}})`}function installAppProfileRuntime(config2,factories=APP_PROFILE_RUNTIME_FACTORIES){let environment=factories.environment(config2);if(!environment)return;let pageTransport=factories.pageTransport(config2,environment),containerStack=factories.containerStack(config2,environment,{pageTransport,getSystemBars:()=>systemBars,getBridgeProtocol:()=>bridgeProtocol}),systemBars=factories.systemBars(config2,environment,{getRootFrame:containerStack.getRootFrame,getLayers:containerStack.getLayers,getClosingLayerCount:containerStack.getClosingLayerCount,requestClose:containerStack.requestClose,requestNativeBack:containerStack.requestNativeBack}),bridgeProtocol=factories.bridgeProtocol(config2,environment,{pageTransport,systemBars,requestOpen:containerStack.requestOpen,requestClose:containerStack.requestClose,requestCloseAll:containerStack.closeAllLayers,requestContainerData:containerStack.requestContainerData})}import https from"node:https";import http3 from"node:http";var TYPE_INTO_ELEMENT_SRC=typeIntoElement.toString(),CLICK_ELEMENT_VIA_JS_SRC=clickElementViaJS.toString(),GET_CLICK_COORDS_FROM_NODE_SRC=getClickCoordsFromNode.toString();function nodeFetch(urlStr,options={}){return new Promise((resolve3,reject)=>{let url2=new URL(urlStr),isHttps=url2.protocol==="https:",lib=isHttps?https:http3,{method="GET",headers={},body,timeoutMs=3e4}=options,req=lib.request({host:url2.hostname,port:url2.port||(isHttps?443:80),path:url2.pathname+url2.search,method,headers},res=>{let responseHeaders={};for(let[key,value]of Object.entries(res.headers))typeof value=="string"?responseHeaders[key]=value:Array.isArray(value)&&(responseHeaders[key]=value.join(", "));let chunks=[];res.on("data",chunk=>chunks.push(Buffer.from(chunk))),res.on("end",()=>{let bodyBuffer=Buffer.concat(chunks);resolve3({status:res.statusCode??0,statusText:res.statusMessage??"",headers:responseHeaders,body:bodyBuffer.toString("utf-8"),bodyBuffer})})});req.on("error",reject),req.setTimeout(timeoutMs,()=>{req.destroy(),reject(new Error(`Request timeout: ${urlStr}`))}),body&&req.write(body),req.end()})}async function getCookiesForUrl(session,targetUrl){let result=await session.client.sendCommand("Network.getCookies",{urls:[targetUrl]}),map2=new Map;for(let cookie of result.cookies??[])map2.set(cookie.name,cookie.value);return map2}function decodeTracknick(raw){if(!raw)return"";try{return decodeURIComponent(raw).replace(/\\u([0-9a-fA-F]{4})/g,(_match,hex3)=>String.fromCharCode(parseInt(hex3,16)))}catch{return raw}}function buildMultipartFormBody(fields){let boundary=`----mearl-${Date.now()}-${Math.random().toString(36).slice(2)}`,body=[...Object.entries(fields).map(([name,value])=>`--${boundary}\r
|
|
1021
|
+
</style><div id="surface"><div id="nav"><button id="back" type="button" aria-label="čŋå"><svg viewBox="0 0 28 28" aria-hidden="true"><path d="M19.5 3.5 9 14l10.5 10.5"/></svg></button><div id="title"></div></div></div>`;let surface=shadow.getElementById("surface"),title=shadow.getElementById("title"),back=shadow.getElementById("back");return back.addEventListener("click",onBack),{root,surface,title,back}},createStatusBarView=()=>{let root=document.createElement("div");root.setAttribute("data-mearl-app-statusbar",config2.profile),root.style.cssText=`position:fixed;left:0;right:0;top:0;height:${config2.statusBarHeight}px;z-index:2147483600;overflow:visible;box-sizing:border-box;pointer-events:none;`;let shadow=root.attachShadow({mode:"open"}),deviceModel=config2.globals.__DEVICE_MODEL__??"",legacyDynamicIsland=config2.platform==="iOS"&&/^iPhone(?:15|16|17|18),/.test(deviceModel),explicitCutout=config2.deviceAppearance?.cutout,cutoutKind=config2.platform!=="iOS"?"none":explicitCutout==="none"||explicitCutout==="dynamic-island"||explicitCutout==="notch"?explicitCutout:explicitCutout===void 0&&legacyDynamicIsland?"dynamic-island":"none",hasDynamicIsland=cutoutKind==="dynamic-island",cutoutMarkup=hasDynamicIsland?'<button id="device-cutout" type="button" data-state="idle"><svg id="cutout-camera" viewBox="0 0 20 20" aria-hidden="true"><path d="M6.5 5.5 7.7 3.8h4.6l1.2 1.7h2.2c1 0 1.8.8 1.8 1.8v7c0 1-.8 1.8-1.8 1.8H4.3c-1 0-1.8-.8-1.8-1.8v-7c0-1 .8-1.8 1.8-1.8z"/><circle cx="10" cy="10.5" r="3.2"/></svg><svg id="cutout-check" viewBox="0 0 20 20" aria-hidden="true"><path d="m4.5 10.5 3.2 3.2 7.8-7.8"/></svg></button>':cutoutKind==="notch"?'<span id="device-cutout" aria-hidden="true"></span>':"";shadow.innerHTML=`<style>
|
|
1022
|
+
:host{all:initial}
|
|
1023
|
+
#surface{position:relative;width:100%;height:calc(100% + 1px);box-sizing:border-box;color:#0f131a;-webkit-font-smoothing:antialiased;text-rendering:geometricPrecision}
|
|
1024
|
+
#surface[data-platform="ios"]{font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","Helvetica Neue","PingFang SC",sans-serif}
|
|
1025
|
+
#status{height:${config2.statusBarHeight}px;box-sizing:border-box;position:relative;display:flex;align-items:center;justify-content:space-between;padding:0 21px 0 27px;font-size:15px;font-weight:600;line-height:1;font-variant-numeric:tabular-nums;letter-spacing:-.25px}
|
|
1026
|
+
#time{min-width:54px;position:relative;z-index:1;text-align:left}
|
|
1027
|
+
#indicators{height:14px;display:flex;align-items:center;gap:6.5px;position:relative;z-index:1}
|
|
1028
|
+
#indicators svg{display:block;overflow:visible;fill:none;stroke:currentColor}
|
|
1029
|
+
#signal{width:18px;height:12px;fill:currentColor!important;stroke:none!important}
|
|
1030
|
+
#wifi{width:18px;height:14px;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
|
|
1031
|
+
#battery{width:28px;height:13px;stroke-width:1.25}
|
|
1032
|
+
#battery-outline{opacity:.42}#battery-level{fill:currentColor;stroke:none}#battery-cap{fill:currentColor;stroke:none;opacity:.45}
|
|
1033
|
+
#device-cutout{appearance:none;display:none;position:absolute;left:50%;border:0;padding:0;background:#000;color:#fff;z-index:2;pointer-events:none}
|
|
1034
|
+
#surface[data-cutout-kind="dynamic-island"] #device-cutout{display:var(--mearl-device-cutout-display,flex);align-items:center;justify-content:center;top:50%;transform:translate(-50%,-50%);width:126px;height:37px;border-radius:19px;box-shadow:inset 0 0 0 .5px rgba(255,255,255,.08);pointer-events:auto;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:width 320ms cubic-bezier(.34,1.56,.64,1),transform 160ms ease}
|
|
1035
|
+
#surface[data-cutout-kind="dynamic-island"] #device-cutout:active{transform:translate(-50%,-50%) scale(.97)}
|
|
1036
|
+
#surface[data-cutout-kind="dynamic-island"] #device-cutout:focus-visible{outline:2px solid #2563eb;outline-offset:2px}
|
|
1037
|
+
#surface[data-cutout-kind="dynamic-island"] #device-cutout[data-state="copied"],#surface[data-cutout-kind="dynamic-island"] #device-cutout[data-state="downloaded"],#surface[data-cutout-kind="dynamic-island"] #device-cutout[data-state="failed"]{width:154px;padding:0 10px;justify-content:space-between}
|
|
1038
|
+
#surface[data-cutout-kind="notch"] #device-cutout{display:block;top:0;transform:translateX(-50%);width:164px;height:31px;border-radius:0 0 18px 18px}
|
|
1039
|
+
#cutout-camera,#cutout-check{display:none;width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
|
|
1040
|
+
#device-cutout[data-state="copied"] #cutout-camera,#device-cutout[data-state="downloaded"] #cutout-camera,#device-cutout[data-state="failed"] #cutout-camera,#device-cutout[data-state="copied"] #cutout-check,#device-cutout[data-state="downloaded"] #cutout-check,#device-cutout[data-state="failed"] #cutout-check{display:block}
|
|
1041
|
+
@media(prefers-reduced-motion:reduce){#device-cutout{transition:none}}
|
|
1042
|
+
#surface[data-platform="android"]{font-family:Roboto,"Noto Sans SC",sans-serif}
|
|
1043
|
+
#surface[data-platform="android"] #status{padding:0 12px;font-size:12px;font-weight:500;letter-spacing:0}
|
|
1044
|
+
#surface[data-platform="android"] #indicators{gap:5px;transform:scale(.86);transform-origin:right center}
|
|
1045
|
+
</style><div id="surface" data-platform="${config2.platform.toLowerCase()}" data-cutout="${String(cutoutKind!=="none")}" data-cutout-kind="${cutoutKind}"><div id="status"><span id="time"></span>${cutoutMarkup}<span id="indicators" aria-hidden="true"><svg id="signal" viewBox="0 0 18 12"><rect x="0" y="8" width="3" height="4" rx="1"/><rect x="5" y="6" width="3" height="6" rx="1"/><rect x="10" y="3" width="3" height="9" rx="1"/><rect x="15" y="0" width="3" height="12" rx="1"/></svg><svg id="wifi" viewBox="1 3.8 22 17.2"><path d="M2 8.82a15 15 0 0 1 20 0"/><path d="M5 12.859a10 10 0 0 1 14 0"/><path d="M8.5 16.429a5 5 0 0 1 7 0"/><path d="M12 20h.01"/></svg><svg id="battery" viewBox="0 0 28 13"><rect id="battery-outline" x=".65" y=".65" width="23" height="11.7" rx="3.1"/><rect id="battery-level" x="2.35" y="2.35" width="19.6" height="8.3" rx="1.7"/><path id="battery-cap" d="M25 4.1c1.1.35 1.7 1.15 1.7 2.4s-.6 2.05-1.7 2.4z"/></svg></span></div></div>`;let surface=shadow.getElementById("surface"),time3=shadow.getElementById("time"),cutout=shadow.getElementById("device-cutout"),cutoutStatusPath=shadow.querySelector("#cutout-check path"),localizedScreenshotText=config2.language.toLowerCase().startsWith("zh")?{idle:"æĒåž",copied:"厞å¤åļ",downloaded:"厞ä¸čŊŊ",failed:"æĒåžå¤ąč´Ĩ"}:{idle:"Screenshot",copied:"Copied",downloaded:"Downloaded",failed:"Capture failed"},setCutoutState=state=>{cutout&&(cutout.dataset.state=state,cutout.setAttribute("aria-label",localizedScreenshotText[state]),cutout.title=localizedScreenshotText[state],cutoutStatusPath&&cutoutStatusPath.setAttribute("d",state==="failed"?"M5.5 5.5l9 9m0-9-9 9":"m4.5 10.5 3.2 3.2 7.8-7.8"))},screenshotPending=!1,screenshotBlob=data=>{let binary=atob(data),bytes=new Uint8Array(binary.length);for(let index=0;index<binary.length;index+=1)bytes[index]=binary.charCodeAt(index);return new Blob([bytes],{type:"image/png"})},downloadScreenshot=blob=>{let link=document.createElement("a"),objectUrl=URL.createObjectURL(blob);link.href=objectUrl,link.download=`mearl-screenshot-${new Date().toISOString().replace(/[:.]/g,"-")}.png`,link.style.display="none",document.body.appendChild(link),link.click(),link.remove(),window.setTimeout(()=>URL.revokeObjectURL(objectUrl),1e3)},captureScreenshot=async()=>{if(!cutout||screenshotPending||cutout.dataset.state!=="idle")return;screenshotPending=!0,cutout.setAttribute("aria-busy","true");let requestId=Date.now()*1e3+Math.floor(Math.random()*1e3),timeoutTimer=0,onResponse=null,image=new Promise((resolve3,reject)=>{let cleanup=()=>{timeoutTimer&&window.clearTimeout(timeoutTimer),onResponse&&window.removeEventListener("message",onResponse)};onResponse=event=>{if(event.source!==window)return;let message=event.data;if(!message||message.source!=="mearl-content"||message.type!=="APP_BRIDGE_SCREENSHOT_RESPONSE"||message.requestId!==requestId)return;cleanup();let result=message.result;result?.success===!0&&typeof result.data=="string"?resolve3({data:result.data}):reject(new Error(String(result?.error??"screenshot failed")))},window.addEventListener("message",onResponse),timeoutTimer=window.setTimeout(()=>{cleanup(),reject(new Error("screenshot timeout"))},35e3)}).then(result=>screenshotBlob(result.data)),clipboardWrite=null;if(navigator.clipboard?.write&&typeof ClipboardItem<"u")try{clipboardWrite=navigator.clipboard.write([new ClipboardItem({"image/png":image})]),clipboardWrite.catch(()=>{})}catch{clipboardWrite=null}window.postMessage({source:SRC,type:"screenshot",requestId},"*");try{let blob=await image;if(clipboardWrite)try{await clipboardWrite,setCutoutState("copied")}catch{downloadScreenshot(blob),setCutoutState("downloaded")}else downloadScreenshot(blob),setCutoutState("downloaded")}catch{setCutoutState("failed")}finally{screenshotPending=!1,cutout.setAttribute("aria-busy","false")}window.setTimeout(()=>{screenshotPending||setCutoutState("idle")},1600)};hasDynamicIsland&&cutout&&(setCutoutState("idle"),cutout.addEventListener("click",()=>void captureScreenshot()));let updateTime=()=>{let now=new Date;time3&&(time3.textContent=`${String(now.getHours()).padStart(2,"0")}:${String(now.getMinutes()).padStart(2,"0")}`)};return window.addEventListener("mearl:page-time-change",updateTime),updateTime(),{root,surface,timeTimer:window.setInterval(updateTime,3e4)}},install=()=>{let titleBar=config2.titleBar;if(!titleBar||!isContainerFrame||!simulateSystemBars)return;let observeState=()=>{new MutationObserver(syncSimulatedTitleBar).observe(document.head??document.documentElement,{subtree:!0,childList:!0,characterData:!0,attributes:!0,attributeFilter:["content","value"]}),window.addEventListener("popstate",syncSimulatedTitleBar),window.addEventListener("hashchange",syncSimulatedTitleBar),document.readyState==="loading"&&document.addEventListener("DOMContentLoaded",syncSimulatedTitleBar,{once:!0});try{let pushState=history.pushState.bind(history),replaceState=history.replaceState.bind(history);history.pushState=function(...args){pushState(...args),syncSimulatedTitleBar()},history.replaceState=function(...args){replaceState(...args),syncSimulatedTitleBar()}}catch{}};if(!isTop){observeState(),syncSimulatedTitleBar();return}let mount=()=>{if(titleBarRoot||!document.body)return;let totalHeight=config2.statusBarHeight+titleBar.navigationBarHeight,navigationView=createNavigationBarView("root",host.requestNativeBack),statusView=externalDeviceChrome||config2.statusBarHeight<=0?null:createStatusBarView(),spacer=document.createElement("div");if(spacer.setAttribute("data-mearl-app-titlebar-spacer",""),spacer.style.cssText=`display:block;width:100%;height:${totalHeight}px;min-height:${totalHeight}px;flex:none;`,spacer.style.setProperty("--mearl-app-navigation-bar-height",`${titleBar.navigationBarHeight}px`),document.body.insertBefore(spacer,document.body.firstChild),document.body.appendChild(navigationView.root),statusView&&document.body.appendChild(statusView.root),!externalDeviceChrome&&safeAreaInsets.bottom>0){let bottomRoot=document.createElement("div");bottomRoot.setAttribute("data-mearl-app-system-bottom",config2.profile),bottomRoot.style.cssText=`position:fixed;left:0;right:0;bottom:0;height:${safeAreaInsets.bottom}px;z-index:2147483600;box-sizing:border-box;pointer-events:none;color:#111111;`;let bottomShadow=bottomRoot.attachShadow({mode:"open"});bottomShadow.innerHTML=`<style>:host{all:initial}#surface{appearance:none;border:0;padding:0;width:166px;max-width:100%;height:24px;position:absolute;left:50%;bottom:0;transform:translateX(-50%);display:block;box-sizing:border-box;pointer-events:auto;color:#111;background:transparent;cursor:pointer;-webkit-tap-highlight-color:transparent}#surface:focus-visible{outline:2px solid #2563eb;outline-offset:-2px}#indicator{position:absolute;left:50%;bottom:8px;transform:translateX(-50%);width:134px;height:5px;border-radius:999px;background:currentColor;opacity:.92;transition:transform 120ms ease,opacity 120ms ease}#surface:hover #indicator{opacity:1;transform:translateX(-50%) scaleX(1.05)}#surface[data-platform="android"] #indicator{bottom:6px;width:108px;height:4px;opacity:.82}</style><button id="surface" type="button" aria-label="æåŧæĄĨæ¨Ąæé
įŊŽ" title="æĄĨæ¨Ąæé
įŊŽ" data-platform="${config2.platform.toLowerCase()}"><span id="indicator" aria-hidden="true"></span></button>`,document.body.appendChild(bottomRoot),systemBottomRoot=bottomRoot,systemBottomSurface=bottomShadow.getElementById("surface"),systemBottomSurface?.addEventListener("click",()=>{window.postMessage({source:SRC,type:"showBridgeConfig",profile:config2.profile,actions:config2.actions},"*")})}rootTitleBarView=navigationView,systemStatusView=statusView,titleBarRoot=navigationView.root,titleBarSpacer=spacer,syncSimulatedTitleBar(),observeState()};document.body?mount():document.addEventListener("DOMContentLoaded",mount,{once:!0})},service={initialLayerTitleBarState,resolvedTitleBarState,parseReportedTitleBarState,setPresentedRootTitleBarState:state=>{presentedRootTitleBarState=state,syncSimulatedTitleBar()},markStateExplicit:()=>{titleBarStateExplicit=!0},applyNavigationBarState,applyStatusBarState,createNavigationBarView,destroyNavigationBarView:view=>view?.root.remove(),syncLayerViewport,syncActiveSystemBars,syncSimulatedTitleBar};return install(),service}function installAppProfilePageTransport(config2,environment){let{SRC,TAG,log:log3}=environment,appToast=null,appToastHideTimer=null,appToastRemoveTimer=null;function showAppToast(params){let p=params&&typeof params=="object"?params:{},messageValue=[p.message,p.msg,p.content,p.text].find(value=>typeof value=="string"&&value.trim().length>0);if(typeof messageValue!="string")return"missing message";let durationValue=Number(p.milliseconds??p.duration),duration3=Number.isFinite(durationValue)&&durationValue>0?durationValue:2e3,hideAfter=Math.min(6e4,Math.max(300,Math.round(duration3)));appToastHideTimer!==null&&window.clearTimeout(appToastHideTimer),appToastRemoveTimer!==null&&window.clearTimeout(appToastRemoveTimer);let toast=appToast?.isConnected===!0?appToast:document.createElement("div");return toast!==appToast&&(appToast=toast,toast.setAttribute("data-mearl-app-toast",""),toast.setAttribute("role","status"),toast.setAttribute("aria-live","polite"),Object.assign(toast.style,{position:"fixed",left:"50%",top:"50%",zIndex:"2147483647",maxWidth:"calc(100vw - 64px)",boxSizing:"border-box",padding:"14px 20px",borderRadius:"12px",background:"rgba(20, 20, 20, 0.88)",color:"#ffffff",fontFamily:'-apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif',fontSize:"16px",fontWeight:"400",lineHeight:"24px",textAlign:"center",whiteSpace:"pre-wrap",overflowWrap:"anywhere",pointerEvents:"none",opacity:"0",transform:"translate(-50%, -50%) scale(0.96)",transition:"opacity 180ms ease, transform 180ms ease"}),(document.body??document.documentElement).appendChild(toast)),toast.textContent=messageValue,toast.style.opacity="0",toast.style.transform="translate(-50%, -50%) scale(0.96)",toast.offsetWidth,toast.style.opacity="1",toast.style.transform="translate(-50%, -50%) scale(1)",appToastHideTimer=window.setTimeout(()=>{appToastHideTimer=null,toast.style.opacity="0",toast.style.transform="translate(-50%, -50%) scale(0.96)",appToastRemoveTimer=window.setTimeout(()=>{appToastRemoveTimer=null,appToast===toast&&(appToast=null),toast.remove()},180)},hideAfter),null}let bridgeRequestSeq=0,pendingMtop={},pendingMtopStreams={},pendingUserInfo={};function callMtop(params,succ,fail){let id=++bridgeRequestSeq;pendingMtop[id]={succ,fail};let post=params.post,rawTimeout=params.timeout??params.timer,timeout=typeof rawTimeout=="number"?rawTimeout:typeof rawTimeout=="string"&&rawTimeout.trim()!==""?Number(rawTimeout):void 0,payload={...params,data:params.data!==void 0?params.data:params.param??{},method:params.method??(post===!0||post===1||post==="1"||post==="true"?"POST":"GET"),env:params.env??(/(^|\.)wapa\.taobao\.com$/i.test(location.hostname)?"pre":"online"),...Number.isFinite(timeout)&&{timeout}};window.postMessage({source:SRC,type:"mtop",requestId:id,payload},"*"),log3("mtop äģŖå â",params.api)}function callMtopAsync(params){return new Promise((resolve3,reject)=>callMtop(params,resolve3,reject))}function callMtopStream(params,succ,fail){let sessionId=typeof params.id=="string"?params.id:String(params.id??""),request=params.request&&typeof params.request=="object"?params.request:null;if(!sessionId||!request||typeof request.api!="string"){fail?.("invalid mtop_stream params");return}let requestId=++bridgeRequestSeq;pendingMtopStreams[requestId]={sessionId},window.postMessage({source:SRC,type:"mtopStream",requestId,payload:{...request,timeout:params.timeout,method:params.method??request.method,env:/(^|\.)wapa\.taobao\.com$/i.test(location.hostname)?"pre":"online"}},"*"),succ?.({}),log3("mtop æĩåŧäģŖå â",request.api)}function callUserInfo(fallback,succ){if(fallback.userId){succ?.(fallback);return}let requestId=++bridgeRequestSeq,timer=setTimeout(()=>{let pending=pendingUserInfo[requestId];pending&&(delete pendingUserInfo[requestId],pending.succ?.(pending.fallback))},1e3);pendingUserInfo[requestId]={fallback,succ,timer},window.postMessage({source:SRC,type:"userInfo",requestId},"*")}function emitMtopStreamEvent(sessionId,eventType,data){let detail=data&&typeof data=="object"?{...data,eventType}:{data,eventType};document.dispatchEvent(new CustomEvent(`mtop_stream${sessionId}`,{detail}))}function createUploadId(){try{if(typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch{}return`${Date.now()}-${Math.random().toString(36).slice(2)}`}function pickDirectUploadTarget(response){if(!response||typeof response!="object")return null;let data=response.data;if(data?.success===!1)return null;let result=data?.result,target=Array.isArray(result?.urls)?result.urls[0]:void 0;if(!target||typeof target!="object")return null;let item=target;if(typeof item.put!="string"||!item.put||typeof item.get!="string"||!item.get)return null;let rawHeaders=item.putHeaders&&typeof item.putHeaders=="object"?item.putHeaders:{},putHeaders=Object.fromEntries(Object.entries(rawHeaders).map(([key,value])=>[key,String(value)]));return{put:item.put,get:item.get,putHeaders}}async function uploadImage(file2){let uploader=config2.imagePicker;if(!uploader)throw new Error("åžįä¸äŧ čŊåæĒé
įŊŽ");let env=/(^|\.)wapa\.taobao\.com$/i.test(location.hostname)?"pre":"online",response=await callMtopAsync({api:uploader.api,v:uploader.version,method:"POST",env,timeout:6e4,data:{fcId:uploader.fcId,fcGroup:uploader.fcGroup,fcName:uploader.uploadUrlFunction,fcData:JSON.stringify({requestType:"url",mimes:[file2.type||"image/jpeg"],prefix:uploader.prefix,region:uploader.region,uploadNumber:1}),fcConfig:JSON.stringify({timeout:6e4,disasterRecover:!0})}}),target=pickDirectUploadTarget(response);if(!target)throw new Error("čˇååžįä¸äŧ å°åå¤ąč´Ĩ");let uploadUrl=`${target.put}${target.put.includes("?")?"&":"?"}getAvatar=1`,uploadResponse=await fetch(uploadUrl,{method:"PUT",headers:target.putHeaders,body:file2});if(uploadResponse.status!==200)throw new Error(`åžįį´äŧ å¤ąč´Ĩ: HTTP ${uploadResponse.status}`);return target.get}function openImagePicker(callbackCommandFn){let input=document.createElement("input");input.type="file",input.accept="image/*",input.style.display="none";let settled=!1,finish=()=>{settled=!0,input.remove()};input.addEventListener("cancel",finish,{once:!0}),input.addEventListener("change",()=>{let file2=input.files?.[0];if(!file2){finish();return}if(!file2.type.startsWith("image/")){finish(),console.error(TAG,"äģ
æ¯æéæŠåžįæäģļ");return}uploadImage(file2).then(pic=>{typeof callbackCommandFn=="function"&&callbackCommandFn({pic,uuid:createUploadId(),timeStamp:Date.now()}),log3("åžįéæŠåšļä¸äŧ åŽæ:",pic)}).catch(error48=>console.error(TAG,"åžįä¸äŧ å¤ąč´Ĩ:",error48)).finally(finish)},{once:!0}),(document.body??document.documentElement).appendChild(input),input.click(),window.addEventListener("focus",()=>{setTimeout(()=>{!settled&&!input.files?.length&&finish()},1e3)},{once:!0})}function showPaymentDialog(api,params,succeed,failed){document.querySelector('[data-mearl-payment-dialog="true"]')?.remove();let overlay=document.createElement("div");overlay.setAttribute("data-mearl-payment-dialog","true"),Object.assign(overlay.style,{position:"fixed",inset:"0",zIndex:"2147483647",display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.5)"});let card=document.createElement("div");Object.assign(card.style,{background:"#fff",borderRadius:"12px",padding:"24px",width:"300px",textAlign:"center",fontFamily:"system-ui, sans-serif"});let title=document.createElement("div");Object.assign(title.style,{fontSize:"17px",fontWeight:"600",marginBottom:"8px"}),title.textContent="æ¯äģįĄŽčŽ¤";let desc=document.createElement("div");Object.assign(desc.style,{fontSize:"14px",color:"#666",marginBottom:"20px"}),desc.textContent=`æ¨Ąæ ${api} æ¯äģīŧč¯ˇéæŠæäŊ`;let btnRow=document.createElement("div");Object.assign(btnRow.style,{display:"flex",gap:"12px"});let btnBase=(text,bg,color,action)=>{let btn=document.createElement("button");return btn.textContent=text,btn.setAttribute("data-mearl-action",action),Object.assign(btn.style,{flex:"1",padding:"10px 0",border:"none",borderRadius:"8px",fontSize:"15px",fontWeight:"500",cursor:"pointer",background:bg,color}),btn},confirmBtn=btnBase("åŽææ¯äģ","#1677ff","#fff","payment-confirm"),cancelBtn=btnBase("åæļæ¯äģ","#f5f5f5","#333","payment-cancel"),cleanup=()=>{overlay.remove()};confirmBtn.addEventListener("click",()=>{cleanup(),log3("፿ˇåŽææ¯äģ",api),succeed(api==="wx.requestPayment"?{errMsg:"requestPayment:ok"}:{ResultStatus:"9000",resultStatus:"9000"})}),cancelBtn.addEventListener("click",()=>{cleanup(),log3("፿ˇåæļæ¯äģ",api),failed(api==="wx.requestPayment"?{errMsg:"requestPayment:fail cancel"}:{ResultStatus:"6001",resultStatus:"6001"})}),btnRow.appendChild(cancelBtn),btnRow.appendChild(confirmBtn),card.appendChild(title),card.appendChild(desc),card.appendChild(btnRow),overlay.appendChild(card),(document.body??document.documentElement).appendChild(overlay)}function showMiniProgramActionDialog(action,params,confirmed,cancelled){document.querySelector('[data-mearl-mini-program-dialog="true"]')?.remove();let overlay=document.createElement("div");overlay.setAttribute("data-mearl-mini-program-dialog","true"),overlay.setAttribute("data-mearl-mini-program-action",action),Object.assign(overlay.style,{position:"fixed",inset:"0",zIndex:"2147483647",display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.5)"});let card=document.createElement("div");Object.assign(card.style,{background:"#fff",borderRadius:"12px",padding:"24px",width:"300px",textAlign:"center",fontFamily:"system-ui, sans-serif"});let title=document.createElement("div");Object.assign(title.style,{fontSize:"17px",fontWeight:"600",marginBottom:"8px"}),title.textContent=action==="navigateMiniProgram"?"æåŧå
ļäģå°į¨åē":"čŽĸé
æļæ¯";let desc=document.createElement("div");Object.assign(desc.style,{fontSize:"14px",color:"#666",marginBottom:"20px"});let targetTitle=params.title?.trim()||"å
ļäģ";desc.textContent=action==="navigateMiniProgram"?`åŗå°æåŧâ${targetTitle}âå°į¨åēīŧæ¯åĻįģ§įģīŧ`:"æ¨ĄæåžŽäŋĄčŽĸé
æļæ¯ææīŧč¯ˇéæŠæäŊ";let btnRow=document.createElement("div");Object.assign(btnRow.style,{display:"flex",gap:"12px"});let createButton=(text,background,color,actionName)=>{let button=document.createElement("button");return button.textContent=text,button.setAttribute("data-mearl-action",actionName),Object.assign(button.style,{flex:"1",padding:"10px 0",border:"none",borderRadius:"8px",fontSize:"15px",fontWeight:"500",cursor:"pointer",background,color}),button},confirmButton=createButton(action==="navigateMiniProgram"?"įĄŽåŽ":"å
莸","#1677ff","#fff","mini-program-confirm"),cancelButton=createButton("åæļ","#f5f5f5","#333","mini-program-cancel"),cleanup=()=>overlay.remove();confirmButton.addEventListener("click",()=>{cleanup();let result=action==="navigateMiniProgram"?{errMsg:"navigateToMiniProgram:ok"}:{result:"SUCCESS",data:{totalCount:1,acceptCount:1}};log3("፿ˇįĄŽčޤå°į¨åēåįčŊå",action,params.appId??params.scene??""),confirmed(result)}),cancelButton.addEventListener("click",()=>{cleanup();let result=action==="navigateMiniProgram"?{errMsg:"navigateToMiniProgram:fail cancel"}:{result:"CLOSE_BY_USER"};log3("፿ˇåæļå°į¨åēåįčŊå",action),cancelled(result)}),btnRow.appendChild(cancelButton),btnRow.appendChild(confirmButton),card.appendChild(title),card.appendChild(desc),card.appendChild(btnRow),overlay.appendChild(card),(document.body??document.documentElement).appendChild(overlay)}function handleMessage(msg){if(msg.source==="mearl-content"&&msg.type==="APP_BRIDGE_MTOP_RESPONSE"){let pending=pendingMtop[msg.requestId];if(!pending)return!0;delete pendingMtop[msg.requestId];let result=msg.result;return result?.success?pending.succ?.(result.response):pending.fail?.(result?.error??"mtop delegate failed"),!0}if(msg.source==="mearl-content"&&msg.type==="APP_BRIDGE_USER_INFO_RESPONSE"){let requestId=msg.requestId,pending=pendingUserInfo[requestId];if(!pending)return!0;delete pendingUserInfo[requestId],clearTimeout(pending.timer);let result=msg.result,response=result?.success&&result.response&&typeof result.response=="object"?result.response:{};return pending.succ?.({...pending.fallback,...response}),!0}if(msg.source==="mearl-content"&&msg.type==="APP_BRIDGE_MTOP_STREAM_EVENT"){let requestId=msg.requestId,pending=pendingMtopStreams[requestId];if(!pending)return!0;let eventType=msg.eventType;return emitMtopStreamEvent(pending.sessionId,eventType,msg.data),(eventType==="onFinish"||eventType==="onError")&&delete pendingMtopStreams[requestId],!0}return!1}return{showAppToast,callMtop,callMtopStream,callUserInfo,openImagePicker,showPaymentDialog,showMiniProgramActionDialog,handleMessage}}function installAppProfileBridgeProtocol(config2,environment,host){let{w,SRC,TAG,isTop,log:log3}=environment,{pageTransport,systemBars,requestOpen,requestClose,requestCloseAll,requestContainerData}=host,{showAppToast,callMtop,callMtopStream,callUserInfo,openImagePicker,showPaymentDialog,showMiniProgramActionDialog}=pageTransport,{applyNavigationBarState,applyStatusBarState,syncSimulatedTitleBar}=systemBars,NOT_IMPLEMENTED_PAYLOAD=JSON.stringify({ret:["HY_FAILED"],msg:"not implemented"}),FPT_STORAGE_KEY=`__mearl_app_fpt__:${config2.profile}`,CALENDAR_STORAGE_KEY=`__mearl_app_calendar_events__:${config2.profile}`,unsupportedNativeInputNotified=!1,stopNetworkQualityMonitor=null,simulatedPageHidden=!1,simulatedVisibilityInstalled=!1,hasPendingMiniProgramBackData=!1,pendingMiniProgramBackData,notificationListeners=new Map,megaListenerSeq=0,megaBroadcastListeners=new Map,megaLifeCycleListeners=new Set,megaPageCloseListeners=new Set,megaSystemBackListener=null,megaKVMutationVersion=0,MEGA_KV_TOTAL_SIZE=5*1024*1024,MEGA_KV_STORAGE_KEY=`__mearl_mega_kv__:${config2.profile}`;function readMegaKVStorage(){let storage=new Map;try{let parsed=JSON.parse(localStorage.getItem(MEGA_KV_STORAGE_KEY)??"{}");if(!parsed||typeof parsed!="object"||Array.isArray(parsed))return storage;for(let[bizId,rawEntries]of Object.entries(parsed)){if(!rawEntries||typeof rawEntries!="object"||Array.isArray(rawEntries))continue;let entries=new Map;for(let[key,value]of Object.entries(rawEntries))typeof value=="string"&&entries.set(key,value);storage.set(bizId,entries)}}catch{}return storage}let megaKVStorage=readMegaKVStorage();function megaKVSnapshot(){let snapshot={};for(let[bizId,values]of megaKVStorage)snapshot[bizId]=Object.fromEntries(values);return snapshot}function persistMegaKVStorage(){try{localStorage.setItem(MEGA_KV_STORAGE_KEY,JSON.stringify(megaKVSnapshot()))}catch{}}function replaceMegaKVStorage(value){if(!(!value||typeof value!="object"||Array.isArray(value))){megaKVStorage.clear();for(let[bizId,rawEntries]of Object.entries(value)){if(!rawEntries||typeof rawEntries!="object"||Array.isArray(rawEntries))continue;let entries=new Map;for(let[key,entryValue]of Object.entries(rawEntries))typeof entryValue=="string"&&entries.set(key,entryValue);megaKVStorage.set(bizId,entries)}persistMegaKVStorage()}}function applyMegaKVMutation(payload){let operation=typeof payload.operation=="string"?payload.operation:"",bizId=typeof payload.bizId=="string"?payload.bizId:"",key=typeof payload.key=="string"?payload.key:"";if(bizId){if(operation==="set"&&key&&typeof payload.value=="string"){let entries=megaKVStorage.get(bizId)??new Map;entries.set(key,payload.value),megaKVStorage.set(bizId,entries)}else if(operation==="remove"&&key){let entries=megaKVStorage.get(bizId);entries?.delete(key),entries?.size===0&&megaKVStorage.delete(bizId)}else if(operation==="clear")megaKVStorage.delete(bizId);else return;megaKVMutationVersion+=1,persistMegaKVStorage()}}function emitMegaCallback(callback,value){callback&&setTimeout(()=>callback(value),0)}function megaBroadcastBizId(value){return typeof value=="string"&&value?value:"__MEGA_GLOBAL_MESSAGE__"}function dispatchMegaBroadcast(payload){let bizId=megaBroadcastBizId(payload.bizId),eventName=typeof payload.eventName=="string"?payload.eventName:"";if(eventName)for(let listener of Array.from(megaBroadcastListeners.values()))listener.bizId!==bizId||listener.eventName!==eventName||(listener.once&&megaBroadcastListeners.delete(listener.id),emitMegaCallback(listener.callback,{statusCode:1,type:"onEvent",data:{detail:payload.detail}}),listener.once&&emitMegaCallback(listener.callback,{statusCode:99,type:"finish"}))}let documentPrototype=typeof Document=="function"?Document.prototype:null,nativeHiddenDescriptor=documentPrototype?Object.getOwnPropertyDescriptor(documentPrototype,"hidden"):void 0,nativeVisibilityDescriptor=documentPrototype?Object.getOwnPropertyDescriptor(documentPrototype,"visibilityState"):void 0;function installSimulatedVisibilityState(){if(!simulatedVisibilityInstalled){simulatedVisibilityInstalled=!0;try{Object.defineProperty(document,"hidden",{configurable:!0,get:()=>simulatedPageHidden||!!(nativeHiddenDescriptor?.get?.call(document)??!1)}),Object.defineProperty(document,"visibilityState",{configurable:!0,get:()=>simulatedPageHidden?"hidden":nativeVisibilityDescriptor?.get?.call(document)??"visible"})}catch{}}}function dispatchPageTransitionEvent(type){try{let event=typeof PageTransitionEvent=="function"?new PageTransitionEvent(type,{persisted:!1}):new Event(type);window.dispatchEvent(event)}catch{}}function dispatchActiveEvents(){for(let name of config2.activeEvents)try{document.dispatchEvent(new Event(name))}catch{}}function handlePageVisibility(hidden){if(hidden===simulatedPageHidden)return;installSimulatedVisibilityState(),simulatedPageHidden=hidden;let lifeCycleType=hidden?"onPageDisappear":"onPageAppear";for(let callback of megaLifeCycleListeners)emitMegaCallback(callback,{statusCode:1,type:lifeCycleType,data:{pageId:location.href}});try{document.dispatchEvent(new Event("visibilitychange"))}catch{}if(hidden){try{window.dispatchEvent(new Event("blur"))}catch{}dispatchPageTransitionEvent("pagehide");return}dispatchPageTransitionEvent("pageshow");try{window.dispatchEvent(new Event("focus"))}catch{}dispatchActiveEvents()}function resolveWindowFunction(path23){let parts=path23.split(".").filter(Boolean),owner=w;for(let index=0;index<parts.length-1;index+=1){let next=owner[parts[index]];if(!next||typeof next!="object")return null;owner=next}let fn=owner[parts[parts.length-1]];return typeof fn=="function"?fn.bind(owner):null}function handleNativeBack(){let megaHandled=!1;for(let callback of megaPageCloseListeners)megaHandled=!0,emitMegaCallback(callback,{statusCode:1,type:"onClose",data:{}});if(megaSystemBackListener&&(megaHandled=!0,emitMegaCallback(megaSystemBackListener,{statusCode:1,type:"onSuccess",data:{}})),megaHandled)return!0;let nativeBack=config2.nativeBack;if(!nativeBack)return!1;if(nativeBack.handler){let handler=resolveWindowFunction(nativeBack.handler);if(!handler)return!1;try{return handler(),!0}catch{return!1}}let controlled=!1;if(nativeBack.controlFunction){let control=resolveWindowFunction(nativeBack.controlFunction);if(!control)return!1;try{controlled=control()===!0}catch{return!1}if(!controlled)return!1}if(!nativeBack.event)return controlled;try{let event=new Event(nativeBack.event,{cancelable:!0});return document.dispatchEvent(event),controlled||event.defaultPrevented}catch{return controlled}}function handleAppMessage(message){if(!message||typeof message!="object")return;let payload=message;if(payload.kind==="megaBroadcast"){dispatchMegaBroadcast(payload);return}if(payload.kind==="megaKVStorage"){applyMegaKVMutation(payload);return}if(payload.kind==="legacyBroadcast"&&typeof payload.instanceId=="string"){try{let event=new CustomEvent(`Broadcast.Message.${payload.instanceId}`,{detail:payload.message});Object.defineProperty(event,"param",{configurable:!0,value:payload.message}),document.dispatchEvent(event)}catch{}return}if(payload.kind==="notification"&&typeof payload.name=="string"){let listener=notificationListeners.get(payload.name);listener&&setTimeout(()=>listener(payload.data),0);return}if(!(payload.kind!=="message"||!config2.messageEvent))try{document.dispatchEvent(new CustomEvent(config2.messageEvent,{detail:{data:payload.data}}))}catch{}}function sendAppMessage(message){if(isTop){handleAppMessage(message);return}window.top?.postMessage({source:SRC,type:"appMessageToOpener",message},"*")}function applyRuntimeResponses(responses){let current=config2.actions.responses??{};for(let[api,response]of Object.entries(responses))!response||typeof response!="object"||Array.isArray(response)||(current[api]=response);config2.actions.responses=current}function parseFpt(value){let entries=[],normalized=value.trim();if(!normalized)return entries;let pattern=/([0-9A-Za-z._-]+)\(([0-9A-Za-z._-]+)\)/g,consumed="";for(let match of normalized.matchAll(pattern))consumed+=match[0],entries.push([match[1],match[2]]);return consumed===normalized?entries:[]}function setFptEntry(entries,key,value){entries.delete(key),entries.set(key,value)}function readInitialFptEntries(){let entries=new Map;try{for(let[key,value]of parseFpt(sessionStorage.getItem(FPT_STORAGE_KEY)??""))setFptEntry(entries,key,value)}catch{}try{let currentFpt=new URL(location.href).searchParams.get("fpt")??"";for(let[key,value]of parseFpt(currentFpt))setFptEntry(entries,key,value)}catch{}return entries}let fptEntries=readInitialFptEntries();function serializeFpt(entries){return Array.from(entries,([key,value])=>`${key}(${value})`).join("")}function persistFpt(){try{let value=serializeFpt(fptEntries);value?sessionStorage.setItem(FPT_STORAGE_KEY,value):sessionStorage.removeItem(FPT_STORAGE_KEY)}catch{}}function decorateUrlWithFpt(rawUrl){let targetUrl=mapScheme(rawUrl)??rawUrl;if(fptEntries.size===0)return targetUrl;try{let url2=new URL(targetUrl,location.href);if(url2.protocol!=="http:"&&url2.protocol!=="https:")return targetUrl;let merged=new Map(fptEntries);for(let[key,value]of parseFpt(url2.searchParams.get("fpt")??""))setFptEntry(merged,key,value);return url2.searchParams.set("fpt",serializeFpt(merged)),url2.href}catch{return targetUrl}}function classify(api){let a=config2.actions;return a.open.includes(api)?"open":a.close.includes(api)?"close":a.title.includes(api)?"title":a.navigationBar?.includes(api)?"navigationBar":a.statusBar?.includes(api)?"statusBar":a.systemInfo.includes(api)?"systemInfo":a.mtop.includes(api)?"mtop":a.kvGet?.includes(api)?"kvGet":a.kvSet?.includes(api)?"kvSet":a.kvDelete?.includes(api)?"kvDelete":a.pageContext?.includes(api)?"pageContext":a.responses&&Object.prototype.hasOwnProperty.call(a.responses,api)?"response":a.behaviors&&Object.prototype.hasOwnProperty.call(a.behaviors,api)?a.behaviors[api]:a.noop.includes(api)?"noop":"unknown"}function pickUrl(params){if(!params||typeof params!="object")return null;let p=params,candidates=[p.url,p.data?.url,p.param?.url,p.value?.params?.url];for(let c of candidates)if(typeof c=="string"&&c)return c;return null}function pickCloseData(params){if(params&&typeof params=="object"){let p=params;if("data"in p&&p.data!==void 0)return p.data;if(Object.keys(p).length>0)return p}}function decodeCookieValue2(raw){let value=raw;for(let i=0;i<2;i+=1)try{let decoded=decodeURIComponent(value);if(decoded===value)break;value=decoded}catch{break}return value.replace(/\\u([0-9a-f]{4})/gi,(_match,hex3)=>String.fromCharCode(Number.parseInt(hex3,16)))}function readCookie(name){let prefix=`${name}=`,pair=document.cookie.split(";").map(value=>value.trim()).find(value=>value.startsWith(prefix));return pair?decodeCookieValue2(pair.slice(prefix.length)):""}function readUserCookie(name){let pageUserCookie=w.userCookie;if(!pageUserCookie||typeof pageUserCookie!="object")return"";let value=pageUserCookie[name];return typeof value=="string"?decodeCookieValue2(value):""}function readFirstUserCookie(names){for(let name of names){let value=readCookie(name)||readUserCookie(name);if(value&&value!=="null")return value}return""}let cbSeq=0,callbacks={};function stashCallback(fn){if(typeof fn!="function")return 0;let id=++cbSeq;return callbacks[id]=fn,id}function extractQuery(url2,param){let q=url2.indexOf("?");if(q===-1)return null;for(let pair of url2.slice(q+1).split("&")){let eq=pair.indexOf("=");if(eq>0&&pair.slice(0,eq)===param)return pair.slice(eq+1)}return null}function matchesHostSuffix(hostname3,suffixes){if(!suffixes?.length)return!0;let normalizedHost=hostname3.toLowerCase().replace(/\.$/,"");return suffixes.some(value=>{let suffix=value.toLowerCase().replace(/^\./,"").replace(/\.$/,"");return normalizedHost===suffix||normalizedHost.endsWith(`.${suffix}`)})}function matchesRouteHost(rawUrl,suffixes){if(!suffixes?.length)return!0;try{let parsed=new URL(rawUrl,location.href),hostname3=parsed.protocol==="http:"||parsed.protocol==="https:"?parsed.hostname:location.hostname;return matchesHostSuffix(hostname3,suffixes)}catch{return matchesHostSuffix(location.hostname,suffixes)}}function resolveSchemeValue(raw,depth){if(depth>3)return null;let value=raw;try{value=decodeURIComponent(raw)}catch{}if(value.startsWith("{"))try{let found=pickUrl(JSON.parse(value));if(!found)return null;value=found}catch{return null}if(/^https?:/i.test(value))return value;if(/^[a-z][a-z0-9+.-]*:/i.test(value))return mapScheme(value,depth+1);let nestedUrl=extractQuery(value,"url");return nestedUrl?resolveSchemeValue(nestedUrl,depth+1):null}function mapScheme(url2,depth=0){if(depth>3)return null;let lower=url2.toLowerCase();for(let rule of config2.schemes){if(!matchesRouteHost(url2,rule.hostSuffixes))continue;let normalizedMatch=rule.match.toLowerCase(),matchedUrl=url2;if(!lower.startsWith(normalizedMatch)){if(!normalizedMatch.startsWith("/"))continue;try{let parsed=new URL(url2,location.href);if(matchedUrl=`${parsed.pathname}${parsed.search}${parsed.hash}`,!matchedUrl.toLowerCase().startsWith(normalizedMatch))continue}catch{continue}}if(rule.targetPath){let suffix=matchedUrl.slice(rule.match.length);if(suffix&&!suffix.startsWith("?")&&!suffix.startsWith("#"))continue;try{let source=new URL(matchedUrl),origin=location.origin;if(rule.targetHostPrefix){let hostname3=location.hostname.toLowerCase(),domainSuffix=hostname3==="wapa.taobao.com"||hostname3.endsWith(".wapa.taobao.com")?"wapa.taobao.com":hostname3==="m.taobao.com"||hostname3.endsWith(".m.taobao.com")?"m.taobao.com":"";domainSuffix&&(origin=`https://${rule.targetHostPrefix}.${domainSuffix}`)}let target=new URL(rule.targetPath,`${origin}/`);target.search=source.search,target.hash=source.hash;for(let[key,value]of Object.entries(rule.targetParams??{}))target.searchParams.has(key)||target.searchParams.set(key,value);return target.href}catch{return null}}if(!rule.param)continue;let raw=extractQuery(matchedUrl,rule.param);if(!raw)return null;let resolved=resolveSchemeValue(raw,depth);if(!resolved||!rule.useCurrentOrigin)return resolved;try{let target=new URL(resolved);return`${location.origin}${target.pathname}${target.search}${target.hash}`}catch{return resolved}}return null}function firstRouteParam(params,names){for(let name of names){let value=params.get(name);if(value)return value}return""}function resolvePaymentCallbackUrl(rawUrl,paymentPageUrl,useCurrentOrigin,forwardParams,resultParam){if(!rawUrl)return null;try{let target=new URL(rawUrl,location.href);for(let name of forwardParams){let value=paymentPageUrl.searchParams.get(name);value&&!target.searchParams.get(name)&&target.searchParams.set(name,value)}resultParam&&target.searchParams.set(resultParam.name,JSON.stringify(resultParam.value));let resolved=useCurrentOrigin&&(target.protocol==="http:"||target.protocol==="https:")?`${location.origin}${target.pathname}${target.search}${target.hash}`:target.href;return decorateUrlWithFpt(resolved)}catch{return null}}function openPaymentCallback(rawUrl,paymentPageUrl,useCurrentOrigin,forwardParams,resultParam){let target=resolvePaymentCallbackUrl(rawUrl,paymentPageUrl,useCurrentOrigin,forwardParams,resultParam);target&&requestOpen(target,0,!1)}function handleMiniProgramPaymentRoute(rawUrl){let paymentPageUrl;try{paymentPageUrl=new URL(rawUrl,location.href)}catch{return!1}let normalizedPathname=paymentPageUrl.pathname.replace(/\/+$/,"")||"/",rule=config2.miniProgram?.paymentRoutes?.find(candidate=>(candidate.pathname.replace(/\/+$/,"")||"/")===normalizedPathname&&matchesHostSuffix(paymentPageUrl.hostname,candidate.hostSuffixes));if(!rule)return!1;let successUrl=firstRouteParam(paymentPageUrl.searchParams,rule.successUrlParams),failureUrl=firstRouteParam(paymentPageUrl.searchParams,rule.failureUrlParams),forwardParams=rule.forwardParams??[],useCurrentOrigin=rule.useCurrentOrigin===!0,paymentParams;try{let parsed=JSON.parse(paymentPageUrl.searchParams.get(rule.paymentParamsParam)??"");if(!parsed||typeof parsed!="object"||Array.isArray(parsed))throw new Error;paymentParams=parsed,paymentParams.timeStamp!==void 0&&(paymentParams.timeStamp=String(paymentParams.timeStamp))}catch{return log3("垎äŋĄæ¯äģåæ°č§Ŗæå¤ąč´Ĩīŧæ§čĄå¤ąč´Ĩå莺",rawUrl),openPaymentCallback(failureUrl,paymentPageUrl,useCurrentOrigin,forwardParams),!0}return showPaymentDialog("wx.requestPayment",paymentParams,result=>{openPaymentCallback(successUrl,paymentPageUrl,useCurrentOrigin,forwardParams,rule.successResultParam?{name:rule.successResultParam,value:result}:void 0)},()=>{openPaymentCallback(failureUrl,paymentPageUrl,useCurrentOrigin,forwardParams)}),!0}function finishMiniProgramNativeRoute(action,result,storageId){handleResume({data:action==="subscribeMessage"?result:void 0,storageId,callbackId:0,final:!0})}function handleMiniProgramNativeRoute(rawUrl){let nativePageUrl;try{nativePageUrl=new URL(rawUrl,location.href)}catch{return!1}let normalizedPathname=nativePageUrl.pathname.replace(/\/+$/,"")||"/",action=nativePageUrl.searchParams.get("action");if(action!=="navigateMiniProgram"&&action!=="subscribeMessage"||!config2.miniProgram?.nativeRoutes?.find(candidate=>(candidate.pathname.replace(/\/+$/,"")||"/")===normalizedPathname&&candidate.actions.includes(action)&&matchesHostSuffix(nativePageUrl.hostname,candidate.hostSuffixes)))return!1;let params={};nativePageUrl.searchParams.forEach((value,name)=>{params[name]=value});let storageId=nativePageUrl.searchParams.get("__storage_id");return handlePageVisibility(!0),showMiniProgramActionDialog(action,params,result=>finishMiniProgramNativeRoute(action,result,storageId),result=>finishMiniProgramNativeRoute(action,result,storageId)),!0}function handleMiniProgramPostMessage(data){let rules=config2.miniProgram?.messageRules;if(!rules?.length)return!1;let messages=Array.isArray(data)?data:[data],handled=!1;for(let value of messages){if(!value||typeof value!="object"||Array.isArray(value))continue;let message=value;if(typeof message.type!="string")continue;let rule=rules.find(candidate=>candidate.type===message.type&&matchesHostSuffix(location.hostname,candidate.hostSuffixes));rule&&(handled=!0,rule.action==="stageBackData"?(pendingMiniProgramBackData=message.data,hasPendingMiniProgramBackData=!0):rule.action==="closeAll"&&(isTop?requestCloseAll(message.data)||requestClose(message.data):window.top?.postMessage({source:SRC,type:"closeAll",data:message.data},"*")))}return handled}function matchesImagePickerScheme(url2){let lower=url2.toLowerCase();return config2.imagePicker?.schemes.some(scheme=>lower.startsWith(scheme))===!0}function handleMaybeScheme(url2){if(typeof url2!="string"||!url2||!/^[a-z][a-z0-9+.-]*:/i.test(url2)||/^(https?|about|blob|data|javascript):/i.test(url2))return!1;let mapped=mapScheme(url2);return mapped?(log3("scheme æ å°ä¸ē H5 open:",url2,"â",mapped),requestOpen(decorateUrlWithFpt(mapped),0,!1)):log3("å¤é¨ scheme 厞æĻæĒīŧįæē襨į°ä¸ēå¤į̝īŧ:",url2),!0}function handleResume(msg){let{data,storageId,callbackId,final,gotoEvent,silent}=msg;if(gotoEvent&&dispatchGotoEvent(data),callbackId&&callbacks[callbackId]){if(!silent)try{callbacks[callbackId]({backdata:data})}catch(e){console.error(TAG,"callbackCommand æ§čĄå¤ąč´Ĩ",e)}final&&delete callbacks[callbackId]}if(data&&typeof data=="object"&&storageId)try{let d={...data};d.__$data=!0,d.__$storageId=String(storageId),localStorage.setItem("XPI_BACK_LISTENER_DATA_STORAGE",JSON.stringify(d))}catch{}simulatedPageHidden?handlePageVisibility(!1):dispatchActiveEvents()}function dispatchGotoEvent(data){if(data!==void 0)try{document.dispatchEvent(new CustomEvent("WV.GotoEvent",{detail:{data}}))}catch{}}function sendUserTrack(params){if(!params||typeof params!="object")return;let p=params,logkey=typeof p.logkey=="string"?p.logkey:"",gmkey=typeof p.gmkey=="string"?p.gmkey:typeof p.event=="string"?p.event:"",gokey=typeof p.gokey=="string"?p.gokey:"";if(!/^\/[0-9A-Za-z._/-]+$/.test(logkey)||!/^[0-9A-Za-z_-]+$/.test(gmkey))return;let pageWindow=w,aplus=pageWindow.goldlog??pageWindow.aplus;if(typeof aplus?.send!="function")return;let configuredHost=aplus.getMetaInfo?.("aplus-rhost-g"),host2=(typeof configuredHost=="string"?configuredHost:"gm.mmstat.com").replace(/^https?:\/\//i,"").replace(/^\/\//,"").split("/")[0];if(!(!host2||!/^[0-9A-Za-z.-]+$/.test(host2)))try{aplus.send(`//${host2}${logkey}`,`gmkey=${encodeURIComponent(gmkey)}&gokey=${gokey}&ts=${Date.now()}`,"GET")}catch{}}function readNetworkState(){let connection=navigator.connection;return navigator.onLine?connection?.type==="wifi"?"wifi":connection?.effectiveType??"unknown":"fail"}function networkTypeNumber(state){return{wifi:2,"slow-2g":3,"2g":3,"3g":4,"4g":5,"5g":6,fail:7}[state]??0}function calendarTimestamp(value){if(typeof value=="number"&&Number.isFinite(value))return value;if(typeof value!="string"||!value.trim())return null;let numeric=Number(value);if(Number.isFinite(numeric)&&numeric>0)return numeric;let parsed=Date.parse(value);return Number.isFinite(parsed)?parsed:null}function calendarEventFromParams(params){let p=params&&typeof params=="object"?params:{},stringValue=(...values)=>values.find(value=>typeof value=="string")??"";return{title:stringValue(p.calendar_title,p.title),startTime:calendarTimestamp(p.calendar_start_ms??p.start_time??p.calendar_start_datetime),endTime:calendarTimestamp(p.calendar_end_ms??p.end_time??p.calendar_end_datetime),url:stringValue(p.calendar_url,p.url),note:stringValue(p.calendar_note,p.note),location:stringValue(p.calendar_location,p.location)}}function readCalendarEvents(){try{let parsed=JSON.parse(localStorage.getItem(CALENDAR_STORAGE_KEY)??"[]");return Array.isArray(parsed)?parsed.filter(event=>event!==null&&typeof event=="object"&&typeof event.title=="string"):[]}catch{return[]}}function writeCalendarEvents(events){try{return localStorage.setItem(CALENDAR_STORAGE_KEY,JSON.stringify(events)),!0}catch{return!1}}function sameCalendarEvent(stored,candidate){return candidate.url?stored.url===candidate.url:!!candidate.title&&stored.title===candidate.title&&(candidate.startTime===null||stored.startTime===candidate.startTime)&&(candidate.endTime===null||stored.endTime===candidate.endTime)}function calendarEventResponse(event){return{title:event.title,start_time:event.startTime,end_time:event.endTime,url:event.url,note:event.note,location:event.location}}function dispatch(api,params,onSuccess,onFailure,callbackCommandFn){let succeed=value=>{onSuccess&&setTimeout(()=>onSuccess(value),0)},failed=reason=>{onFailure&&setTimeout(()=>onFailure(reason),0)},kind=classify(api),silent=config2.actions.silent?.includes(api)===!0;if(silent||log3("æĄĨč°į¨",api,`(${kind})`,params??""),kind==="open"||kind==="navigate"){let p=params&&typeof params=="object"?params:{},navigationData=p.data&&typeof p.data=="object"?p.data:void 0;if(kind==="navigate"&&navigationData?.type==="back"){isTop?requestCloseAll(navigationData.data,!0)||dispatchGotoEvent(navigationData.data):window.top?.postMessage({source:SRC,type:"closeAll",data:navigationData.data,gotoEvent:!0},"*"),succeed({});return}let url2=pickUrl(params);if(!url2){failed("missing url");return}if(matchesImagePickerScheme(url2)){openImagePicker(callbackCommandFn),succeed({});return}if(handleMiniProgramPaymentRoute(url2)){succeed({});return}if(handleMiniProgramNativeRoute(url2)){succeed({});return}let wd=p.useWebdialog===!0||p.useWebdialog==="true"||p.useWebdialog===1||p.useWebdialog==="1";requestOpen(decorateUrlWithFpt(url2),stashCallback(callbackCommandFn),wd,p),succeed({});return}if(kind==="closeAll"){isTop?requestCloseAll(void 0):window.top?.postMessage({source:SRC,type:"closeAll"},"*"),succeed({});return}if(kind==="closeBackData"){let p=params&&typeof params=="object"?params:{};requestClose(Object.prototype.hasOwnProperty.call(p,"backdata")?p.backdata:pickCloseData(p)),succeed({});return}if(kind==="close"){if(api==="navigateBack"&&hasPendingMiniProgramBackData){let data=pendingMiniProgramBackData;pendingMiniProgramBackData=void 0,hasPendingMiniProgramBackData=!1,requestClose(data)}else requestClose(pickCloseData(params));succeed({});return}if(kind==="postMessage"){let p=params&&typeof params=="object"?params:{},data=p.data??p;handleMiniProgramPostMessage(data)||sendAppMessage({kind:"message",data}),succeed({});return}if(kind==="notifySubscribe"){let p=params&&typeof params=="object"?params:{};if(typeof p.name!="string"||!p.name){failed("missing notification name");return}onSuccess&¬ificationListeners.set(p.name,onSuccess);return}if(kind==="notifyUnsubscribe"){let p=params&&typeof params=="object"?params:{};typeof p.name=="string"&¬ificationListeners.delete(p.name),succeed({});return}if(kind==="notifyPost"){let p=params&&typeof params=="object"?params:{};if(typeof p.name!="string"||!p.name){failed("missing notification name");return}sendAppMessage({kind:"notification",name:p.name,data:p.data}),succeed({});return}if(kind==="sharedFileRead"||kind==="sharedFileWrite"||kind==="sharedDataGet"||kind==="sharedDataSet"){requestContainerData(kind,params&&typeof params=="object"?params:{},succeed,failed);return}if(kind==="legacyBroadcastCreate"||kind==="legacyBroadcastPost"||kind==="legacyBroadcastClose"){requestContainerData(kind,params&&typeof params=="object"?params:{},succeed,failed);return}if(kind==="title"){let title=params&&typeof params=="object"?params.title??params.name:void 0;if(typeof title=="string"&&title){systemBars.markStateExplicit();try{document.title=title,syncSimulatedTitleBar()}catch{}isTop||window.top?.postMessage({source:SRC,type:"title",title},"*")}succeed({});return}if(kind==="navigationBar"){applyNavigationBarState(api,params),succeed({});return}if(kind==="statusBar"){applyStatusBarState(params),succeed({});return}if(kind==="systemInfo"){let model=config2.globals.__DEVICE_MODEL__||"iPhone";succeed({language:config2.language,model,systemVersion:config2.systemVersion,statusBarHeight:config2.statusBarHeight,platform:config2.platform,brand:config2.platform==="iOS"?"Apple":"Android",client_version:config2.globals.__APP_VERSION__??"",client_type:config2.clientType});return}if(kind==="mtop"){callMtop(params??{},onSuccess,onFailure);return}if(kind==="mtopStream"){callMtopStream(params??{},succeed,failed);return}if(kind==="kvGet"||kind==="kvSet"||kind==="kvDelete"){let p=params&&typeof params=="object"?params:{},key=typeof p.key=="string"?p.key:"";if(!key){failed("missing key");return}try{let storageKey=`__mearl_app_kv__:${key}`;if(kind==="kvGet"){let stored=localStorage.getItem(storageKey);stored!==null?succeed(stored):failed(JSON.stringify({ret:["HY_FAILED"],msg:"key not found"}))}else if(kind==="kvSet"){let value=typeof p.value=="string"?p.value:p.value===void 0?"":JSON.stringify(p.value);localStorage.setItem(storageKey,value),succeed({})}else localStorage.removeItem(storageKey),succeed({})}catch{failed(JSON.stringify({ret:["HY_FAILED"],msg:"kv storage unavailable"}))}return}if(kind==="pageContext"){succeed({pageContext:void 0});return}if(kind==="memoryGet"||kind==="memorySet"||kind==="memoryDelete"){let p=params&&typeof params=="object"?params:{},key=typeof p.key=="string"?p.key:"";if(!key){failed({error_message:"missing key"});return}try{let storageKey=`__mearl_app_memory__:${key}`;if(kind==="memoryGet"){let value=sessionStorage.getItem(storageKey);succeed(value===null?{}:{value})}else if(kind==="memorySet"){let value=typeof p.value=="string"?p.value:p.value===void 0?"":JSON.stringify(p.value);sessionStorage.setItem(storageKey,value),succeed({key,success:!0})}else sessionStorage.removeItem(storageKey),succeed({key,success:!0})}catch{failed({error_message:"memory cache unavailable"})}return}if(kind==="availabilityMap"){let p=params&&typeof params=="object"?params:{},channels=Array.isArray(p.data)?p.data.filter(value=>typeof value=="string"):[];succeed({res:"success",data:Object.fromEntries(channels.map(channel=>[channel,!1]))});return}if(kind==="userInfo"){let userId=readFirstUserCookie(["unb"]),userName=readFirstUserCookie(["_w_tb_nick","_nk_","snk","tracknick"]);callUserInfo({...userId&&{userId},...userName&&{userName}},succeed);return}if(kind==="networkInfo"){let state=readNetworkState();if(api==="WVNetwork.getNetworkType"){succeed({type:{wifi:"WIFI","slow-2g":"2G","2g":"2G","3g":"3G","4g":"4G"}[state]??"UNKNOWN"});return}if(config2.profile==="alipay"||config2.profile==="koubei"){succeed({networkAvailable:state!=="fail",networkType:{wifi:"WIFI","slow-2g":"2G","2g":"2G","3g":"3G","4g":"4G",fail:"NOTREACHABLE"}[state]??"UNKNOWN"});return}let type=networkTypeNumber(state);succeed({type,state:state==="slow-2g"?"2g":state});return}if(kind==="networkQualityMonitor"){let p=params&&typeof params=="object"?params:{},action=typeof p.action=="string"?p.action:"";if(action==="add_notify_network_quality"){if(!stopNetworkQualityMonitor){let notify=()=>{try{document.dispatchEvent(new CustomEvent("WV.NETWORK_TYPE_CHANGED",{detail:{new_network_type:networkTypeNumber(readNetworkState())}}))}catch{}},connection=navigator.connection;window.addEventListener("online",notify),window.addEventListener("offline",notify),connection?.addEventListener?.("change",notify),stopNetworkQualityMonitor=()=>{window.removeEventListener("online",notify),window.removeEventListener("offline",notify),connection?.removeEventListener?.("change",notify)}}succeed({});return}if(action==="remove_notify_network_quality"){stopNetworkQualityMonitor?.(),stopNetworkQualityMonitor=null,succeed({});return}failed({error_message:"unsupported network quality monitor action"});return}if(kind==="beaconRequest"){let url2=pickUrl(params);if(!url2){failed({error_message:"missing url"});return}try{let resolved=new URL(url2,location.href);if(resolved.protocol!=="http:"&&resolved.protocol!=="https:"){failed({error_message:"unsupported request protocol"});return}let image=new Image;image.referrerPolicy="no-referrer-when-downgrade",image.src=resolved.href,succeed({})}catch{failed({error_message:"invalid url"})}return}if(kind==="calendar"){let p=params&&typeof params=="object"?params:{},events=readCalendarEvents();if(api==="store_calendar_event"){let event=calendarEventFromParams(p);if(!event.title||event.startTime===null){failed({error_message:"calendar title and start time are required"});return}let next=events.filter(stored=>!sameCalendarEvent(stored,event));if(next.push(event),!writeCalendarEvents(next)){failed({error_message:"calendar storage unavailable"});return}succeed({success:!0});return}if(api==="remove_calendar_event"){let candidate=calendarEventFromParams(p),next=events.filter(stored=>!sameCalendarEvent(stored,candidate));if(!writeCalendarEvents(next)){failed({error_message:"calendar storage unavailable"});return}succeed({success:!0,removed:events.length-next.length});return}if(api==="check_batch_calendar"){let batch=Array.isArray(p.batch)?p.batch:[];succeed({batch:batch.map(item=>{let candidate=calendarEventFromParams(item);return{...item&&typeof item=="object"?item:{},success:events.some(stored=>sameCalendarEvent(stored,candidate))}})});return}let urls=Array.isArray(p.urls)?p.urls.filter(value=>typeof value=="string"):typeof p.url=="string"?[p.url]:[],titles=Array.isArray(p.calendar_titles)?p.calendar_titles.filter(value=>typeof value=="string"):typeof p.calendar_title=="string"?[p.calendar_title]:[],matched=events.filter(event=>(urls.length===0||urls.includes(event.url))&&(titles.length===0||titles.includes(event.title)));succeed({events:matched.map(calendarEventResponse)});return}if(kind==="geolocation"){if(!navigator.geolocation){failed({errorCode:2,errorMsg:"geolocation unavailable"});return}let locate=()=>navigator.geolocation.getCurrentPosition(position=>{let{latitude,longitude,accuracy,altitude,altitudeAccuracy,heading,speed}=position.coords;succeed({latitude,longitude,accuracy,altitude,altitudeAccuracy,heading,speed,timestamp:position.timestamp})},error48=>failed({errorCode:error48.code,errorMsg:error48.message}),{enableHighAccuracy:!1,timeout:1e4,maximumAge:3e5});navigator.permissions?.query?navigator.permissions.query({name:"geolocation"}).then(status=>{status.state==="granted"?locate():failed({errorCode:1,errorMsg:"location permission not granted"})}).catch(locate):locate();return}if(kind==="permission"){let p=params&&typeof params=="object"?params:{},action=typeof p.action=="string"?p.action:"",permission=typeof p.permission=="string"?p.permission:"",permissionFailed=message=>failed({error_code:-1,error_message:message});if(permission==="album"||permission==="MODIFY_AUDIO_SETTINGS"){action==="check"||action==="request"?succeed({}):permissionFailed("unsupported permission action");return}let browserPermission=permission==="mic"?"microphone":permission==="camera"?"camera":permission==="lbs"?"geolocation":"";if(!browserPermission){permissionFailed("unsupported permission");return}if(action==="check"&&navigator.permissions?.query){navigator.permissions.query({name:browserPermission}).then(status=>{status.state==="granted"?succeed({}):permissionFailed("permission not granted")}).catch(()=>permissionFailed("permission check failed"));return}if(action==="request"&&(permission==="mic"||permission==="camera")){if(!navigator.mediaDevices?.getUserMedia){permissionFailed("media permission unavailable");return}navigator.mediaDevices.getUserMedia({audio:permission==="mic",video:permission==="camera"}).then(stream=>{for(let track of stream.getTracks())track.stop();succeed({})}).catch(()=>permissionFailed("permission denied"));return}if(action==="request"&&permission==="lbs"&&navigator.geolocation){navigator.geolocation.getCurrentPosition(()=>succeed({}),()=>permissionFailed("permission denied"),{timeout:1e4});return}permissionFailed("unsupported permission action");return}if(kind==="prefetch"){let p=params&&typeof params=="object"?params:{},url2=typeof p.url=="string"?p.url:"";if(!url2){failed({code:-1,errorMsg:"url is empty"});return}let resolvedUrl;try{resolvedUrl=new URL(url2,location.href).href}catch{failed({code:-1,errorMsg:"invalid url"});return}if(!Array.from(document.querySelectorAll('link[rel="prefetch"]')).some(link=>link.href===resolvedUrl)){let link=document.createElement("link");link.rel="prefetch",link.href=url2,(document.head??document.documentElement).appendChild(link)}succeed({});return}if(kind==="fptTrack"){let p=params&&typeof params=="object"?params:{},action=typeof p.action=="string"?p.action:"",actionParams=p.params&&typeof p.params=="object"?p.params:{},key=typeof actionParams.key=="string"?actionParams.key:"";if(action==="setFpt"){let value=typeof actionParams.value=="string"?actionParams.value:"";if(!key||!value||!/^[0-9A-Za-z._-]+$/.test(key)||!/^[0-9A-Za-z._-]+$/.test(value)||`${key}(${value})`.length>100){failed({error_message:"invalid fpt key or value"});return}setFptEntry(fptEntries,key,value),persistFpt()}else action==="deleteFpt"&&key&&(fptEntries.delete(key),persistFpt());succeed({});return}if(kind==="previewFile"){let p=params&&typeof params=="object"?params:{},fileUrl=typeof p.file_url=="string"?p.file_url:"",remoteUrl=typeof p.file_remote_url=="string"?p.file_remote_url:"",url2=(fileUrl.startsWith("http")?fileUrl:remoteUrl)||fileUrl||remoteUrl;url2?(requestOpen(url2,0,!1),succeed({})):failed({code:-1,errorMsg:"file_url is empty"});return}if(kind==="toast"){let error48=showAppToast(params);error48?failed({error_message:error48}):succeed({});return}if(kind==="unsupportedNativeInput"){let containerType="";try{containerType=new URL(location.href).searchParams.get("containerType")??""}catch{}!unsupportedNativeInputNotified&&(containerType==="h5_dx"||containerType==="flutter_h5")&&(unsupportedNativeInputNotified=!0,showAppToast({message:"åŊåéĄĩéĸäŊŋį¨åįčžå
ĨæĄīŧ蝎į§ģé¤ URL ä¸į containerType åæ°äģĨæŖå¸¸æäŊ",milliseconds:4e3})),succeed({});return}if(kind==="payment"){log3("æĄĨč°į¨æ¯äģīŧįåž
፿ˇįĄŽčޤ",api,params),showPaymentDialog(api,params,succeed,failed);return}if(kind==="userTrack"){sendUserTrack(params),succeed({});return}if(kind==="response"){succeed(config2.actions.responses?.[api]);return}if(kind==="noop"){succeed({});return}silent||log3("æĒčĻįæĄĨæšæŗīŧåč° failureīŧéĄĩéĸåēå°čĩ° H5 å
åēīŧ:",api),failed(NOT_IMPLEMENTED_PAYLOAD)}let MEGA_SUPPORTED_APIS={stdPop:["showWeex2","showWeex","showH5","changeSize","close"],broadcast:["addEventListener","dispatchEvent","removeEventListener"],kvStorage:["setItem","getItem","removeItem","getAllKeys","clear","getCurrentInfo","getCurrentInfoAndKeys"],LifeCycle:["addPageLifeCycleListener","removePageLifeCycleListener"],Container:["interceptPageClose","disableInterceptPageClose"],navigator:["openURL","close","replace","setSystemBackBlockListener","removeSystemBackBlockListener"],NavBar:["setTitle"],Router:["popPage"]};function isMegaApiSupported(ability,api){return typeof ability=="string"&&typeof api=="string"&&MEGA_SUPPORTED_APIS[ability]?.includes(api)===!0}function megaParams(value){return value&&typeof value=="object"&&!Array.isArray(value)?value:{}}function megaError(callback,statusCode,message){emitMegaCallback(callback,{statusCode,type:"result",data:{errorMessage:typeof message=="string"?message:String(message??"")}})}function cloneMegaDetail(value){if(value===void 0)return{success:!0,value:void 0};try{return{success:!0,value:JSON.parse(JSON.stringify(value))}}catch{return{success:!1}}}function megaSuccess(data={}){return{statusCode:0,type:"result",data}}function megaFailure(message){return{statusCode:500,type:"result",data:{errorMessage:message}}}function megaKVParams(params){return{bizId:typeof params.bizID=="string"?params.bizID:typeof params.bizId=="string"?params.bizId:"",key:typeof params.key=="string"?params.key:"",value:typeof params.value=="string"?params.value:null}}function megaStringByteLength(value){try{return typeof TextEncoder=="function"?new TextEncoder().encode(value).length:value.length}catch{return value.length}}function megaKVUsedSize(entries){let size=0;for(let value of entries.values())size+=megaStringByteLength(value);return size}function reportMegaKVMutation(operation,bizId,key="",value,onSuccess,onFailure){requestContainerData("megaKVMutation",{operation,bizId,key,...value===void 0?{}:{value}},()=>onSuccess?.(),reason=>{log3("KVStorage 厚å¨åæĨå¤ąč´Ĩ:",reason),onFailure?.(reason)})}function completeMegaKVMutation(operation,bizId,key,value,synchronous,callback){let result=megaSuccess();return reportMegaKVMutation(operation,bizId,key,value,synchronous?void 0:()=>emitMegaCallback(callback,result),synchronous?void 0:reason=>emitMegaCallback(callback,megaFailure(String(reason??"container sync failed")))),synchronous?result:null}function executeMegaKVStorage(api,params,synchronous,callback){let{bizId,key,value}=megaKVParams(params);if(!bizId)return megaFailure("missing bizID");let entries=megaKVStorage.get(bizId)??new Map;if(api==="setItem"){if(!key)return megaFailure("missing key");if(value===null||value==="")return megaFailure("missing value");let previousSize=megaStringByteLength(entries.get(key)??"");return megaKVUsedSize(entries)-previousSize+megaStringByteLength(value)>MEGA_KV_TOTAL_SIZE?megaFailure("KVStorage quota exceeded"):(entries.set(key,value),megaKVStorage.set(bizId,entries),megaKVMutationVersion+=1,persistMegaKVStorage(),completeMegaKVMutation("set",bizId,key,value,synchronous,callback))}if(api==="getItem"){if(!key)return megaFailure("missing key");let result=entries.get(key)??"";return megaSuccess(synchronous?{result}:result)}if(api==="removeItem")return key?(entries.delete(key),entries.size===0&&megaKVStorage.delete(bizId),megaKVMutationVersion+=1,persistMegaKVStorage(),completeMegaKVMutation("remove",bizId,key,void 0,synchronous,callback)):megaFailure("missing key");if(api==="getAllKeys"){let result=Array.from(entries.keys());return megaSuccess(synchronous?{result}:result)}if(api==="clear")return megaKVStorage.delete(bizId),megaKVMutationVersion+=1,persistMegaKVStorage(),completeMegaKVMutation("clear",bizId,"",void 0,synchronous,callback);if(api==="getCurrentInfo"||api==="getCurrentInfoAndKeys"){let data={totalSize:MEGA_KV_TOTAL_SIZE,freeSize:Math.max(MEGA_KV_TOTAL_SIZE-megaKVUsedSize(entries),0)};return api==="getCurrentInfoAndKeys"&&(data.keys=Array.from(entries.keys())),megaSuccess(data)}return{statusCode:405,type:"result",data:{}}}function handleMegaLifeCycle(api,callback){if(api==="addPageLifeCycleListener"){callback&&megaLifeCycleListeners.add(callback),emitMegaCallback(callback,megaSuccess());return}if(api==="removePageLifeCycleListener"){let listeners=Array.from(megaLifeCycleListeners);megaLifeCycleListeners.clear(),emitMegaCallback(callback,megaSuccess());for(let listener of listeners)emitMegaCallback(listener,{statusCode:99,type:"finish",data:{}});return}megaError(callback,405,`LifeCycle.${api} is not supported`)}function handleMegaContainer(api,callback){if(api==="interceptPageClose"){callback&&megaPageCloseListeners.add(callback),emitMegaCallback(callback,megaSuccess());return}if(api==="disableInterceptPageClose"){let listeners=Array.from(megaPageCloseListeners);megaPageCloseListeners.clear(),emitMegaCallback(callback,megaSuccess());for(let listener of listeners)emitMegaCallback(listener,{statusCode:99,type:"finish",data:{}});return}megaError(callback,405,`Container.${api} is not supported`)}function megaNavigationUrl(params){let rawUrl=pickUrl(params);if(!rawUrl)return null;if(!params.extQuery||typeof params.extQuery!="object"||Array.isArray(params.extQuery))return rawUrl;try{let target=new URL(rawUrl,location.href);for(let[key,value]of Object.entries(params.extQuery))value!=null&&target.searchParams.set(key,String(value));return target.href}catch{return rawUrl}}function handleMegaNavigator(api,params,callback){if(api==="openURL"||api==="replace"){let url2=megaNavigationUrl(params);if(!url2){megaError(callback,500,"missing url");return}let callbackId=api==="openURL"&&callback?stashCallback(value=>{let backdata=value&&typeof value=="object"?value.backdata:void 0;emitMegaCallback(callback,{statusCode:1,type:"onResult",data:{result:!0,...backdata===void 0?{}:{data:backdata}}}),emitMegaCallback(callback,{statusCode:99,type:"finish",data:{}})}):0;requestOpen(url2,callbackId,!1,{...params,...api==="replace"?{__mearlReplace:!0}:{}}),emitMegaCallback(callback,megaSuccess());return}if(api==="close"){emitMegaCallback(callback,megaSuccess()),requestClose(void 0);return}if(api==="setSystemBackBlockListener"){megaSystemBackListener&&megaSystemBackListener!==callback&&emitMegaCallback(megaSystemBackListener,{statusCode:99,type:"finish",data:{}}),megaSystemBackListener=callback??null,emitMegaCallback(callback,megaSuccess());return}if(api==="removeSystemBackBlockListener"){let listener=megaSystemBackListener;megaSystemBackListener=null,emitMegaCallback(callback,megaSuccess()),listener&&emitMegaCallback(listener,{statusCode:99,type:"finish",data:{}});return}megaError(callback,405,`navigator.${api} is not supported`)}function handleMegaNavBar(api,params,callback){if(api!=="setTitle"){megaError(callback,405,`NavBar.${api} is not supported`);return}applyNavigationBarState(api,params),emitMegaCallback(callback,megaSuccess())}function handleMegaRouter(api,callback){if(api!=="popPage"){megaError(callback,405,`Router.${api} is not supported`);return}emitMegaCallback(callback,megaSuccess()),requestClose(void 0)}function handleMegaStdPop(api,params,callback){if(api==="showH5"||api==="showWeex2"||api==="showWeex"){let url2=pickUrl(params),popId=typeof params.popId=="string"?params.popId.trim():"";if(!url2||!popId){megaError(callback,500,url2?"missing popId":"missing url");return}let callbackId=stashCallback(value=>{let result=value&&typeof value=="object"&&"backdata"in value?value.backdata:void 0;emitMegaCallback(callback,{statusCode:1,type:"onClose",data:result}),emitMegaCallback(callback,{statusCode:99,type:"finish"})});requestOpen(url2,callbackId,!0,{...params,__mearlMegaPopId:popId}),emitMegaCallback(callback,{statusCode:0,type:"result",data:{}});return}if(api==="close"){let popId=typeof params.popId=="string"?params.popId.trim():"";if(!popId){megaError(callback,500,"missing popId");return}let cloned=cloneMegaDetail(params.result);if(!cloned.success){megaError(callback,500,"result is not serializable");return}requestContainerData("megaPopClose",{popId,result:cloned.value},()=>emitMegaCallback(callback,{statusCode:0,type:"result",data:{}}),reason=>megaError(callback,500,reason));return}if(api==="changeSize"){let popId=typeof params.popId=="string"?params.popId.trim():"";if(!popId){megaError(callback,500,"missing popId");return}requestContainerData("megaPopResize",{...params,popId},()=>emitMegaCallback(callback,{statusCode:0,type:"result",data:{}}),reason=>megaError(callback,500,reason));return}megaError(callback,405,`stdPop.${api} is not supported`)}function handleMegaBroadcast(api,params,callback){let bizId=megaBroadcastBizId(params.bizId),eventName=typeof params.eventName=="string"?params.eventName.trim():"";if(!eventName){megaError(callback,500,"missing eventName");return}if(api==="addEventListener"){if(!callback)return;let id=`mearl-mega-listener-${++megaListenerSeq}`;megaBroadcastListeners.set(id,{id,bizId,eventName,once:params.once===!0,callback}),emitMegaCallback(callback,{statusCode:0,type:"result",data:{}}),emitMegaCallback(callback,{statusCode:1,type:"onAdd",data:{listenerId:id}});return}if(api==="dispatchEvent"){let detail=cloneMegaDetail(params.detail);if(!detail.success){megaError(callback,500,"detail is not serializable");return}requestContainerData("megaBroadcast",{message:{kind:"megaBroadcast",bizId,eventName,detail:detail.value}},()=>emitMegaCallback(callback,{statusCode:0,type:"result",data:{}}),reason=>megaError(callback,500,reason));return}if(api==="removeEventListener"){let listenerId=typeof params.listenerId=="string"?params.listenerId:"",removed=[];for(let listener of Array.from(megaBroadcastListeners.values()))listener.bizId!==bizId||listener.eventName!==eventName||listenerId&&listener.id!==listenerId||(megaBroadcastListeners.delete(listener.id),removed.push(listener));emitMegaCallback(callback,{statusCode:0,type:"result",data:{}});for(let listener of removed)emitMegaCallback(listener.callback,{statusCode:99,type:"finish"});return}megaError(callback,405,`broadcast.${api} is not supported`)}function makeMegaBridge(){return{asyncCall:(ability,api,rawParams,callback)=>{let params=megaParams(rawParams);if(ability==="ability"&&api==="available"){emitMegaCallback(callback,{statusCode:0,type:isMegaApiSupported(params.ability,params.api)?"YES":"NO",data:{}});return}if(ability==="ability"&&api==="batchFinishTrace"){emitMegaCallback(callback,{statusCode:0,type:"result",data:{}});return}if(!isMegaApiSupported(ability,api)){megaError(callback,405,`${ability}.${api} is not supported`);return}if(ability==="stdPop")handleMegaStdPop(api,params,callback);else if(ability==="broadcast")handleMegaBroadcast(api,params,callback);else if(ability==="kvStorage"){let result=executeMegaKVStorage(api,params,!1,callback);result&&emitMegaCallback(callback,result)}else ability==="LifeCycle"?handleMegaLifeCycle(api,callback):ability==="Container"?handleMegaContainer(api,callback):ability==="navigator"?handleMegaNavigator(api,params,callback):ability==="NavBar"?handleMegaNavBar(api,params,callback):handleMegaRouter(api,callback)},syncCall:(ability,api,rawParams)=>{let params=megaParams(rawParams);return ability==="ability"&&api==="available"?{statusCode:0,type:isMegaApiSupported(params.ability,params.api)?"YES":"NO",data:{}}:ability==="kvStorage"&&isMegaApiSupported(ability,api)?executeMegaKVStorage(api,params,!0)??megaFailure("container sync pending"):{statusCode:405,type:"result",data:{}}}}}function makeBridge(style){if(style==="mega")return makeMegaBridge();if(style==="easybikeNative"){let callNative=rawPayload=>{let payload;try{payload=typeof rawPayload=="string"?JSON.parse(rawPayload):rawPayload??{}}catch{return}let classMap=typeof payload.classMap=="string"?payload.classMap:"",method=typeof payload.method=="string"?payload.method:"",callbackId=typeof payload.callbackId=="string"||typeof payload.callbackId=="number"?String(payload.callbackId):"",params;try{params=typeof payload.params=="string"?payload.params?JSON.parse(payload.params):{}:payload.params??{}}catch{params={}}let complete=(code,data,msg="")=>{let callback=resolveWindowFunction("callBack");callbackId&&callback&&callback({callbackId,code,data,msg})};dispatch(`${classMap}.${method}`,params,value=>complete(0,value),error48=>complete(1,void 0,typeof error48=="string"?error48:String(error48??"")))};return{postMessage:callNative,callNative}}if(style==="windvane")return{isAvailable:!0,version:"8.7.0",call:(cls,method,params,succ,fail)=>dispatch(`${cls}.${method}`,params,succ,fail)};if(style==="fliggy"||style==="alipay"||style==="callback"){let bridge={call:(api,params,succ,fail)=>{typeof params=="function"&&(fail=succ,succ=params,params=void 0);let p=params&&typeof params=="object"?params:{},successFn=succ??(typeof p.success_callback=="function"?p.success_callback:void 0)??(typeof p.successCallback=="function"?p.successCallback:void 0),failureFn=fail??(typeof p.fail_callback=="function"?p.fail_callback:void 0)??(typeof p.failure_callback=="function"?p.failure_callback:void 0)??(typeof p.failCallback=="function"?p.failCallback:void 0)??(typeof p.failureCallback=="function"?p.failureCallback:void 0);dispatch(api,p,res=>successFn?.(res),err=>{failureFn?failureFn(err):successFn?.({error:err})},p.callbackCommand??p.callback_command)},pushBack:(prefixOrApi,apiOrParams,paramsOrSucc,succ)=>{let api=prefixOrApi,params=apiOrParams,success2=paramsOrSucc;typeof apiOrParams=="string"&&(api=apiOrParams,params=paramsOrSucc,success2=succ);let p=params??{},successFn=(typeof success2=="function"?success2:void 0)??(typeof p.successCallback=="function"?p.successCallback:void 0);return dispatch(api,p,res=>successFn?.(res),void 0,p.callbackCommand??p.callback_command),bridge},sendUriScheme:uri=>(handleMaybeScheme(uri),bridge)};if(style==="fliggy"){let normalizedAppName=(config2.globals.__APP_NAME__??"").toUpperCase(),os11=config2.clientType==="iphone"?"ios":"android",isAliApp=name=>normalizedAppName===name.toUpperCase();Object.assign(bridge,{version:"1.0.21",device:{os:os11,OS:config2.platform,type:os11,version:config2.systemVersion,model:config2.globals.__DEVICE_MODEL__??""},platform:os11,isAliApp,isTmall:isAliApp("TM"),isTaobao:isAliApp("TB"),isAlipay:isAliApp("AP"),isAlitrip:isAliApp("LX"),isKoubei:isAliApp("KB"),isElm:isAliApp("ELMC"),isGaode:isAliApp("amap"),isUC:/UCBrowser/i.test(config2.userAgent),isWeibo:/Weibo/i.test(config2.userAgent),isWeixin:/MicroMessenger/i.test(config2.userAgent),isWindVane:config2.bridges.some(item=>item.style==="windvane"),isAlipayClient:/AlipayClient/i.test(config2.userAgent)})}return bridge}if(style==="btrip")return{call:(api,params)=>dispatch(api,params??{},void 0,void 0)};if(style==="invoke")return{invoke:(api,params)=>{let p=params??{};dispatch(api,p,p.success,p.fail)}};if(style==="callHandler")return{callHandler:(api,params)=>dispatch(api,params??{},void 0,void 0)};if(style==="amap")return{ready:cb=>cb?.(),send:(msg,cb)=>{let m=msg??{};dispatch(typeof m.action=="string"?m.action:"",m,res=>cb?.(res),err=>cb?.({error:err}))}};if(style==="didi")return{openPage:params=>dispatch("openPage",params??{},void 0,void 0),closePage:params=>dispatch("closePage",params??{},void 0,void 0)};if(style==="wechatMiniProgram"){let invoke2=(api,params)=>{let p=params&&typeof params=="object"?params:{};dispatch(api,p,value=>{p.success?.(value),p.complete?.(value)},error48=>{p.fail?.(error48),p.complete?.(error48)})};return{navigateTo:params=>invoke2("navigateTo",params),redirectTo:params=>invoke2("redirectTo",params),switchTab:params=>invoke2("switchTab",params),reLaunch:params=>invoke2("reLaunch",params),navigateBack:params=>invoke2("navigateBack",params),postMessage:params=>invoke2("postMessage",params),getEnv:callback=>{callback&&setTimeout(()=>callback({miniprogram:!0}),0)}}}return{}}function setGlobal(path23,value){let parts=path23.split("."),obj=w;for(let i=0;i<parts.length-1;i++){let cur=obj[parts[i]];(!cur||typeof cur!="object")&&(obj[parts[i]]={}),obj=obj[parts[i]]}obj[parts[parts.length-1]]=value}function setPersistentGlobal(path23,value){let parts=path23.split(".").filter(Boolean);if(parts.length<2){setGlobal(path23,value);return}let[rootKey,...nestedParts]=parts,isObjectLike=candidate=>typeof candidate=="object"&&candidate!==null||typeof candidate=="function",attachBridge=candidate=>{let root=isObjectLike(candidate)?candidate:{},obj=root;for(let index=0;index<nestedParts.length-1;index+=1){let key=nestedParts[index],child=obj[key];if(!isObjectLike(child))try{obj[key]={}}catch{return root}obj=obj[key]}let leaf=nestedParts[nestedParts.length-1];try{Object.defineProperty(obj,leaf,{configurable:!1,enumerable:!0,get:()=>value,set:()=>{}})}catch{try{obj[leaf]=value}catch{}}return root},currentRoot=attachBridge(w[rootKey]);try{Object.defineProperty(w,rootKey,{configurable:!1,enumerable:!0,get:()=>currentRoot,set:next=>{currentRoot=attachBridge(next)}})}catch{w[rootKey]=currentRoot}}if(config2.bridges.some(spec=>spec.style==="mega")){let hydrationVersion=megaKVMutationVersion;requestContainerData("megaKVSnapshot",{},value=>{let entries=value&&typeof value=="object"?value.entries:void 0;megaKVMutationVersion===hydrationVersion&&replaceMegaKVStorage(entries)},()=>{})}for(let spec of config2.bridges)try{let bridge=makeBridge(spec.style);spec.persistent?setPersistentGlobal(spec.global,bridge):setGlobal(spec.global,bridge)}catch(e){console.error(TAG,"æĄĨåŽčŖ
å¤ąč´Ĩ:",spec.global,e)}return{mapScheme,handleMaybeScheme,handleAppMessage,handleNativeBack,handleResume,handlePageVisibility,applyRuntimeResponses}}function installAppProfileContainerStack(config2,environment,links){let{SRC,TAG,simulateSystemBars,ROOT_FRAME_NAME,LAYER_FRAME_NAME,isTop,isRootFrame,isLayerFrame,isContainerFrame,usesRootContainer,log:log3}=environment,{pageTransport}=links,initialLayerTitleBarState=url2=>links.getSystemBars().initialLayerTitleBarState(url2),resolvedTitleBarState=layer=>links.getSystemBars().resolvedTitleBarState(layer),parseReportedTitleBarState=value=>links.getSystemBars().parseReportedTitleBarState(value),createSimulatedNavigationBarView=(placement,onBack)=>links.getSystemBars().createNavigationBarView(placement,onBack),destroySimulatedNavigationBarView=view=>links.getSystemBars().destroyNavigationBarView(view),syncLayerViewport=(layer,state)=>links.getSystemBars().syncLayerViewport(layer,state),syncActiveSystemBars=()=>links.getSystemBars().syncActiveSystemBars(),syncSimulatedTitleBar=()=>links.getSystemBars().syncSimulatedTitleBar(),rootContainerActive=!1,rootFrame=null,rootBusinessUrl=location.href,webViewEnvironmentRequestSeq=0,simulatedPageHidden=!1,runtimeResponses=null;function syncSimulatorStateToWindow(target){target&&(runtimeResponses&&target.postMessage({source:SRC,type:"runtimeResponses",profile:config2.profile,responses:runtimeResponses},"*"),simulatedPageHidden&&target.postMessage({source:SRC,type:"simulatorVisibility",hidden:!0},"*"))}function startPreparedWebViewNavigation(frame,target,canCommit,registerCleanup){let insets=config2.safeAreaInsets??{top:config2.statusBarHeight,right:0,bottom:0,left:0};if(!usesRootContainer||!Object.values(insets).some(value=>value>0)){canCommit()&&(frame.src=target);return}let requestId=++webViewEnvironmentRequestSeq,settled=!1,fallbackTimer=0,cleanup=()=>{settled||(settled=!0,clearTimeout(fallbackTimer),window.removeEventListener("message",handleResponse),registerCleanup?.(null))},commitNavigation=fallbackReason=>{cleanup(),fallbackReason&&console.warn(TAG,"WebView į¯åĸå夿ĒåŽæīŧéįē§æäē¤å¯ŧčĒ",{target,requestId,reason:fallbackReason}),canCommit()&&(frame.src=target)},handleResponse=event=>{if(event.source!==window||event.data?.source!=="mearl-content"||event.data?.type!=="APP_BRIDGE_PREPARE_WEBVIEW_RESPONSE"||event.data?.requestId!==requestId)return;let result=event.data.result;result?.success===!0?commitNavigation():commitNavigation(String(result?.error??"unknown preparation failure"))};registerCleanup?.(cleanup),window.addEventListener("message",handleResponse),fallbackTimer=setTimeout(()=>commitNavigation("preparation timed out after 500ms"),500);try{window.postMessage({source:SRC,type:"prepareWebView",requestId},"*")}catch(error48){commitNavigation(error48 instanceof Error?error48.message:String(error48))}}function installRootContainer(){if(!usesRootContainer||!/^https?:$/i.test(location.protocol))return;let shellRoot,frame;try{for(let cookie of config2.rootContainer?.initialCookies??[]){if(!cookie.name)continue;let parts=[`${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`,`Path=${cookie.path??"/"}`];cookie.domain&&parts.push(`Domain=${cookie.domain}`),document.cookie=parts.join("; ")}shellRoot=document.createElement("html");let shellHead=document.createElement("head"),charset=document.createElement("meta"),viewport=document.createElement("meta"),title=document.createElement("title"),shellBody=document.createElement("body");frame=document.createElement("iframe"),shellRoot.setAttribute("data-mearl-app-shell",""),shellBody.setAttribute("data-mearl-app-shell",""),charset.setAttribute("charset","utf-8"),viewport.name="viewport",viewport.content="width=device-width,initial-scale=1,viewport-fit=cover",shellHead.append(charset,viewport,title),shellRoot.append(shellHead,shellBody),shellRoot.style.cssText="width:100%;height:100%;margin:0;overflow:hidden;background:#fff;",shellBody.style.cssText="width:100%;height:100%;margin:0;overflow:hidden;background:#fff;",frame.name=ROOT_FRAME_NAME,frame.setAttribute("data-mearl-root-webview",config2.profile),frame.style.cssText="position:fixed;left:0;right:0;top:0;bottom:0;width:100%;height:100%;border:0;display:block;background:#fff;z-index:0;opacity:1;",frame.addEventListener("load",()=>{let committedSrc=frame.getAttribute("src");!committedSrc||committedSrc==="about:blank"||(syncSimulatorStateToWindow(frame.contentWindow),requestAnimationFrame(()=>{rootFrame!==frame||!frame.isConnected||(frame.setAttribute("data-mearl-webview-ready",""),syncSimulatedTitleBar())}))}),shellBody.appendChild(frame);let currentRoot=document.documentElement;currentRoot?document.replaceChild(shellRoot,currentRoot):document.appendChild(shellRoot)}catch(error48){console.warn(TAG,"æ š WebView 厚å¨ååģēå¤ąč´ĨīŧäŋįåŊåéĄĩéĸ",error48),rootFrame=null;return}rootFrame=frame,rootContainerActive=!0;try{typeof window.stop=="function"&&window.stop()}catch(error48){console.warn(TAG,"åæĸå¤åąææĄŖå čŊŊå¤ąč´Ĩīŧįģ§įģå¯å¨æ š WebView",error48)}try{startPreparedWebViewNavigation(frame,rootBusinessUrl,()=>rootFrame===frame&&frame.isConnected)}catch(error48){console.warn(TAG,"æ š WebView į¯åĸåå¤å¯å¨å¤ąč´Ĩīŧį´æĨæäē¤ä¸åĄå¯ŧčĒ",error48),rootFrame===frame&&frame.isConnected&&(frame.src=rootBusinessUrl)}}installRootContainer();function normalizeProxyPathPrefix(prefix){let withLeadingSlash=prefix.startsWith("/")?prefix:`/${prefix}`;return withLeadingSlash.endsWith("/")?withLeadingSlash:`${withLeadingSlash}/`}function matchesProxyTarget(hostname3,suffixes){return suffixes.some(suffix=>hostname3===suffix||hostname3.endsWith(`.${suffix}`))}function mapLayerFrameUrl(url2){let proxy=config2.layerUrlProxy;if(!proxy||!location.hostname.startsWith(proxy.sourceHostPrefix))return url2;try{let target=new URL(url2,location.href);if(!/^https?:$/.test(target.protocol))return url2;let prefix=normalizeProxyPathPrefix(proxy.pathPrefix);if(target.hostname===location.hostname){if(target.pathname.startsWith(prefix))return url2;let derivedHost=location.pathname.startsWith(prefix)?location.pathname.slice(prefix.length).split("/")[0]:proxy.defaultTargetHost;return!derivedHost||!matchesProxyTarget(derivedHost,proxy.targetHostSuffixes)?url2:`${location.origin}${prefix}${derivedHost}${target.pathname}${target.search}${target.hash}`}return matchesProxyTarget(target.hostname,proxy.targetHostSuffixes)?`${location.origin}${prefix}${target.host}${target.pathname}${target.search}${target.hash}`:url2}catch{return url2}}function restoreLayerBusinessUrl(url2){let proxy=config2.layerUrlProxy;if(!proxy)return url2;try{let current=new URL(url2,location.href),prefix=normalizeProxyPathPrefix(proxy.pathPrefix);if(current.origin!==location.origin||!current.pathname.startsWith(prefix))return url2;let rest=current.pathname.slice(prefix.length),slash=rest.indexOf("/"),host=slash===-1?rest:rest.slice(0,slash);if(!host)return url2;let hostname3=new URL(`${current.protocol}//${host}`).hostname;if(!matchesProxyTarget(hostname3,proxy.targetHostSuffixes))return url2;let pathname=slash===-1?"/":rest.slice(slash);return`${current.protocol}//${host}${pathname}${current.search}${current.hash}`}catch{return url2}}let ANIM_MS=config2.animationMs??300;function boolParam(value,fallback){return value===!0||value===1||value==="1"||value==="true"?!0:value===!1||value===0||value==="0"||value==="false"?!1:value===""?!0:fallback}function numberParam(value,fallback,min,max){let parsed=typeof value=="number"?value:Number(value);return Number.isFinite(parsed)?Math.min(Math.max(parsed,min),max):fallback}function resolveOverlayPresentation(url2,params,explicitWebdialog){let query=null;try{query=new URL(url2,location.href).searchParams}catch{}let records=[],addRecord=value=>{value&&typeof value=="object"&&!Array.isArray(value)&&records.push(value)};addRecord(params?.pageParams),addRecord(params?.page_params),addRecord(params?.popConfig),addRecord(params?.data),addRecord(params?.param),addRecord(params);let read=key=>{for(let record2 of records)if(Object.prototype.hasOwnProperty.call(record2,key))return record2[key];return query?.has(key)?query.get(key):void 0},protocol=config2.overlay;if(!explicitWebdialog&&(!protocol||!boolParam(read(protocol.enabledParam),!1)))return null;let configuredTopRatio=protocol?read(protocol.topRatioParam):void 0,configuredHeightRatio=protocol?.heightRatioParam?read(protocol.heightRatioParam):void 0,configuredMaxHeight=read("maxHeight")??configuredHeightRatio,defaultTopRatio=protocol?.defaultTopRatio??.2;return{topRatio:configuredTopRatio!==void 0?numberParam(configuredTopRatio,defaultTopRatio,0,1):configuredMaxHeight!==void 0?1-numberParam(configuredMaxHeight,1-defaultTopRatio,0,1):defaultTopRatio,widthRatio:numberParam(read("maxWidth"),1,0,1),radius:numberParam((protocol?read(protocol.radiusParam):void 0)??read("cornerRadius"),protocol?.defaultRadius??0,0,50),maskAlpha:numberParam(protocol?read(protocol.maskAlphaParam):void 0,protocol?.defaultMaskAlpha??.3,0,1),tapClose:boolParam((protocol?read(protocol.tapCloseParam):void 0)??read("tapEnable"),protocol?.defaultTapClose??!0)}}function requestsPopBeforeOpen(url2,params){if(params?.__mearlReplace===!0)return!0;let key=config2.popBeforeOpenParam;if(!key)return!1;let records=[params?.pageParams,params?.page_params,params?.data,params?.param,params];for(let value of records){if(!value||typeof value!="object"||Array.isArray(value))continue;let record2=value;if(Object.prototype.hasOwnProperty.call(record2,key))return boolParam(record2[key],!1)}try{let query=new URL(url2,location.href).searchParams;return query.has(key)&&boolParam(query.get(key),!1)}catch{return!1}}let layers=[],forwardStack=[],layerSeq=0,enteringLayerCount=0,closingLayerCount=0,explicitLayerTitleBarStates=new Map,rootScrollStyles=null,pendingClose=null,nativeBackRequestSeq=0,pendingNativeBack=null,containerDataRequestSeq=0,containerDataCallbacks=new Map,sharedFiles=new Map,sharedData=new Map,legacyBroadcastChannels=new Set,MEGA_KV_STORAGE_KEY=`__mearl_mega_kv__:${config2.profile}`;function readMegaKVStorage(){let storage=new Map;try{let parsed=JSON.parse(localStorage.getItem(MEGA_KV_STORAGE_KEY)??"{}");if(!parsed||typeof parsed!="object"||Array.isArray(parsed))return storage;for(let[bizId,rawEntries]of Object.entries(parsed)){if(!rawEntries||typeof rawEntries!="object"||Array.isArray(rawEntries))continue;let entries=new Map;for(let[key,value]of Object.entries(rawEntries))typeof value=="string"&&entries.set(key,value);storage.set(bizId,entries)}}catch{}return storage}let megaKVStorage=readMegaKVStorage();function megaKVSnapshot(){let snapshot={};for(let[bizId,values]of megaKVStorage)snapshot[bizId]=Object.fromEntries(values);return snapshot}function persistMegaKVStorage(){try{localStorage.setItem(MEGA_KV_STORAGE_KEY,JSON.stringify(megaKVSnapshot()))}catch{}}let PENDING_CLOSE_TIMEOUT_MS=400,pendingHistoryDepth=null;function clearPendingClose(){pendingClose&&(clearTimeout(pendingClose.timer),pendingClose=null)}function clearPendingNativeBack(){pendingNativeBack&&(clearTimeout(pendingNativeBack.timer),pendingNativeBack=null)}function clearPendingHistoryDepth(){pendingHistoryDepth&&(clearTimeout(pendingHistoryDepth.timer),pendingHistoryDepth=null)}function syncHistoryAfterDirectClose(){clearPendingHistoryDepth();let depth=layers.length,timer=setTimeout(()=>{pendingHistoryDepth=null,console.warn(TAG,"WebView 厞åēæ īŧäŊæĩč§å¨å垿Ēå¨éĸææļé´å
åæĨ",{depth})},PENDING_CLOSE_TIMEOUT_MS);pendingHistoryDepth={depth,timer},history.back()}function armPendingClose(data,retries){clearPendingClose();let timer=setTimeout(()=>{pendingClose=null,log3("close æĒįå° popstateīŧį´æĨå
ŗæ éĄļå
åē"),closeToDepth(Math.max(layers.length-1,0),data,!0)},PENDING_CLOSE_TIMEOUT_MS);pendingClose={data,retries,timer},history.back()}function parseStorageId(url2){try{return new URL(url2,location.href).searchParams.get("__storage_id")}catch{return null}}function titleBarStateCacheKey(url2){try{let parsed=new URL(url2,location.href);return parsed.hash="",parsed.href}catch{return url2}}function cacheExplicitTitleBarState(layer,state){explicitLayerTitleBarStates.set(titleBarStateCacheKey(layer.entryUrl),state),explicitLayerTitleBarStates.set(titleBarStateCacheKey(layer.url),state)}function readDepth(state){if(state&&typeof state=="object"){let d=state.__mearl_layer__;if(typeof d=="number")return d}return null}function mapUrlForSync(url2){let suffixes=config2.urlSyncHostSuffixes??[];try{let u=new URL(url2,location.href);if(!/^https?:$/.test(u.protocol)||!(suffixes.length===0||suffixes.some(s=>u.host===s||u.host.endsWith(`.${s}`))))return;let proxy=config2.layerUrlProxy;return proxy&&location.hostname.startsWith(proxy.sourceHostPrefix)&&matchesProxyTarget(u.hostname,proxy.targetHostSuffixes)?`${normalizeProxyPathPrefix(proxy.pathPrefix)}${u.host}${u.pathname}${u.search}${u.hash}`:u.pathname+u.search+u.hash}catch{return}}function createLayerEl(overlay,id){let el=document.createElement("div");el.setAttribute("data-mearl-layer",String(id)),el.style.cssText=`position:fixed;inset:0;z-index:${2147483e3+id%100*2};`;let frame=document.createElement("iframe");if(frame.name=LAYER_FRAME_NAME,frame.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-modals allow-downloads allow-popups"),frame.style.cssText="position:absolute;inset:0;width:100%;height:100%;border:0;display:block;background:#fff;z-index:0;opacity:1;",overlay){el.style.pointerEvents="none";let mask=document.createElement("div");mask.style.cssText=`position:absolute;inset:0;background:rgba(0,0,0,${overlay.maskAlpha});opacity:0;pointer-events:auto;`;let sheet=document.createElement("div"),width=overlay.widthRatio*100,left=(1-overlay.widthRatio)/2*100;return sheet.style.cssText=`position:absolute;left:${left}%;right:auto;bottom:0;width:${width}%;height:${(1-overlay.topRatio)*100}%;background:#fff;border-radius:${overlay.radius}px ${overlay.radius}px 0 0;overflow:hidden;pointer-events:auto;`,sheet.appendChild(frame),el.appendChild(mask),el.appendChild(sheet),{el,frame,animEl:sheet,mask}}return el.style.background="#fff",el.appendChild(frame),{el,frame,animEl:el,mask:null}}function setLayerInteractive(layer,interactive){layer.frame.style.pointerEvents=interactive?"":"none",layer.titleBarView&&(layer.titleBarView.root.style.pointerEvents=interactive?"":"none"),interactive?(layer.frame.removeAttribute("inert"),layer.frame.removeAttribute("aria-hidden"),layer.frame.removeAttribute("tabindex")):(layer.frame.setAttribute("inert",""),layer.frame.setAttribute("aria-hidden","true"),layer.frame.setAttribute("tabindex","-1"),layer.frame.blur()),layer.overlay?(layer.el.style.pointerEvents="none",layer.animEl.style.pointerEvents=interactive?"auto":"none",layer.mask&&(layer.mask.style.pointerEvents=interactive?"auto":"none")):layer.el.style.pointerEvents=interactive?"":"none"}function setRootFrameInteractive(interactive){rootFrame&&(rootFrame.style.pointerEvents=interactive?"":"none",interactive?(rootFrame.removeAttribute("inert"),rootFrame.removeAttribute("aria-hidden"),rootFrame.removeAttribute("tabindex")):(rootFrame.setAttribute("inert",""),rootFrame.setAttribute("aria-hidden","true"),rootFrame.setAttribute("tabindex","-1"),rootFrame.blur()))}function blockClosingLayerInteractions(layer){setLayerInteractive(layer,!1),layer.el.style.pointerEvents="auto"}function syncRootScrollLock(locked){let body=document.body;if(locked&&!rootScrollStyles){rootScrollStyles={html:document.documentElement.style.overflow,body:body?.style.overflow??null},document.documentElement.style.overflow="hidden",body&&(body.style.overflow="hidden");return}!locked&&rootScrollStyles&&(document.documentElement.style.overflow=rootScrollStyles.html,body&&rootScrollStyles.body!==null&&(body.style.overflow=rootScrollStyles.body),rootScrollStyles=null)}function syncLayerInteractivity(){let activeLayer=closingLayerCount===0&&enteringLayerCount===0?layers[layers.length-1]:void 0;for(let layer of layers)setLayerInteractive(layer,layer===activeLayer),!activeLayer&&layer===layers[layers.length-1]&&(layer.el.style.pointerEvents="auto");setRootFrameInteractive(layers.length===0&&enteringLayerCount===0&&closingLayerCount===0),syncRootScrollLock(layers.length>0||enteringLayerCount>0||closingLayerCount>0)}function finishLayerEntry(layer){layer.entering&&(layer.entering=!1,layer.enterTimer!==null&&clearTimeout(layer.enterTimer),layer.enterTimer=null,layer.enterTransitionEnd&&(layer.animEl.removeEventListener("transitionend",layer.enterTransitionEnd),layer.enterTransitionEnd=null),enteringLayerCount=Math.max(enteringLayerCount-1,0),syncLayerInteractivity())}function animateIn(layer){let t=layer.animEl;if(t.style.transform=layer.overlay?"translateY(100%)":"translateX(100%)",t.offsetWidth,t.style.transition=`transform ${ANIM_MS}ms ease`,t.style.transform="translate(0px, 0px)",layer.mask&&(layer.mask.style.transition=`opacity ${ANIM_MS}ms ease`,layer.mask.style.opacity="1"),ANIM_MS<=0){finishLayerEntry(layer);return}layer.enterTransitionEnd=event=>{event.target===t&&event.propertyName==="transform"&&finishLayerEntry(layer)},t.addEventListener("transitionend",layer.enterTransitionEnd),layer.enterTimer=setTimeout(()=>finishLayerEntry(layer),ANIM_MS+60)}function animateOut(layer,done){let t=layer.animEl;if(ANIM_MS<=0){t.style.transform=layer.overlay?"translateY(100%)":"translateX(100%)",layer.mask&&(layer.mask.style.opacity="0"),setTimeout(done,0);return}let settled=!1,fallbackTimer=0,finish=()=>{settled||(settled=!0,t.removeEventListener("transitionend",onTransitionEnd),clearTimeout(fallbackTimer),done())},onTransitionEnd=event=>{event.target===t&&event.propertyName==="transform"&&finish()};t.addEventListener("transitionend",onTransitionEnd),t.style.transition=`transform ${ANIM_MS}ms ease`,t.style.transform=layer.overlay?"translateY(100%)":"translateX(100%)",layer.mask&&(layer.mask.style.opacity="0"),fallbackTimer=setTimeout(finish,ANIM_MS+60)}function startLayerNavigation(layer,target){startPreparedWebViewNavigation(layer.frame,target,()=>!layer.closing&&layer.el.isConnected,cleanup=>{layer.navigationPreparationCleanup=cleanup})}function setPageVisibility(target,hidden){if(target===window){links.getBridgeProtocol().handlePageVisibility(hidden);return}try{target.postMessage({source:SRC,type:"simulatorVisibility",hidden},"*")}catch{}}function openLayer(url2,callbackId,overlay,openerWin,pushHistory,popId=null){clearPendingClose();let target=url2;if(!/^https?:/i.test(target)){let mapped=links.getBridgeProtocol().mapScheme(target);if(!mapped)return log3("open å¤ąč´Ĩīŧscheme æĒæ å°:",url2),null;target=mapped}location.protocol==="https:"&&target.startsWith("http:")&&(target="https:"+target.slice(5));let presentation=overlay??resolveOverlayPresentation(target,void 0,!1);log3("open â",presentation?"(webdialog) ":"",target);let parts=createLayerEl(presentation,++layerSeq),restoredTitleBarState=explicitLayerTitleBarStates.get(titleBarStateCacheKey(target)),layer={id:layerSeq,win:parts.frame.contentWindow,frame:parts.frame,entryUrl:target,url:target,overlay:presentation,openerWin,callbackId,storageId:parseStorageId(target),popId,el:parts.el,animEl:parts.animEl,mask:parts.mask,entering:!0,enterTimer:null,enterTransitionEnd:null,closing:!1,navigationPreparationCleanup:null,titleBarState:restoredTitleBarState??initialLayerTitleBarState(target),titleBarStateExplicit:restoredTitleBarState!==void 0,titleBarStateReady:restoredTitleBarState!==void 0,titleBarView:null};if(popId&&layer.el.setAttribute("data-mearl-pop-id",popId),layer.mask&&presentation?.tapClose&&layer.mask.addEventListener("click",()=>requestOverlayClose(layer)),!presentation&&simulateSystemBars&&config2.titleBar&&(layer.titleBarView=createSimulatedNavigationBarView("layer",()=>requestNativeBack()),layer.titleBarView.root.setAttribute("data-mearl-layer-titlebar",String(layer.id)),parts.el.appendChild(layer.titleBarView.root)),layers.push(layer),setPageVisibility(openerWin,!0),enteringLayerCount+=1,syncLayerViewport(layer,layer.titleBarState),syncLayerInteractivity(),parts.frame.addEventListener("load",()=>{layer.win=parts.frame.contentWindow,parts.frame.name=LAYER_FRAME_NAME;let committedSrc=parts.frame.getAttribute("src");!committedSrc||committedSrc==="about:blank"||(syncSimulatorStateToWindow(parts.frame.contentWindow),requestAnimationFrame(()=>{layer.titleBarStateReady||layer.closing||!layer.el.isConnected||(layer.titleBarStateReady=!0,syncLayerViewport(layer,resolvedTitleBarState(layer)))}))}),(document.body??document.documentElement).appendChild(parts.el),layer.win=parts.frame.contentWindow,startLayerNavigation(layer,mapLayerFrameUrl(target)),animateIn(layer),pushHistory){forwardStack.length=0;try{history.pushState({__mearl_layer__:layers.length},"",mapUrlForSync(target))}catch{}}return layer}function replaceLayer(sourceLayer,url2,callbackId,overlay,popId=null){if(sourceLayer.closing||layers[layers.length-1]!==sourceLayer){openLayer(url2,callbackId,overlay,sourceLayer.win??window,!0,popId);return}let replacement=openLayer(url2,callbackId,overlay,sourceLayer.openerWin,!1,popId);if(!replacement)return;sourceLayer.navigationPreparationCleanup?.(),sourceLayer.navigationPreparationCleanup=null,sourceLayer.entering&&(sourceLayer.entering=!1,enteringLayerCount=Math.max(enteringLayerCount-1,0),sourceLayer.enterTimer!==null&&clearTimeout(sourceLayer.enterTimer),sourceLayer.enterTransitionEnd&&sourceLayer.animEl.removeEventListener("transitionend",sourceLayer.enterTransitionEnd));let sourceIndex=layers.indexOf(sourceLayer);sourceIndex>=0&&layers.splice(sourceIndex,1),destroySimulatedNavigationBarView(sourceLayer.titleBarView),sourceLayer.el.remove(),forwardStack.length=0,syncLayerInteractivity(),syncActiveSystemBars();try{history.replaceState({__mearl_layer__:layers.length},"",mapUrlForSync(replacement.url))}catch{}}function closeLayer(layer,data,final,gotoEvent=!1,resumeOpener=!0,silent=!1){if(layer.closing)return;layer.navigationPreparationCleanup?.(),layer.navigationPreparationCleanup=null,layer.entering&&(layer.entering=!1,enteringLayerCount=Math.max(enteringLayerCount-1,0),layer.enterTimer!==null&&clearTimeout(layer.enterTimer),layer.enterTimer=null,layer.enterTransitionEnd&&(layer.animEl.removeEventListener("transitionend",layer.enterTransitionEnd),layer.enterTransitionEnd=null)),layer.closing=!0;let idx=layers.indexOf(layer);idx>=0&&layers.splice(idx,1),closingLayerCount+=1,blockClosingLayerInteractions(layer),syncLayerInteractivity(),syncActiveSystemBars(),final?forwardStack.length=0:forwardStack.push({url:layer.url,overlay:layer.overlay,openerWin:layer.openerWin,callbackId:layer.callbackId,storageId:layer.storageId,popId:layer.popId}),log3("close â",layer.url,data===void 0?"":data),animateOut(layer,()=>{if(destroySimulatedNavigationBarView(layer.titleBarView),layer.el.remove(),closingLayerCount=Math.max(closingLayerCount-1,0),syncLayerInteractivity(),syncActiveSystemBars(),!!resumeOpener)if(layer.openerWin===window)links.getBridgeProtocol().handleResume({data,storageId:layer.storageId,callbackId:layer.callbackId,final,gotoEvent,silent});else try{layer.openerWin.postMessage({source:SRC,type:"resume",data,storageId:layer.storageId,callbackId:layer.callbackId,final,gotoEvent,silent},"*")}catch{}})}function closeToDepth(depth,data,final){for(;layers.length>depth;){let revealsTarget=layers.length===depth+1;closeLayer(layers[layers.length-1],revealsTarget?data:void 0,final,!1,revealsTarget)}}function closeAllLayers(data,gotoEvent=!1){let depth=layers.length;for(;layers.length>0;){let isRootmostLayer=layers.length===1;closeLayer(layers[layers.length-1],isRootmostLayer?data:void 0,!0,isRootmostLayer&&gotoEvent,isRootmostLayer)}if(depth>0)try{history.go(-depth)}catch{}return depth>0}function requestOverlayClose(layer){if(!(layer.closing||layers[layers.length-1]!==layer)){if(!config2.overlay?.silentTapClose){for(let selector of config2.overlay?.tapCloseSelectors??[])try{let control=layer.frame.contentDocument?.querySelector(selector);if(typeof control?.click!="function")continue;control.click();return}catch{}requestCloseOnTop(void 0);return}pendingClose||pendingHistoryDepth||(closeLayer(layer,void 0,!0,!1,!0,!0),syncHistoryAfterDirectClose())}}function forwardToDepth(depth){for(;layers.length<depth&&forwardStack.length>0;){let entry=forwardStack.pop();openLayer(entry.url,entry.callbackId,entry.overlay,entry.openerWin,!1,entry.popId)}}function requestCloseOnTop(data){if(layers.length===0){history.back();return}if(rootContainerActive){closeLayer(layers[layers.length-1],data,!0),syncHistoryAfterDirectClose();return}armPendingClose(data,8)}function isActiveBusinessWindow(target){let topLayer=layers[layers.length-1];return topLayer?topLayer.frame.contentWindow===target:rootFrame?rootFrame.contentWindow===target:target===window}function finishNativeBack(requestId,target,handled){pendingNativeBack?.requestId!==requestId||pendingNativeBack.target!==target||(clearPendingNativeBack(),!handled&&isActiveBusinessWindow(target)&&requestCloseOnTop(void 0))}function requestNativeBack(){if(!isTop||pendingNativeBack)return;let target=layers[layers.length-1]?.frame.contentWindow??rootFrame?.contentWindow??window;if(!target||target===window){links.getBridgeProtocol().handleNativeBack()||requestCloseOnTop(void 0);return}let requestId=++nativeBackRequestSeq,timer=setTimeout(()=>finishNativeBack(requestId,target,!1),120);pendingNativeBack={requestId,target,timer};try{target.postMessage({source:SRC,type:"nativeBack",requestId},"*")}catch{finishNativeBack(requestId,target,!1)}}function layerForWindow(source){if(source)for(let layer of layers){if(layer.win===source)return layer;let currentWindow=layer.frame.contentWindow;if(currentWindow&¤tWindow===source)return layer.win=currentWindow,layer}}if(isTop){if(!rootContainerActive){let rawPushState=history.pushState.bind(history),rawReplaceState=history.replaceState.bind(history),withDepth=state=>state==null?{__mearl_layer__:layers.length}:typeof state=="object"&&!Array.isArray(state)?{...state,__mearl_layer__:layers.length}:state;try{history.pushState=function(...args){rawPushState(withDepth(args[0]),args[1],args[2])},history.replaceState=function(...args){rawReplaceState(withDepth(args[0]),args[1],args[2])}}catch{}}try{readDepth(history.state)===null&&history.replaceState({__mearl_layer__:0},"")}catch{}window.addEventListener("popstate",e=>{let depth=readDepth(e.state);if(pendingHistoryDepth){let expectedDepth=pendingHistoryDepth.depth;if(clearPendingHistoryDepth(),depth===expectedDepth)return;console.warn(TAG,"æĩč§å¨å垿ˇąåēĻä¸ WebView åēæ äēåĄä¸ä¸č´",{expectedDepth,actualDepth:depth})}if(rootContainerActive){if(depth===null)return;depth<layers.length?closeToDepth(depth,void 0,!1):depth>layers.length&&forwardToDepth(depth);return}if(pendingClose){if(depth!==null&&depth<layers.length){let{data}=pendingClose;clearPendingClose(),closeToDepth(depth,data,!0)}else if(pendingClose.retries>0)armPendingClose(pendingClose.data,pendingClose.retries-1);else{let{data}=pendingClose;clearPendingClose(),closeToDepth(layers.length-1,data,!0)}return}depth!==null&&(depth<layers.length?closeToDepth(depth,void 0,!1):depth>layers.length&&forwardToDepth(depth))})}function broadcastAppMessage(message){links.getBridgeProtocol().handleAppMessage(message);let targets=[rootFrame?.contentWindow??null,...layers.filter(layer=>!layer.closing).map(layer=>layer.frame.contentWindow)];for(let target of targets)if(!(!target||target===window))try{target.postMessage({source:SRC,type:"appMessage",message},"*")}catch{}}function closeMegaPop(popId,data){let index=layers.findIndex(layer=>layer.popId===popId&&!layer.closing);if(index<0)return!1;let closingDepth=layers.length-index;closeToDepth(index,data,!0);try{history.go(-closingDepth)}catch{}return!0}function resizeMegaPop(popId,params){let layer=layers.find(candidate=>candidate.popId===popId&&!candidate.closing);if(!layer?.overlay)return!1;if(params.maxHeight!==void 0){let maxHeight=numberParam(params.maxHeight,1-layer.overlay.topRatio,0,1);layer.overlay.topRatio=1-maxHeight,layer.animEl.style.height=`${maxHeight*100}%`}if(params.maxWidth!==void 0){let maxWidth=numberParam(params.maxWidth,1,0,1);layer.overlay.widthRatio=maxWidth,layer.animEl.style.width=`${maxWidth*100}%`,layer.animEl.style.left=`${(1-maxWidth)/2*100}%`,layer.animEl.style.right="auto"}return params.animated===!0&&(layer.animEl.style.transition="height 200ms ease, width 200ms ease, left 200ms ease"),!0}function executeContainerData(action,params){if(action==="sharedFileRead"||action==="sharedFileWrite"){let fileName=typeof params.fileName=="string"?params.fileName:"";if(!fileName)return{success:!1,value:"missing fileName"};if(action==="sharedFileRead")return{success:!0,value:{data:sharedFiles.get(fileName)??""}};let data=typeof params.data=="string"?params.data:String(params.data??"");return sharedFiles.set(fileName,data),{success:!0,value:{}}}if(action==="sharedDataGet"){let keys=Array.isArray(params.keys)?params.keys.filter(key=>typeof key=="string"):[],data={};for(let key of keys)sharedData.has(key)&&(data[key]=sharedData.get(key));return{success:!0,value:{data}}}if(action==="sharedDataSet"){if(!params.data||typeof params.data!="object"||Array.isArray(params.data))return{success:!1,value:"missing shared data"};for(let[key,value]of Object.entries(params.data))value==null?sharedData.delete(key):sharedData.set(key,value);return{success:!0,value:{}}}if(action==="megaBroadcast")return!params.message||typeof params.message!="object"||Array.isArray(params.message)?{success:!1,value:"missing broadcast message"}:(broadcastAppMessage(params.message),{success:!0,value:{}});if(action==="megaKVSnapshot")return{success:!0,value:{entries:megaKVSnapshot()}};if(action==="megaKVMutation"){let operation=typeof params.operation=="string"?params.operation:"",bizId=typeof params.bizId=="string"?params.bizId:"";if(!bizId)return{success:!1,value:"missing bizID"};let key=typeof params.key=="string"?params.key:"";if((operation==="set"||operation==="remove")&&!key)return{success:!1,value:"missing key"};if(operation==="set"){if(typeof params.value!="string")return{success:!1,value:"missing value"};let entries=megaKVStorage.get(bizId)??new Map;entries.set(key,params.value),megaKVStorage.set(bizId,entries)}else if(operation==="remove"){let entries=megaKVStorage.get(bizId);entries?.delete(key),entries?.size===0&&megaKVStorage.delete(bizId)}else if(operation==="clear")megaKVStorage.delete(bizId);else return{success:!1,value:"unsupported KVStorage operation"};return persistMegaKVStorage(),broadcastAppMessage({kind:"megaKVStorage",operation,bizId,key,value:params.value}),{success:!0,value:{}}}if(action==="legacyBroadcastCreate"){let instanceId=typeof params.instanceId=="string"?params.instanceId:"";return instanceId?(legacyBroadcastChannels.add(instanceId),{success:!0,value:{}}):{success:!1,value:"missing instanceId"}}if(action==="legacyBroadcastPost"){let instanceId=typeof params.instanceId=="string"?params.instanceId:"";return instanceId?legacyBroadcastChannels.has(instanceId)?(broadcastAppMessage({kind:"legacyBroadcast",instanceId,message:params.message}),{success:!0,value:{}}):{success:!1,value:"broadcast channel not found"}:{success:!1,value:"missing instanceId"}}if(action==="legacyBroadcastClose"){let instanceId=typeof params.instanceId=="string"?params.instanceId:"";return instanceId?(legacyBroadcastChannels.delete(instanceId),{success:!0,value:{}}):{success:!1,value:"missing instanceId"}}if(action==="megaPopClose"){let popId=typeof params.popId=="string"?params.popId:"";return popId?closeMegaPop(popId,params.result)?{success:!0,value:{}}:{success:!1,value:"popId not found"}:{success:!1,value:"missing popId"}}if(action==="megaPopResize"){let popId=typeof params.popId=="string"?params.popId:"";return popId?resizeMegaPop(popId,params)?{success:!0,value:{}}:{success:!1,value:"popId not found"}:{success:!1,value:"missing popId"}}return{success:!1,value:"unsupported container data action"}}function requestContainerData(action,params,onSuccess,onFailure){if(isTop){let result=executeContainerData(action,params);setTimeout(()=>result.success?onSuccess(result.value):onFailure(result.value),0);return}let requestId=++containerDataRequestSeq;containerDataCallbacks.set(requestId,{success:onSuccess,failure:onFailure});try{window.top?.postMessage({source:SRC,type:"containerDataRequest",requestId,action,params},"*")}catch(error48){containerDataCallbacks.delete(requestId),onFailure(error48 instanceof Error?error48.message:String(error48))}}function requestOpen(url2,callbackId,webdialog,params){let overlay=resolveOverlayPresentation(url2,params,webdialog),popBeforeOpen=requestsPopBeforeOpen(url2,params),popId=typeof params?.__mearlMegaPopId=="string"?params.__mearlMegaPopId:null;isTop?openLayer(url2,callbackId,overlay,window,!0,popId):window.top?.postMessage({source:SRC,type:"open",url:url2,callbackId,overlay,popBeforeOpen,popId},"*")}function requestClose(data){let payload;try{payload=data===void 0?void 0:JSON.parse(JSON.stringify(data))}catch{payload=void 0}isTop?requestCloseOnTop(payload):window.top?.postMessage({source:SRC,type:"close",data:payload},"*")}if(window.addEventListener("message",event=>{let msg=event.data;if(!(!msg||typeof msg!="object")){if(msg.source==="mearl-content"&&(msg.type==="APP_BRIDGE_SIMULATOR_VISIBILITY"||msg.type==="APP_BRIDGE_RUNTIME_RESPONSES")){if(!isTop||event.source!==window)return;if(msg.type==="APP_BRIDGE_SIMULATOR_VISIBILITY"&&typeof msg.hidden=="boolean"){simulatedPageHidden=msg.hidden,links.getBridgeProtocol().handlePageVisibility(msg.hidden);let lifecycleMessage={source:SRC,type:"simulatorVisibility",hidden:msg.hidden};rootFrame?.contentWindow?.postMessage(lifecycleMessage,"*");for(let layer of layers)layer.closing||layer.frame.contentWindow?.postMessage(lifecycleMessage,"*")}else if(msg.type==="APP_BRIDGE_RUNTIME_RESPONSES"&&msg.profile===config2.profile&&msg.responses&&typeof msg.responses=="object"&&!Array.isArray(msg.responses)){let responses=msg.responses;runtimeResponses={...runtimeResponses??{},...responses},links.getBridgeProtocol().applyRuntimeResponses(responses);let configMessage={source:SRC,type:"runtimeResponses",profile:config2.profile,responses};rootFrame?.contentWindow?.postMessage(configMessage,"*");for(let layer of layers)layer.closing||layer.frame.contentWindow?.postMessage(configMessage,"*")}return}if(msg.source===SRC){if(isTop){let sourceLayer=layerForWindow(event.source),sourceIsRoot=!!(rootFrame?.contentWindow&&rootFrame.contentWindow===event.source);if(!sourceLayer&&!sourceIsRoot)return;if(msg.type==="open"&&typeof msg.url=="string"){let rawOverlay=msg.overlay&&typeof msg.overlay=="object"?msg.overlay:void 0,overlay=rawOverlay?{topRatio:numberParam(rawOverlay.topRatio,.2,0,1),widthRatio:numberParam(rawOverlay.widthRatio,1,0,1),radius:numberParam(rawOverlay.radius,0,0,50),maskAlpha:numberParam(rawOverlay.maskAlpha,.3,0,1),tapClose:boolParam(rawOverlay.tapClose,!0)}:resolveOverlayPresentation(msg.url,void 0,!1),callbackId=typeof msg.callbackId=="number"?msg.callbackId:0,popId=typeof msg.popId=="string"&&msg.popId?msg.popId:null;msg.popBeforeOpen===!0&&sourceLayer?replaceLayer(sourceLayer,msg.url,callbackId,overlay,popId):openLayer(msg.url,callbackId,overlay,event.source??window,!0,popId)}else if(msg.type==="close")requestCloseOnTop(msg.data);else if(msg.type==="closeAll"){let gotoEvent=msg.gotoEvent===!0;if(gotoEvent&&sourceIsRoot&&layers.length===0&&msg.data!==void 0)try{event.source.postMessage({source:SRC,type:"resume",data:msg.data,storageId:null,callbackId:0,final:!0,gotoEvent:!0},"*")}catch{}else closeAllLayers(msg.data,gotoEvent)}else if(msg.type==="appMessageToOpener"&&sourceLayer){let target=sourceLayer.openerWin;if(target===window)links.getBridgeProtocol().handleAppMessage(msg.message);else try{target.postMessage({source:SRC,type:"appMessage",message:msg.message},"*")}catch{}}else if(msg.type==="containerDataRequest"&&typeof msg.requestId=="number"&&typeof msg.action=="string"&&msg.params&&typeof msg.params=="object"&&!Array.isArray(msg.params)&&event.source){let result=executeContainerData(msg.action,msg.params);try{event.source.postMessage({source:SRC,type:"containerDataResponse",requestId:msg.requestId,success:result.success,value:result.value},"*")}catch{}}else if(msg.type==="nativeBackResult"&&typeof msg.requestId=="number"&&typeof msg.handled=="boolean"&&event.source)finishNativeBack(msg.requestId,event.source,msg.handled);else if(msg.type==="urlChanged"&&typeof msg.url=="string"){let topLayer=layers[layers.length-1];if(sourceIsRoot&&!topLayer){rootBusinessUrl=msg.url;let mapped=mapUrlForSync(msg.url);if(mapped)try{history.replaceState({__mearl_layer__:0},"",mapped)}catch{}}else if(topLayer&&!topLayer.closing&&sourceLayer===topLayer){topLayer.url=msg.url,topLayer.titleBarStateExplicit&&topLayer.titleBarState&&cacheExplicitTitleBarState(topLayer,topLayer.titleBarState);let mapped=mapUrlForSync(msg.url);if(mapped)try{history.replaceState({__mearl_layer__:layers.length},"",mapped)}catch{}}}else if(msg.type==="title"&&typeof msg.title=="string"){let topLayer=layers[layers.length-1];if(sourceIsRoot&&!topLayer)try{document.title=msg.title,syncSimulatedTitleBar()}catch{}else if(topLayer&&sourceLayer===topLayer){document.title=msg.title;let state=resolvedTitleBarState(topLayer);topLayer.titleBarState={...state,title:msg.title},syncLayerViewport(topLayer,topLayer.titleBarState)}}else if(msg.type==="titleBarState"){let state=parseReportedTitleBarState(msg.state);if(state&&sourceIsRoot)links.getSystemBars().setPresentedRootTitleBarState(state);else if(state&&sourceLayer){let explicit=msg.explicit===!0;sourceLayer.titleBarStateReady=!0,explicit?(sourceLayer.titleBarState=state,sourceLayer.titleBarStateExplicit=!0,cacheExplicitTitleBarState(sourceLayer,state)):sourceLayer.titleBarStateExplicit||(sourceLayer.titleBarState=state);let resolvedState=sourceLayer.titleBarState??state;syncLayerViewport(sourceLayer,resolvedState)}}}else if(msg.type==="simulatorVisibility"&&typeof msg.hidden=="boolean"){if(event.source!==window.top)return;links.getBridgeProtocol().handlePageVisibility(msg.hidden)}else if(msg.type==="appMessage"){if(event.source!==window.top)return;links.getBridgeProtocol().handleAppMessage(msg.message)}else if(msg.type==="nativeBack"&&typeof msg.requestId=="number"){if(event.source!==window.top)return;let handled=links.getBridgeProtocol().handleNativeBack();window.top?.postMessage({source:SRC,type:"nativeBackResult",requestId:msg.requestId,handled},"*")}else if(msg.type==="containerDataResponse"&&typeof msg.requestId=="number"){if(event.source!==window.top)return;let callback=containerDataCallbacks.get(msg.requestId);if(!callback)return;containerDataCallbacks.delete(msg.requestId),msg.success===!0?callback.success(msg.value):callback.failure(msg.value)}else if(msg.type==="runtimeResponses"&&msg.profile===config2.profile&&msg.responses&&typeof msg.responses=="object"&&!Array.isArray(msg.responses)){if(event.source!==window.top)return;links.getBridgeProtocol().applyRuntimeResponses(msg.responses)}else if(msg.type==="resume"){if(event.source!==window.top)return;links.getBridgeProtocol().handleResume({data:msg.data,storageId:msg.storageId??null,callbackId:typeof msg.callbackId=="number"?msg.callbackId:0,final:msg.final===!0,gotoEvent:msg.gotoEvent===!0,silent:msg.silent===!0})}else event.source!==window.top&&window.top?.postMessage(msg,"*");return}pageTransport.handleMessage(msg)}}),!isTop&&isContainerFrame){let reportUrl=()=>{try{window.top?.postMessage({source:SRC,type:"urlChanged",url:restoreLayerBusinessUrl(location.href)},"*")}catch{}};try{let origPushState=history.pushState.bind(history),origReplaceState=history.replaceState.bind(history);history.pushState=function(...args){origPushState(...args),reportUrl()},history.replaceState=function(...args){origReplaceState(...args),reportUrl()},window.addEventListener("popstate",reportUrl),window.addEventListener("hashchange",reportUrl)}catch{}}if(isContainerFrame){let requestProxyLocationOpen=url2=>{if(links.getBridgeProtocol().handleMaybeScheme(url2))return!0;try{let current=new URL(restoreLayerBusinessUrl(location.href)),target=new URL(url2,current);return!/^https?:$/.test(target.protocol)||target.origin===current.origin&&target.pathname===current.pathname&&target.search===current.search?!1:(requestOpen(target.href,0,!1),!0)}catch{return!1}};Object.defineProperty(window,"__PROXY_LOCATION__",{value:{get href(){return location.href},set href(url2){requestProxyLocationOpen(url2)||(location.href=mapLayerFrameUrl(url2))},replace(url2){links.getBridgeProtocol().handleMaybeScheme(url2)||location.replace(mapLayerFrameUrl(url2))},assign(url2){requestProxyLocationOpen(url2)||location.assign(mapLayerFrameUrl(url2))}},writable:!1,configurable:!0})}if(isContainerFrame){document.addEventListener("click",event=>{let el=event.target;for(;el&&el.tagName!=="A";)el=el.parentElement;if(!el)return;let href=el.getAttribute("href");if(href){if(links.getBridgeProtocol().handleMaybeScheme(href)){event.preventDefault(),event.stopPropagation();return}/^https?:/i.test(href)&&el.getAttribute("target")==="_blank"&&(event.preventDefault(),event.stopPropagation(),requestOpen(href,0,!1))}},!0);let origOpen=window.open;window.open=function(url2,target,features){let urlStr=typeof url2=="string"?url2:url2 instanceof URL?url2.href:"";return links.getBridgeProtocol().handleMaybeScheme(urlStr)?null:/^https?:/i.test(urlStr)?(requestOpen(urlStr,0,!1),null):origOpen?origOpen.call(window,url2,target,features):null};try{let proto=Location.prototype,origAssign=proto.assign,origReplace=proto.replace;origAssign&&(proto.assign=function(url2){if(links.getBridgeProtocol().handleMaybeScheme(url2))return;let upgraded=location.protocol==="https:"&&url2.startsWith("http:")?"https:"+url2.slice(5):url2;origAssign.call(this,upgraded)}),origReplace&&(proto.replace=function(url2){if(links.getBridgeProtocol().handleMaybeScheme(url2))return;let upgraded=location.protocol==="https:"&&url2.startsWith("http:")?"https:"+url2.slice(5):url2;origReplace.call(this,upgraded)})}catch{}}return log3("厚å¨į¯åĸåˇ˛å°ąįģĒ",isTop?"(top)":isRootFrame?"(root)":isLayerFrame?"(layer)":"(iframeīŧäģ
æĄĨ)"),{getRootFrame:()=>rootFrame,getLayers:()=>layers,getClosingLayerCount:()=>closingLayerCount,requestOpen,requestClose,requestNativeBack,requestContainerData,closeAllLayers}}var APP_PROFILE_RUNTIME_FACTORIES={environment:installAppProfileEnvironment,containerStack:installAppProfileContainerStack,bridgeProtocol:installAppProfileBridgeProtocol,pageTransport:installAppProfilePageTransport,systemBars:installAppProfileSystemBars};function buildAppProfileRuntimeCallSource(configExpression){return`(${installAppProfileRuntime.toString()})(${configExpression},{environment:${installAppProfileEnvironment.toString()},pageTransport:${installAppProfilePageTransport.toString()},containerStack:${installAppProfileContainerStack.toString()},systemBars:${installAppProfileSystemBars.toString()},bridgeProtocol:${installAppProfileBridgeProtocol.toString()}})`}function installAppProfileRuntime(config2,factories=APP_PROFILE_RUNTIME_FACTORIES){let environment=factories.environment(config2);if(!environment)return;let pageTransport=factories.pageTransport(config2,environment),containerStack=factories.containerStack(config2,environment,{pageTransport,getSystemBars:()=>systemBars,getBridgeProtocol:()=>bridgeProtocol}),systemBars=factories.systemBars(config2,environment,{getRootFrame:containerStack.getRootFrame,getLayers:containerStack.getLayers,getClosingLayerCount:containerStack.getClosingLayerCount,requestClose:containerStack.requestClose,requestNativeBack:containerStack.requestNativeBack}),bridgeProtocol=factories.bridgeProtocol(config2,environment,{pageTransport,systemBars,requestOpen:containerStack.requestOpen,requestClose:containerStack.requestClose,requestCloseAll:containerStack.closeAllLayers,requestContainerData:containerStack.requestContainerData})}import https from"node:https";import http3 from"node:http";var TYPE_INTO_ELEMENT_SRC=typeIntoElement.toString(),CLICK_ELEMENT_VIA_JS_SRC=clickElementViaJS.toString(),GET_CLICK_COORDS_FROM_NODE_SRC=getClickCoordsFromNode.toString();function nodeFetch(urlStr,options={}){return new Promise((resolve3,reject)=>{let url2=new URL(urlStr),isHttps=url2.protocol==="https:",lib=isHttps?https:http3,{method="GET",headers={},body,timeoutMs=3e4}=options,req=lib.request({host:url2.hostname,port:url2.port||(isHttps?443:80),path:url2.pathname+url2.search,method,headers},res=>{let responseHeaders={};for(let[key,value]of Object.entries(res.headers))typeof value=="string"?responseHeaders[key]=value:Array.isArray(value)&&(responseHeaders[key]=value.join(", "));let chunks=[];res.on("data",chunk=>chunks.push(Buffer.from(chunk))),res.on("end",()=>{let bodyBuffer=Buffer.concat(chunks);resolve3({status:res.statusCode??0,statusText:res.statusMessage??"",headers:responseHeaders,body:bodyBuffer.toString("utf-8"),bodyBuffer})})});req.on("error",reject),req.setTimeout(timeoutMs,()=>{req.destroy(),reject(new Error(`Request timeout: ${urlStr}`))}),body&&req.write(body),req.end()})}async function getCookiesForUrl(session,targetUrl){let result=await session.client.sendCommand("Network.getCookies",{urls:[targetUrl]}),map2=new Map;for(let cookie of result.cookies??[])map2.set(cookie.name,cookie.value);return map2}function decodeTracknick(raw){if(!raw)return"";try{return decodeURIComponent(raw).replace(/\\u([0-9a-fA-F]{4})/g,(_match,hex3)=>String.fromCharCode(parseInt(hex3,16)))}catch{return raw}}function buildMultipartFormBody(fields){let boundary=`----mearl-${Date.now()}-${Math.random().toString(36).slice(2)}`,body=[...Object.entries(fields).map(([name,value])=>`--${boundary}\r
|
|
752
1046
|
Content-Disposition: form-data; name="${name}"\r
|
|
753
1047
|
\r
|
|
754
1048
|
${value}\r
|
|
755
1049
|
`),`--${boundary}--\r
|
|
756
|
-
`].join("");return{contentType:`multipart/form-data; boundary=${boundary}`,body}}async function waitForPageLoad(session,timeoutMs){return new Promise((resolve3,reject)=>{let settled=!1,removeLoadListener=()=>{},finish=error48=>{settled||(settled=!0,clearTimeout(timer),removeLoadListener(),error48?reject(error48):resolve3())},timer=setTimeout(()=>{finish(new Error(`Page load timeout after ${timeoutMs}ms`))},timeoutMs);removeLoadListener=session.client.on("Page.loadEventFired",()=>finish()),session.client.sendCommand("Runtime.evaluate",{expression:"document.readyState",returnByValue:!0}).then(result=>{result.result?.value==="complete"&&finish()}).catch(()=>{})})}async function getPageViewportSize(session){let result=await session
|
|
1050
|
+
`].join("");return{contentType:`multipart/form-data; boundary=${boundary}`,body}}async function waitForPageLoad(session,timeoutMs){if(isCdpDeviceShellActive(session)){let deadline=Date.now()+timeoutMs;for(;Date.now()<deadline;){if((await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:"document.readyState",returnByValue:!0}).catch(()=>null))?.result?.value==="complete")return;await new Promise(resolve3=>setTimeout(resolve3,50))}throw new Error(`Page load timeout after ${timeoutMs}ms`)}return new Promise((resolve3,reject)=>{let settled=!1,removeLoadListener=()=>{},finish=error48=>{settled||(settled=!0,clearTimeout(timer),removeLoadListener(),error48?reject(error48):resolve3())},timer=setTimeout(()=>{finish(new Error(`Page load timeout after ${timeoutMs}ms`))},timeoutMs);removeLoadListener=session.client.on("Page.loadEventFired",()=>finish()),session.client.sendCommand("Runtime.evaluate",{expression:"document.readyState",returnByValue:!0}).then(result=>{result.result?.value==="complete"&&finish()}).catch(()=>{})})}async function getPageViewportSize(session){let result=await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:`({
|
|
757
1051
|
width: window.visualViewport ? window.visualViewport.width : window.innerWidth,
|
|
758
1052
|
height: window.visualViewport ? window.visualViewport.height : window.innerHeight
|
|
759
|
-
})`,returnByValue:!0}),width=result.result?.value?.width,height=result.result?.value?.height;return typeof width!="number"||typeof height!="number"||width<=0||height<=0?null:{width,height}}async function getCdpInputViewportSize(session){let metrics;try{metrics=await session.client.sendCommand("Page.getLayoutMetrics",{})}catch{return null}let viewport=metrics.cssVisualViewport??metrics.visualViewport??metrics.cssLayoutViewport??metrics.layoutViewport,width=viewport?.clientWidth,height=viewport?.clientHeight;return typeof width!="number"||typeof height!="number"||width<=0||height<=0?null:{width,height}}async function toCdpInputPoint(session,x,y){let[pageViewport,cdpViewport]=await Promise.all([getPageViewportSize(session),getCdpInputViewportSize(session)]);if(!pageViewport||!cdpViewport)return{x,y};let scaleX=cdpViewport.width/pageViewport.width,scaleY=cdpViewport.height/pageViewport.height;return!Number.isFinite(scaleX)||!Number.isFinite(scaleY)||scaleX<=0||scaleY<=0||Math.abs(scaleX-1)<.01&&Math.abs(scaleY-1)<.01?{x,y}:{x:x*scaleX,y:y*scaleY}}async function dispatchCdpClick(session,x,y,pointerType){let point=await toCdpInputPoint(session,x,y);if(pointerType==="touch"){await sendCdpInputCommand(session,"Input.dispatchTouchEvent",{type:"touchStart",touchPoints:[point]}),await sendCdpInputCommand(session,"Input.dispatchTouchEvent",{type:"touchEnd",touchPoints:[]});return}await sendCdpInputCommand(session,"Input.dispatchMouseEvent",{type:"mouseMoved",x:point.x,y:point.y}),await sendCdpInputCommand(session,"Input.dispatchMouseEvent",{type:"mousePressed",x:point.x,y:point.y,button:"left",buttons:1,clickCount:1}),await sendCdpInputCommand(session,"Input.dispatchMouseEvent",{type:"mouseReleased",x:point.x,y:point.y,button:"left",buttons:0,clickCount:1})}async function dispatchCdpDrag(session,from,to,pointerType,durationMs){let[start,end]=await Promise.all([toCdpInputPoint(session,from.x,from.y),toCdpInputPoint(session,to.x,to.y)]),path23=buildPageDragPath(start,end,durationMs),waitForNextPoint=async()=>{path23.intervalMs<=0||await new Promise(resolve3=>setTimeout(resolve3,path23.intervalMs))};if(pointerType==="touch"){await sendCdpInputCommand(session,"Input.dispatchTouchEvent",{type:"touchStart",touchPoints:[start]});let primaryError2;try{for(let point of path23.points)await waitForNextPoint(),await sendCdpInputCommand(session,"Input.dispatchTouchEvent",{type:"touchMove",touchPoints:[point]})}catch(error48){throw primaryError2=error48,error48}finally{await sendCdpInputCommand(session,"Input.dispatchTouchEvent",{type:"touchEnd",touchPoints:[]}).catch(error48=>{if(primaryError2===void 0)throw error48})}return{steps:path23.points.length}}await sendCdpInputCommand(session,"Input.dispatchMouseEvent",{type:"mouseMoved",x:start.x,y:start.y}),await sendCdpInputCommand(session,"Input.dispatchMouseEvent",{type:"mousePressed",x:start.x,y:start.y,button:"left",buttons:1,clickCount:1});let primaryError;try{for(let point of path23.points)await waitForNextPoint(),await sendCdpInputCommand(session,"Input.dispatchMouseEvent",{type:"mouseMoved",x:point.x,y:point.y,button:"left",buttons:1})}catch(error48){throw primaryError=error48,error48}finally{await sendCdpInputCommand(session,"Input.dispatchMouseEvent",{type:"mouseReleased",x:end.x,y:end.y,button:"left",buttons:0,clickCount:1}).catch(error48=>{if(primaryError===void 0)throw error48})}return{steps:path23.points.length}}async function sendCdpInputCommand(session,method,params){try{await session.client.sendCommand(method,params,1e4)}catch(error48){if(error48 instanceof Error&&error48.message===`CDP command timeout: ${method}`){let eventType=typeof params.type=="string"?` (${params.type})`:"";throw new Error(`CDP ${method}${eventType} timed out after ${1e4}ms. The page may already have changed; verify its current state before retrying.`,{cause:error48})}throw error48}}async function resolveBackendNodeObjectId(session,backendNodeId){let objectId=(await session
|
|
760
|
-
Content-Disposition: form-data; name="${safeName}"\r
|
|
761
|
-
\r
|
|
762
|
-
${String(value)}\r
|
|
763
|
-
`))}for(let file2 of resolvedFiles){let fieldName=escapeMultipartQuotedValue(file2.fieldName),filename=escapeMultipartQuotedValue(file2.filename);chunks.push(Buffer.from(`--${boundary}\r
|
|
764
|
-
Content-Disposition: form-data; name="${fieldName}"; filename="${filename}"\r
|
|
765
|
-
Content-Type: ${file2.contentType}\r
|
|
766
|
-
\r
|
|
767
|
-
`),file2.content,Buffer.from(`\r
|
|
768
|
-
`))}return chunks.push(Buffer.from(`--${boundary}--\r
|
|
769
|
-
`)),{contentType:`multipart/form-data; boundary=${boundary}`,body:Buffer.concat(chunks)}}function hasMultipartPayload(data){return data.formData!==void 0||data.files!==void 0}async function executeNodeSendRequest(data,cookieMap=new Map){let{url:url2,method="GET",headers={},params,body,formData,files,responseType="auto",timeout=3e4}=data;if(!url2||typeof url2!="string"||url2.trim()==="")throw new Error("Invalid url: url must be a non-empty string");let normalizedMethod=method.toUpperCase();if(!ALLOWED_METHODS.has(normalizedMethod))throw new Error(`Invalid method: ${method}. Allowed: ${[...ALLOWED_METHODS].join(", ")}`);if(!Number.isFinite(timeout)||timeout<=0)throw new Error("timeout must be a positive number");let targetUrl=new URL(url2);for(let[key,value]of Object.entries(params??{}))targetUrl.searchParams.set(key,String(value));let requestHeaders={Accept:"application/json, text/plain, */*","Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8","User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",...headers},resolvedSourceHeaders=getSendRequestSourceHeaders(targetUrl,headers);resolvedSourceHeaders.referer?setHeader(requestHeaders,"Referer",resolvedSourceHeaders.referer):removeHeader(requestHeaders,"Referer"),resolvedSourceHeaders.origin?setHeader(requestHeaders,"Origin",resolvedSourceHeaders.origin):removeHeader(requestHeaders,"Origin");let cookieHeader=[...cookieMap.entries()].map(([key,value])=>`${key}=${value}`).join("; ");cookieHeader&&setHeader(requestHeaders,"Cookie",cookieHeader);let xsrfToken=cookieMap.get("XSRF-TOKEN");xsrfToken&&!findSendRequestHeaderName(requestHeaders,"x-xsrf-token")&&setHeader(requestHeaders,"X-XSRF-TOKEN",xsrfToken);let requestBody;if(hasMultipartPayload(data)){if(body!=null)throw new Error("body cannot be combined with formData or files");if(normalizedMethod==="GET"||normalizedMethod==="HEAD")throw new Error(`${normalizedMethod} requests cannot use formData or files`);if(findSendRequestHeaderName(requestHeaders,"content-type"))throw new Error("Do not set Content-Type when using formData or files; Mearl sets the boundary");let multipart=await buildMultipartBody(formData,files);requestBody=multipart.body,setHeader(requestHeaders,"Content-Type",multipart.contentType),setHeader(requestHeaders,"Content-Length",String(multipart.body.byteLength))}else body!=null&&!["GET","HEAD"].includes(normalizedMethod)&&(typeof body=="string"?(requestBody=body,findSendRequestHeaderName(requestHeaders,"content-type")||setHeader(requestHeaders,"Content-Type","text/plain")):(requestBody=JSON.stringify(body),findSendRequestHeaderName(requestHeaders,"content-type")||setHeader(requestHeaders,"Content-Type","application/json")));let result=await nodeFetch(targetUrl.toString(),{method:normalizedMethod,headers:requestHeaders,body:requestBody,timeoutMs:timeout}),contentType=(result.headers["content-type"]??"").split(";")[0].trim().toLowerCase(),responseHeaders=Object.fromEntries(Object.entries(result.headers).filter(([name])=>name.toLowerCase()!=="set-cookie"&&name.toLowerCase()!=="set-cookie2")),responseBody,bodyType;if(responseType==="auto"&&isBinarySendRequestContentType(contentType))responseBody=result.bodyBuffer.toString("base64"),bodyType="base64";else{let trimmed=result.body.trimStart();if(responseType==="json"||responseType==="auto"&&contentType.includes("application/json")||responseType==="auto"&&(trimmed.startsWith("{")||trimmed.startsWith("[")))try{responseBody=JSON.parse(result.body),bodyType="json"}catch{if(responseType==="json")throw new Error("send_request expected a JSON response");responseBody=result.body,bodyType="text"}else responseBody=result.body,bodyType="text"}return{success:!0,status:result.status,statusText:result.statusText,headers:responseHeaders,body:responseBody,bodyType,attachedCookieCount:cookieMap.size}}async function cdpSendRequest(session,data){if(!data.url||typeof data.url!="string")throw new Error("Invalid url: url must be a non-empty string");let cookieMap=new Map;if(data.withCookies!==!1)try{cookieMap=await getCookiesForUrl(session,new URL(data.url).toString())}catch{}return executeNodeSendRequest(data,cookieMap)}async function prepareCdpMtopRequest(session,data,stream=!1){let resolved=resolveMtopRequest(data),cookieMap=await getCookiesForUrl(session,resolved.gatewayUrl.toString()),prepared=prepareSignedMtopRequest(resolved,cookieMap,stream);return{...prepared,requestHeaders:{...prepared.cookieHeader?{Cookie:prepared.cookieHeader}:{},...prepared.requestHeaders}}}async function cdpSendMtopRequest(session,data){let prepared=await prepareCdpMtopRequest(session,data),result=await nodeFetch(prepared.targetUrl.toString(),{method:prepared.normalizedMethod,headers:prepared.requestHeaders,body:prepared.body,timeoutMs:prepared.timeout});return{success:!0,response:parseMtopResponseText(result.body),requestData:prepared.requestData}}async function cdpSendMtopStreamRequest(session,data,callbacks){let prepared=await prepareCdpMtopRequest(session,data,!0),controller=new AbortController,timeoutId=setTimeout(()=>controller.abort(),prepared.timeout);try{await callbacks.onRequestPrepared?.({method:prepared.normalizedMethod,url:prepared.targetUrl.toString(),requestHeaders:Object.entries(prepared.requestHeaders).map(([name,value])=>({name,value}))});let response=await fetch(prepared.targetUrl,{method:prepared.normalizedMethod,headers:prepared.requestHeaders,body:prepared.body,signal:controller.signal}),responseHeaders=[];return response.headers.forEach((value,name)=>{name.toLowerCase()!=="set-cookie"&&responseHeaders.push({name,value})}),await callbacks.onResponse?.({status:response.status,statusText:response.statusText,responseHeaders}),{success:!0,response:await consumeMtopSseResponse(response,event=>callbacks.onReceive(event.data)),requestData:prepared.requestData}}catch(error48){throw error48 instanceof Error&&error48.name==="AbortError"?new Error(`send_mtop_stream timed out after ${prepared.timeout}ms: ${prepared.api}`,{cause:error48}):new Error(`send_mtop_stream failed: ${error48 instanceof Error?error48.message:String(error48)}`,{cause:error48})}finally{clearTimeout(timeoutId)}}async function cdpGetApiSchema(session,data){let{api,version:version2="1.0"}=data;if(!api||typeof api!="string")throw new Error("Invalid api: api must be a non-empty string");let targetUrl="https://ultramax.alibaba-inc.com/ultramax/api/query",payload=JSON.stringify({type:"RPC",rpcName:api,rpcVersion:version2}),cookieMap=await getCookiesForUrl(session,targetUrl),cookieHeader=buildCookieHeaderValue(cookieMap),result=await nodeFetch(targetUrl,{method:"POST",headers:{"Content-Type":"application/json",...cookieHeader?{Cookie:cookieHeader}:{}},body:payload,timeoutMs:15e3});if(result.status!==200)throw new Error(`Ultramax API returned status ${result.status}`);let responseBody;try{responseBody=JSON.parse(result.body)}catch{throw new Error(`Failed to parse Ultramax response: ${result.body.slice(0,200)}`)}return responseBody}registerActions([{name:"send_request",session:"page",handler:cdpSendRequest},{name:"send_mtop_request",session:"page",handler:cdpSendMtopRequest},{name:"get_api_schema",session:"page",handler:cdpGetApiSchema}]);var registries=new WeakMap;function getPageRefRegistry(session){let registry2=registries.get(session);if(!registry2){registry2=new BackendNodeRefRegistry,registries.set(session,registry2);let activeRegistry=registry2;session.client.on("Page.frameNavigated",params=>{params.frame?.parentId||activeRegistry.clearDocument()})}return registry2}function beginPageSnapshotRefs(session){return getPageRefRegistry(session).beginSnapshot()}function resolvePageRef(session,ref){return registries.get(session)?.resolve(ref)}function deletePageRef(session,ref){registries.get(session)?.delete(ref)}function clearPageRefsForNavigation(session){registries.get(session)?.clearDocument()}async function enrichCdpPageChangeSetWithRefs(session,observation){return enrichPageChangeSetWithRefs(observation,getPageRefRegistry(session),selectors=>resolveUniqueBackendNodeIds((method,params)=>session.client.sendCommand(method,params),selectors),(node,backendNodeId)=>({backendNodeId,role:node.role??"",name:node.name??""}))}var APP_PROFILE_BINDING="__mearlCdpAppProfileRelay",appProfileStates=new WeakMap;function serializeForSource(value){return JSON.stringify(value).replace(/[\u2028\u2029]/g,character=>character==="\u2028"?"\\u2028":"\\u2029")}function installCdpAppProfileRelay(bindingName){let browser=globalThis,target=globalThis;target.__mearlCdpAppProfileRelayInstalled__||(target.__mearlCdpAppProfileRelayInstalled__=!0,browser.addEventListener("message",event=>{if(event.source!==globalThis)return;let message=event.data;if(!message||message.source!=="mearl-app-bridge")return;let requestId=message.requestId;if(typeof requestId!="number")return;if(message.type==="prepareWebView"){browser.postMessage({source:"mearl-content",type:"APP_BRIDGE_PREPARE_WEBVIEW_RESPONSE",requestId,result:{success:!0}},"*");return}if(message.type!=="mtop"&&message.type!=="mtopStream"&&message.type!=="userInfo")return;let binding=target[bindingName];if(typeof binding=="function")try{binding(JSON.stringify({type:message.type,requestId,payload:message.payload}))}catch{}}))}function installEarlyAppProfileEnvironment(config2){let browser=globalThis,target=globalThis;for(let[key,value]of Object.entries(config2.globals))try{target[key]=value}catch{}let insets=config2.safeAreaInsets??{top:config2.statusBarHeight,right:0,bottom:0,left:0};target.__STATUS_BAR_HEIGHT__=config2.statusBarHeight,target.__SAFE_AREA_INSET_BOTTOM__=insets.bottom;for(let[key,value]of[["userAgent",config2.userAgent],["platform",config2.navigatorPlatform],["vendor","Apple Computer, Inc."],["appVersion",config2.userAgent.replace(/^Mozilla\//,"")],["maxTouchPoints",config2.maxTouchPoints]])try{Object.defineProperty(browser.navigator,key,{configurable:!0,get:()=>value})}catch{}}function installWhenDocumentElementExists(install){let browser=globalThis;if(browser.document.documentElement){install();return}let observer=new browser.MutationObserver(()=>{browser.document.documentElement&&(observer.disconnect(),install())});observer.observe(browser.document,{childList:!0})}function buildDocumentSource(config2){return`;(() => {const config=${serializeForSource(config2)};(${installCdpAppProfileRelay.toString()})(${JSON.stringify(APP_PROFILE_BINDING)});(${installEarlyAppProfileEnvironment.toString()})(config);(${installWhenDocumentElementExists.toString()})(() => {${buildAppProfileRuntimeCallSource("config")};});})();`}function appProfileEmulationCommands(config2,userAgent){return buildEnableEmulationCommands(config2).map(command=>command.method==="Emulation.setUserAgentOverride"?{...command,params:{userAgent,platform:config2.platform}}:command)}async function sendCommands(client2,commands){for(let{method,params,optional:optional2}of commands)await client2.sendCommand(method,params).catch(error48=>{if(!optional2)throw error48})}async function postRuntimeMessage(client2,executionContextId,message){await client2.sendCommand("Runtime.evaluate",{expression:`window.postMessage(${serializeForSource(message)}, '*')`,...typeof executionContextId=="number"?{contextId:executionContextId}:{}})}function listenForBridgeRequests(session,client2,state){return client2.on("Runtime.bindingCalled",params=>{if(params?.name!==APP_PROFILE_BINDING||appProfileStates.get(session)!==state)return;let request;try{request=JSON.parse(params.payload)}catch{return}if(typeof request.requestId!="number")return;let requestId=request.requestId,contextId=typeof params.executionContextId=="number"?params.executionContextId:void 0,reply=message=>postRuntimeMessage(client2,contextId,{requestId,source:"mearl-content",...message});(async()=>{if(request.type==="userInfo"){try{let result=await session.client.sendCommand("Network.getCookies",{urls:[session.url]}),response=resolveAppProfileUserInfo(session.url,(result.cookies??[]).map(cookie=>({name:cookie.name,value:cookie.value})));await reply({type:"APP_BRIDGE_USER_INFO_RESPONSE",result:{success:!0,response}})}catch(error48){await reply({type:"APP_BRIDGE_USER_INFO_RESPONSE",result:{success:!1,error:error48 instanceof Error?error48.message:String(error48)}})}return}let payload=request.payload??{},mtopPayload={...payload,...typeof payload.v=="string"&&payload.version===void 0?{version:payload.v}:{}},streamCapture;try{if(request.type==="mtopStream"){await cdpSendMtopStreamRequest(session,mtopPayload,{onRequestPrepared:metadata=>{streamCapture=recordCdpMtopStreamStart(session.buffers,{api:String(mtopPayload.api??""),url:metadata.url,method:metadata.method,requestHeaders:metadata.requestHeaders,requestData:mtopPayload.data??null})},onResponse:metadata=>{streamCapture&&recordCdpMtopStreamResponse(session.buffers,streamCapture,metadata)},onReceive:async data=>{streamCapture&&recordCdpMtopStreamChunk(session.buffers,streamCapture,data),await reply({type:"APP_BRIDGE_MTOP_STREAM_EVENT",eventType:"onReceive",data})}}),streamCapture&&recordCdpMtopStreamEnd(session.buffers,streamCapture),await reply({type:"APP_BRIDGE_MTOP_STREAM_EVENT",eventType:"onFinish",data:{}});return}let result=await cdpSendMtopRequest(session,mtopPayload);await reply({type:"APP_BRIDGE_MTOP_RESPONSE",result})}catch(error48){let message=error48 instanceof Error?error48.message:String(error48);request.type==="mtopStream"?(streamCapture&&recordCdpMtopStreamEnd(session.buffers,streamCapture,{error:message}),await reply({type:"APP_BRIDGE_MTOP_STREAM_EVENT",eventType:"onError",data:{ret:["HY_FAILED"],msg:message}})):await reply({type:"APP_BRIDGE_MTOP_RESPONSE",result:{success:!1,error:message}})}})().catch(()=>{})})}async function installChildTarget(session,state,params,source){let sessionId=params.sessionId;if(typeof sessionId!="string")return;let child=session.client.createChildSession(sessionId);try{if(params.targetInfo?.type!=="iframe"||appProfileStates.get(session)!==state)return;await child.sendCommand("Runtime.enable");let frameName=(await child.sendCommand("Runtime.evaluate",{expression:"window.name",returnByValue:!0})).result?.value;if(frameName!=="__mearl_root__"&&frameName!=="__mearl_layer__")return;state.emulation?await sendCommands(child,appProfileEmulationCommands(state.emulation,state.config.userAgent)):await child.sendCommand("Emulation.setUserAgentOverride",{userAgent:state.config.userAgent,platform:state.config.navigatorPlatform}),await child.sendCommand("Runtime.addBinding",{name:APP_PROFILE_BINDING}),state.disposeListeners.push(listenForBridgeRequests(session,child,state)),state.childClients.push(child),await child.sendCommand("Page.addScriptToEvaluateOnNewDocument",{source}).catch(()=>{}),await child.sendCommand("Runtime.evaluate",{expression:source})}finally{await child.sendCommand("Runtime.runIfWaitingForDebugger").catch(()=>{})}}async function disposeState(session,state,disableDeviceEmulation){appProfileStates.get(session)===state&&appProfileStates.delete(session);for(let dispose of state.disposeListeners.splice(0))dispose();await session.client.sendCommand("Target.setAutoAttach",{autoAttach:!1,waitForDebuggerOnStart:!1,flatten:!0}).catch(()=>{}),await session.client.sendCommand("Page.removeScriptToEvaluateOnNewDocument",{identifier:state.documentScriptIdentifier}).catch(()=>{}),await Promise.allSettled([session.client,...state.childClients].map(client2=>client2.sendCommand("Runtime.removeBinding",{name:APP_PROFILE_BINDING}))),disableDeviceEmulation&&(state.ownsDeviceEmulation||!state.independentDeviceEmulation?(await sendCommands(session.client,buildDisableEmulationCommands()),session.emulation=void 0):(await sendCommands(session.client,buildEnableEmulationCommands(state.independentDeviceEmulation)),session.emulation={mobile:state.independentDeviceEmulation.mobile,touch:state.independentDeviceEmulation.touch}))}function resolveCdpAppProfile(profile,options={}){let resolved=resolveAppProfile(profile,{os:options.os,appVersion:options.appVersion,deviceModel:options.deviceModel,simulateSystemBars:options.simulateSystemBars,bridgeConfig:options.bridgeConfig}),emulation=resolveEmulationConfig({preset:resolved.recommendedPreset,...options.emulation,enabled:!0});return{profile:resolved,emulation}}async function applyResolvedCdpAppProfile(session,resolved){let previous=appProfileStates.get(session);previous&&await disposeState(session,previous,!1);let source=buildDocumentSource(resolved.profile.injected);await sendCommands(session.client,appProfileEmulationCommands(resolved.emulation,resolved.profile.ua)),session.emulation={mobile:resolved.emulation.mobile,touch:resolved.emulation.touch},await session.client.sendCommand("Runtime.enable"),await session.client.sendCommand("Runtime.addBinding",{name:APP_PROFILE_BINDING});let script=await session.client.sendCommand("Page.addScriptToEvaluateOnNewDocument",{source});if(typeof script.identifier!="string"||!script.identifier)throw await sendCommands(session.client,buildDisableEmulationCommands()),session.emulation=void 0,new Error("Chrome did not return an app profile bootstrap script identifier");let state={config:resolved.profile.injected,documentScriptIdentifier:script.identifier,emulation:resolved.emulation,ownsDeviceEmulation:!0,disposeListeners:[],childClients:[]};appProfileStates.set(session,state),state.disposeListeners.push(listenForBridgeRequests(session,session.client,state)),state.disposeListeners.push(session.client.on("Target.attachedToTarget",params=>{installChildTarget(session,state,params,source).catch(()=>{})})),await session.client.sendCommand("Target.setAutoAttach",{autoAttach:!0,waitForDebuggerOnStart:!0,flatten:!0,filter:[{type:"iframe"},{exclude:!0}]})}function updateCdpAppProfileDeviceEmulation(session,emulation){let state=appProfileStates.get(session);if(state)return state.ownsDeviceEmulation=!1,state.emulation=emulation??void 0,state.independentDeviceEmulation=emulation??void 0,{userAgent:state.config.userAgent,platform:state.config.navigatorPlatform}}function isCdpAppProfileActive(session){return appProfileStates.has(session)}function hasLoadedRootWebView(frameTree){if(!frameTree)return!1;let frame=frameTree.frame;return frame?.name==="__mearl_root__"&&typeof frame.url=="string"&&/^https?:/i.test(frame.url)?!0:Array.isArray(frameTree.childFrames)?frameTree.childFrames.some(child=>hasLoadedRootWebView(child)):!1}async function waitForCdpAppProfileLoad(session,timeoutMs=15e3){let deadline=Date.now()+timeoutMs;for(;Date.now()<deadline;){let result=await session.client.sendCommand("Page.getFrameTree").catch(()=>null);if(hasLoadedRootWebView(result?.frameTree))return;await new Promise(resolve3=>setTimeout(resolve3,50))}throw new Error(`App profile root WebView load timeout after ${timeoutMs}ms`)}async function clearCdpAppProfile(session,reload=!0){let state=appProfileStates.get(session);if(!state)return{enabled:!1,reloaded:!1};await disposeState(session,state,!0);let reloaded=!1;return reload&&(clearPageRefsForNavigation(session),await session.client.sendCommand("Page.reload",{}),await waitForPageLoad(session,3e4),reloaded=!0),{enabled:!1,reloaded}}async function cdpSetAppProfile(session,data){if(typeof data?.enabled!="boolean")throw new Error('set_app_profile: "enabled" is required (true to enable, false to clear)');if(!data.enabled)return clearCdpAppProfile(session,data.reload!==!1);if(!data.profile||typeof data.profile!="string")throw new Error('set_app_profile: "profile" is required when enabled=true');let resolved=resolveCdpAppProfile(data.profile,data);await applyResolvedCdpAppProfile(session,resolved);let reloaded=!1;return data.reload!==!1&&(clearPageRefsForNavigation(session),await session.client.sendCommand("Page.reload",{}),await waitForCdpAppProfileLoad(session),reloaded=!0),{enabled:!0,profile:resolved.profile.profile,label:resolved.profile.label,userAgent:resolved.profile.ua,preset:resolved.emulation.presetName,os:resolved.profile.injected.platform==="Android"?"android":"ios",simulateSystemBars:resolved.profile.injected.simulateSystemBars!==!1,reloaded}}registerActions([{name:"set_app_profile",session:"page",handler:cdpSetAppProfile}]);async function releaseCdpControl(session){let pageSessions=session.listOpenPageSessions(),targetIds=new Set(pageSessions.map(pageSession=>pageSession.targetId)),affectedTabIds=session.listRegisteredTabIds(targetIds).sort((a,b)=>a-b),hadActiveControl=session.hasActiveConnections();try{await releaseCdpRecordings(pageSessions)}finally{await Promise.allSettled(pageSessions.flatMap(pageSession=>[clearCdpAppProfile(pageSession,!1),releaseControlledIndicator(pageSession)])),clearCdpMockState(),session.close()}return{released:!0,hadActiveControl,affectedTabIds}}var SAMPLE_PAGE_READINESS_SRC=samplePageReadinessInPage.toString(),DISPOSE_PAGE_READINESS_SRC=disposePageReadinessObserverInPage.toString();async function startCdpNavigationObserver(cdpSession2,pageSession,urlBefore,options={}){await ensureCdpDomain(pageSession.client,"Page"),options.trackNetwork&&await ensureCdpDomain(pageSession.client,"Network");let browserClient=null,baselineTargetIds=new Set;if(options.trackOpenedTabs)try{browserClient=await cdpSession2.getBrowserClient();let targets=await browserClient.sendCommand("Target.getTargets");for(let target of targets.targetInfos??[])baselineTargetIds.add(target.targetId)}catch{browserClient=null}let mainFrameId=(await pageSession.client.sendCommand("Page.getFrameTree")).frameTree?.frame?.id,tracker=createNavigationSettlementTracker({urlBefore,trackNetwork:options.trackNetwork,networkAvailable:options.trackNetwork===!0,networkIdleMs:options.networkIdleMs,contentReadyAfterMs:options.contentReadyAfterMs,sampleContent:async()=>(await pageSession.client.sendCommand("Runtime.evaluate",{expression:`(${SAMPLE_PAGE_READINESS_SRC})(${options.networkIdleMs??500})`,returnByValue:!0})).result?.value}),removeFrameNavigated=pageSession.client.on("Page.frameNavigated",params=>{params.frame?.parentId||mainFrameId&¶ms.frame?.id!==mainFrameId||tracker.markStarted(params.frame?.url)}),removeWithinDocument=pageSession.client.on("Page.navigatedWithinDocument",params=>{mainFrameId&¶ms.frameId!==mainFrameId||(tracker.markStarted(params.url),tracker.markDocumentComplete(params.url))}),removeLoad=pageSession.client.on("Page.loadEventFired",()=>{tracker.hasStarted()&&tracker.markDocumentComplete()}),removeRequestStarted=options.trackNetwork?pageSession.client.on("Network.requestWillBeSent",params=>{isPotentialNavigationRequest(params.type??"",params.request?.url??"")&&tracker.requestStarted(params.requestId)}):()=>{},onRequestFinished=params=>tracker.requestFinished(params.requestId),removeRequestFinished=options.trackNetwork?pageSession.client.on("Network.loadingFinished",onRequestFinished):()=>{},removeRequestFailed=options.trackNetwork?pageSession.client.on("Network.loadingFailed",onRequestFinished):()=>{};return{hasStarted:tracker.hasStarted,hasNetworkActivity:tracker.hasNetworkActivity,waitForStart:tracker.waitForStart,waitForNetworkIdle:tracker.waitForNetworkIdle,waitForResult:async timeoutMs=>{let result=await tracker.waitForResult(timeoutMs);try{let pageState=await pageSession.client.sendCommand("Runtime.evaluate",{expression:"({ title: document.title, url: location.href })",returnByValue:!0});return{...result,title:pageState.result?.value?.title??result.title,urlAfter:pageState.result?.value?.url??result.urlAfter}}catch{return result}},getOpenedTabs:async timeoutMs=>{if(!browserClient||options.sourceTabId===void 0)return[];let candidates=((await browserClient.sendCommand("Target.getTargets")).targetInfos??[]).filter(target=>target.type==="page"&&target.openerId===pageSession.targetId&&!baselineTargetIds.has(target.targetId));return(await Promise.all(candidates.map(async candidate=>{let tabId=await cdpSession2.ensureTargetRegistered(candidate.targetId),ready=!1;try{let openedPageSession=await cdpSession2.getPageSession(tabId);await ensureCdpDomain(openedPageSession.client,"Page"),await waitForPageLoad(openedPageSession,timeoutMs),ready=!0}catch{}let targetInfo=await browserClient.sendCommand("Target.getTargetInfo",{targetId:candidate.targetId}).then(result=>result.targetInfo).catch(()=>null);return targetInfo?{tabId,openerTabId:options.sourceTabId,url:targetInfo.url??candidate.url??"",title:targetInfo.title??candidate.title??"",ready,settledBy:ready?"load":"timeout"}:null}))).filter(tab=>tab!==null)},dispose:async()=>{removeFrameNavigated(),removeWithinDocument(),removeLoad(),removeRequestStarted(),removeRequestFinished(),removeRequestFailed(),tracker.dispose(),await pageSession.client.sendCommand("Runtime.evaluate",{expression:`(${DISPOSE_PAGE_READINESS_SRC})()`,returnByValue:!1}).catch(()=>{})}}}var INSTALL_PAGE_OBSERVER_SRC=installPageObserverInPage.toString(),DISPOSE_PAGE_OBSERVER_SRC=disposePageObserverInPage.toString(),PAGE_OBSERVER_GLOBAL="__MEARL_PAGE_OBSERVER__";function evaluationError(result){return result.exceptionDetails?result.exceptionDetails.exception?.description??result.exceptionDetails.text??"Page observation evaluation failed":null}async function startPageObservation(session){let result=await session.client.sendCommand("Runtime.evaluate",{expression:`(${INSTALL_PAGE_OBSERVER_SRC})()`,returnByValue:!0}),error48=evaluationError(result);if(error48)throw new Error(error48);let checkpoint=result.result?.value;if(!checkpoint||typeof checkpoint.version!="number")throw new Error("Page observer did not return a checkpoint");return checkpoint}async function finishPageObservation(session,checkpoint,options={}){let{quietMs,firstChangeTimeoutMs,timeoutMs}=resolvePageObservationWaitOptions(options),expression=`(() => {
|
|
770
|
-
const state = globalThis[${JSON.stringify(PAGE_OBSERVER_GLOBAL)}];
|
|
771
|
-
if (!state || typeof state.waitSince !== 'function') {
|
|
772
|
-
throw new Error('Page observer is unavailable after the action');
|
|
773
|
-
}
|
|
774
|
-
return state.waitSince(
|
|
775
|
-
${checkpoint.version},
|
|
776
|
-
${JSON.stringify(checkpoint.focus)},
|
|
777
|
-
${quietMs},
|
|
778
|
-
${firstChangeTimeoutMs},
|
|
779
|
-
${timeoutMs}
|
|
780
|
-
);
|
|
781
|
-
})()`,result=await session.client.sendCommand("Runtime.evaluate",{expression,returnByValue:!0,awaitPromise:!0},timeoutMs+2e3),error48=evaluationError(result);if(error48)throw new Error(error48);let changeSet=result.result?.value;if(!changeSet||changeSet.mode!=="delta")throw new Error("Page observer did not return a change set");return changeSet}async function disposePageObservation(session){await session.client.sendCommand("Runtime.evaluate",{expression:`(${DISPOSE_PAGE_OBSERVER_SRC})()`,returnByValue:!1}).catch(()=>{})}function filterRequests(buffers,opts){let pattern=opts.filter?compileTextPattern(opts.filter):void 0;return queryCapturedEntries(buffers.requests.filter(request=>Number.isSafeInteger(request.captureSequence)),buffers.capture,{after:opts.after,since:opts.since,limit:opts.count??10},request=>(!opts.source||opts.source==="all"||request.source===opts.source)&&(!pattern||matchesTextPattern(request.url,pattern)||matchesTextPattern(request.apiName,pattern)),buffers.capture.droppedRequestsThroughSequence,"requests")}async function cdpGetRequests(session,data){let opts={count:data.count??10,filter:data.filter,since:data.since,after:data.after,source:data.source,applyHiddenFilter:data.applyHiddenFilter!==!1},captured=filterRequests(session.buffers,opts),serializeOpts={includeBody:data.includeBody!==!1,includeHeaders:data.includeHeaders===!0,maxBodySize:data.maxBodySize??5e4,fields:data.fields,keysOnly:data.keysOnly===!0};return{meta:{count:captured.entries.length,totalMatched:captured.totalMatched,totalInBuffer:session.buffers.requests.length,filter:data.filter,since:data.since,after:data.after,nextCursor:captured.nextCursor,hasMore:captured.hasMore,gap:captured.gap,source:"cdp"},requests:captured.entries.map(r=>serializeRequest(r,serializeOpts))}}async function cdpGetLogs(session,data){let{level,since,after,limit=100,filter}=data,pattern=filter?compileTextPattern(filter):void 0,captured=queryCapturedEntries(session.buffers.logs,session.buffers.capture,{after,since,limit},log3=>(!level||level==="all"||log3.level===level)&&(!pattern||matchesTextPattern(log3.message,pattern)||log3.args.some(arg=>matchesTextPattern(arg,pattern))),session.buffers.capture.droppedLogsThroughSequence,"logs"),captureStatus=session.buffers.logs.length===0?"armed":"active";return{meta:{count:captured.entries.length,totalMatched:captured.totalMatched,totalInBuffer:session.buffers.logs.length,level:level||"all",since,after,filter,nextCursor:captured.nextCursor,hasMore:captured.hasMore,gap:captured.gap,captureStatus,...captureStatus==="armed"&&{hint:"Log capture is active, but this tab has no captured history yet. Reload the current tab or repeat the triggering action, then call get_logs again."},source:"cdp"},logs:captured.entries}}async function cdpCaptureCheckpoint(session,_data){return{tabId:session.tabId,cursor:captureCheckpoint(session.buffers.capture),timestampMs:Date.now(),captureStatus:session.buffers.capture.currentSequence===0?"armed":"active"}}async function collectCdpPageDiagnostics(session,after,diagnostics){let result={};if(diagnostics.logs){let options=diagnostics.logs===!0?{level:"error",limit:100}:{level:"error",limit:100,...diagnostics.logs};result.logs=await cdpGetLogs(session,{...options,after})}if(diagnostics.requests){let options=diagnostics.requests===!0?{source:"all",includeBody:!1,count:100}:{source:"all",includeBody:!1,count:100,...diagnostics.requests};result.requests=await cdpGetRequests(session,{...options,after})}if(diagnostics.events){let options=diagnostics.events===!0?{source:"all",limit:100}:{source:"all",limit:100,...diagnostics.events};result.events=await cdpGetEvents(session,{...options,after})}return result}async function cdpGetEvents(session,data){let{source="all",event_type,since,after,limit=20,filter,includeRaw=!1}=data,response=queryCapturedTrackingEvents(session.buffers.events,session.buffers.capture,{source,event_type,since,after,limit,filter},session.buffers.capture.droppedEventsThroughSequence),captureStatus=response.totalInBuffer===0?"armed":"active",hint=response.events.length===0&&captureStatus==="armed"?TRACKING_CAPTURE_ARMED_HINT:void 0;return{meta:{count:response.events.length,totalMatched:response.totalMatched,totalInBuffer:response.totalInBuffer,source,captureStatus,captureSource:"cdp",includeRaw,after,nextCursor:response.nextCursor,hasMore:response.hasMore,gap:response.gap,hint},events:response.events.map(event=>formatTrackingEvent(event,includeRaw))}}registerActions([{name:"tab_checkpoint",session:"page",handler:cdpCaptureCheckpoint},{name:"capture_checkpoint",session:"page",handler:cdpCaptureCheckpoint},{name:"get_requests",session:"page",handler:cdpGetRequests},{name:"get_logs",session:"page",handler:cdpGetLogs},{name:"get_events",session:"page",handler:cdpGetEvents}]);async function cdpRunActions(session,data,controlSource="local"){let{actions,tabId}=data;if(!Array.isArray(actions)||actions.length===0)throw new Error("actions must be a non-empty array");if(actions.length>50)throw new Error("actions array exceeds maximum of 50 steps");let results=[];for(let i=0;i<actions.length;i++){let step=actions[i],stepAction=String(step.action??"");if(!stepAction)return{results,completedSteps:results.length,totalSteps:actions.length,error:`Step ${i}: action must be a non-empty string`,failedStep:i};if(!isBrowserCommandAction(stepAction))return{results,completedSteps:results.length,totalSteps:actions.length,error:`Step ${i}: unsupported action "${stepAction}"`,failedStep:i};if(stepAction==="run_actions")return{results,completedSteps:results.length,totalSteps:actions.length,error:`Step ${i}: composite action "${stepAction}" is not allowed in run_actions`,failedStep:i};if(stepAction==="browser_release")return{results,completedSteps:results.length,totalSteps:actions.length,error:`Step ${i}: browser-level action "${stepAction}" is not allowed in run_actions`,failedStep:i};let mergedData={...step.data};tabId!==void 0&&mergedData.tabId===void 0&&(mergedData.tabId=tabId);try{let result=await dispatchCdpAction(session,stepAction,mergedData,controlSource);results.push({step:i,action:stepAction,success:!0,data:result})}catch(error48){let errorMessage2=error48 instanceof Error?error48.message:String(error48);return results.push({step:i,action:stepAction,success:!1,error:errorMessage2}),{results,completedSteps:i,totalSteps:actions.length,error:errorMessage2,failedStep:i}}}return{results,completedSteps:actions.length,totalSteps:actions.length}}async function cdpObservedPageAction(session,action,data,controlSource="local"){let{actionData,observe,diagnostics}=splitObservedActionPayload(action,data),{tabId}=actionData;if(typeof tabId!="number")throw new Error(`${action} requires a numeric tabId`);let pageSession=await session.getPageSession(tabId);if(await ensureControlledIndicator(pageSession,controlSource),observe===!1){if(!diagnostics)return dispatchCdpAction(session,action,actionData,controlSource);let cursor=captureCheckpoint(pageSession.buffers.capture),actionResult,actionFailure;try{actionResult=await dispatchCdpAction(session,action,actionData,controlSource)}catch(error48){actionFailure=describePageActionFailure(error48)}let result2={action:{name:action,success:actionFailure===void 0,...actionResult!==void 0?{data:actionResult}:{},...actionFailure||{}}};return actionFailure?.stage==="precondition"?result2:{...result2,diagnostics:await collectCdpPageDiagnostics(pageSession,cursor,diagnostics)}}let diagnosticsCursor,result=await runPageAct({action,actionData,observe},{startObservation:()=>startPageObservation(pageSession),finishObservation:(checkpoint,options)=>finishPageObservation(pageSession,checkpoint,options),startNavigationObserver:options=>startCdpNavigationObserver(session,pageSession,options.urlBefore,options),executeAction:(name,params)=>(diagnostics&&(diagnosticsCursor=captureCheckpoint(pageSession.buffers.capture)),dispatchCdpAction(session,name,{...params,tabId},controlSource)),finalizeObservation:observation=>observation.mode==="delta"?enrichCdpPageChangeSetWithRefs(pageSession,observation):Promise.resolve(observation),disposeObservation:()=>disposePageObservation(pageSession)});return!diagnostics||!diagnosticsCursor||result.action.stage==="precondition"?result:{...result,diagnostics:await collectCdpPageDiagnostics(pageSession,diagnosticsCursor,diagnostics)}}registerActions([{name:"run_actions",session:"browser",handler:cdpRunActions}]);import{randomUUID as randomUUID2}from"node:crypto";import{createReadStream}from"node:fs";var FILE_CHUNK_BYTES=256*1024,TRANSFER_ACTION_TIMEOUT_MS=15e3;async function sendFileChunks(transferId,fileIndex,file2,send){let chunkIndex=0,sendChunk=async chunk=>{await send("__send_request_file_chunk",{transferId,fileIndex,chunkIndex,base64:chunk.toString("base64")},TRANSFER_ACTION_TIMEOUT_MS),chunkIndex+=1};if(file2.filePath){for await(let chunk of createReadStream(file2.filePath,{highWaterMark:FILE_CHUNK_BYTES}))await sendChunk(Buffer.isBuffer(chunk)?chunk:Buffer.from(chunk));return}let content=file2.content;for(let offset=0;offset<content.byteLength;offset+=FILE_CHUNK_BYTES)await sendChunk(content.subarray(offset,offset+FILE_CHUNK_BYTES))}async function prepareFileTransfer(data,send){let files=await resolveSendRequestFiles(data.files??[]);if(files.length===0)throw new Error("files must contain at least one file");let transferId=randomUUID2();await send("__send_request_file_start",{transferId,files:files.map(file2=>file2.descriptor),url:data.url,withCookies:data.withCookies},TRANSFER_ACTION_TIMEOUT_MS);try{for(let index=0;index<files.length;index+=1)await sendFileChunks(transferId,index,files[index],send)}catch(error48){throw await send("__send_request_file_abort",{transferId},TRANSFER_ACTION_TIMEOUT_MS).catch(()=>{}),error48}let{files:_files,...request}=data;return{transferId,request}}async function abortFileTransfer(transferId,send){await send("__send_request_file_abort",{transferId},TRANSFER_ACTION_TIMEOUT_MS).catch(()=>{})}function hasSendRequestFiles(data){return!!data&&typeof data=="object"&&Array.isArray(data.files)&&data.files.length>0}function hasRunActionsSendRequestFiles(data){if(!data||typeof data!="object")return!1;let actions=data.actions;return Array.isArray(actions)&&actions.some(step=>step?.action==="send_request"&&hasSendRequestFiles(step.data))}async function sendRequestWithTransferredFiles(data,send){let prepared=await prepareFileTransfer(data,send);try{let requestTimeout=Number(data.timeout??3e4);return await send("__send_request_with_files",{...prepared.request,transferId:prepared.transferId},(Number.isFinite(requestTimeout)&&requestTimeout>0?requestTimeout:3e4)+5e3)}catch(error48){throw await abortFileTransfer(prepared.transferId,send),error48}}async function sendRunActionsWithTransferredFiles(data,send,resolveTimeoutMs){if(!Array.isArray(data.actions))throw new Error("actions must be an array");let preparedTransferIds=[];try{let actions=[];for(let index=0;index<data.actions.length;index+=1){let step=data.actions[index],action=String(step.action??"");if(action.startsWith("__"))throw new Error(`Step ${index}: internal action "${action}" is not available to clients`);if(action!=="send_request"||!hasSendRequestFiles(step.data)){actions.push(step);continue}let prepared=await prepareFileTransfer(step.data,send);preparedTransferIds.push(prepared.transferId),actions.push({action:"__send_request_with_files",data:{...prepared.request,transferId:prepared.transferId}})}let transformed={...data,actions};return await send("run_actions",transformed,resolveTimeoutMs(transformed))}finally{await Promise.all(preparedTransferIds.map(transferId=>abortFileTransfer(transferId,send)))}}import fs2 from"node:fs";import path2 from"node:path";import{spawn as spawn2,spawnSync}from"node:child_process";function isAlive(pid){if(!pid||pid<=0)return!1;try{return process.kill(pid,0),!0}catch(error48){return error48.code==="EPERM"}}import{join}from"node:path";import{homedir}from"node:os";import{createHash}from"node:crypto";var DAEMON_HOME=join(homedir(),".mearl");function hashKey(key){return createHash("sha256").update(key).digest("hex").slice(0,16)}function keyedDir(subdir){return join(DAEMON_HOME,subdir)}function keyedConfigFile(subdir,key){return join(keyedDir(subdir),`${hashKey(key)}.json`)}import{closeSync,existsSync,linkSync,openSync,statSync,mkdirSync,readFileSync,writeFileSync,renameSync,rmSync,readdirSync}from"node:fs";import{dirname,join as join2}from"node:path";import{randomUUID as randomUUID3}from"node:crypto";var LOCK_WAIT_MS=10,LOCK_TIMEOUT_MS=5e3,OWNER_WRITE_GRACE_MS=1e3,lockWaitBuffer=new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));function ensureDir(dir){existsSync(dir)||mkdirSync(dir,{recursive:!0,mode:448})}function pauseForLock(){Atomics.wait(lockWaitBuffer,0,0,LOCK_WAIT_MS)}function readRecordUnlocked(file2){try{if(!existsSync(file2))return null;let parsed=JSON.parse(readFileSync(file2,"utf-8"));return parsed&&typeof parsed.pid=="number"?parsed:null}catch{return null}}function removeRecordUnlocked(file2){rmSync(file2,{force:!0})}function writeRecordUnlocked(file2,record2){let tmp=`${file2}.${process.pid}.${randomUUID3()}.tmp`;try{writeFileSync(tmp,JSON.stringify(record2),{mode:384}),renameSync(tmp,file2)}catch(error48){try{rmSync(tmp,{force:!0})}catch{}throw error48}}function removeStaleLock(lockDir){let ownerFile=join2(lockDir,"owner.json"),owner=readRecordUnlocked(ownerFile);if(owner){if(isAlive(owner.pid))return!1}else try{if(Date.now()-statSync(lockDir).mtimeMs<OWNER_WRITE_GRACE_MS)return!1}catch{return!0}try{return rmSync(lockDir,{recursive:!0,force:!0}),!0}catch{return!1}}function withRecordLock(file2,operation){ensureDir(dirname(file2));let lockDir=`${file2}.registry.lock`,ownerFile=join2(lockDir,"owner.json"),token=randomUUID3(),deadline=Date.now()+LOCK_TIMEOUT_MS;for(;;){try{mkdirSync(lockDir,{mode:448})}catch(error48){if(error48.code!=="EEXIST")throw error48;if(!removeStaleLock(lockDir)){if(Date.now()>=deadline)throw new Error(`Timed out waiting for registry lock: ${file2}`,{cause:error48});pauseForLock()}continue}let ownerFd=null;try{ownerFd=openSync(ownerFile,"wx",384),writeFileSync(ownerFd,JSON.stringify({pid:process.pid,token}))}catch(error48){if(ownerFd!==null&&closeSync(ownerFd),ownerFd=null,error48.code==="EEXIST"){if(Date.now()>=deadline)throw new Error(`Timed out acquiring registry lock: ${file2}`,{cause:error48});pauseForLock();continue}throw error48}finally{ownerFd!==null&&closeSync(ownerFd)}try{return operation()}finally{readRecordUnlocked(ownerFile)?.token===token&&rmSync(lockDir,{recursive:!0,force:!0})}}}function writeRecord(file2,record2){withRecordLock(file2,()=>writeRecordUnlocked(file2,record2))}function readRecord(file2){return readRecordUnlocked(file2)}function removeRecord(file2){try{withRecordLock(file2,()=>removeRecordUnlocked(file2))}catch{}}function removeRecordIfPid(file2,pid){try{return withRecordLock(file2,()=>readRecordUnlocked(file2)?.pid!==pid?!1:(removeRecordUnlocked(file2),!0))}catch{return!1}}function removeInvalidRecord(file2){try{return withRecordLock(file2,()=>!existsSync(file2)||readRecordUnlocked(file2)?!1:(removeRecordUnlocked(file2),!0))}catch{return!1}}function listRecordFiles(dir){try{return readdirSync(dir).filter(name=>name.endsWith(".json")).map(name=>join2(dir,name))}catch{return[]}}function readLiveRecords(dir){let out=[];for(let file2 of listRecordFiles(dir)){let rec=readRecord(file2);rec&&isAlive(rec.pid)?out.push(rec):rec?removeRecordIfPid(file2,rec.pid):removeInvalidRecord(file2)}return out}import{existsSync as existsSync2,statSync as statSync2,renameSync as renameSync2,readFileSync as readFileSync2}from"node:fs";var DEFAULT_MAX_LOG_BYTES=5*1024*1024;import{spawn}from"node:child_process";import{closeSync as closeSync2,openSync as openSync2}from"node:fs";import{dirname as dirname2}from"node:path";var processes=new Map,CONNECTORS_SUBDIR="connectors",REGISTRY_DIR=keyedDir(CONNECTORS_SUBDIR),OFFICIAL_NPM_REGISTRY="https://registry.npmjs.org",STATUS_POLL_MS=5e3;function recordFileFor(serverUrl){return keyedConfigFile(CONNECTORS_SUBDIR,serverUrl)}var logFn=()=>{},isDaemon=!1,sendToExtensionFn=()=>{},nativeHostVersion="unknown",lastPushedKey="",statusWatcher=null;function initCloudConnector(deps){logFn=deps.log,isDaemon=deps.isDaemonMode,sendToExtensionFn=deps.sendToExtension,nativeHostVersion=deps.version,startStatusWatcher()}function liveRecords(){return readLiveRecords(REGISTRY_DIR)}function reconcile(){let live=new Map;for(let record2 of liveRecords())live.set(record2.serverUrl,{serverUrl:record2.serverUrl,pid:record2.pid,...record2.connectorId?{connectorId:record2.connectorId}:{},...record2.name?{name:record2.name}:{}});for(let[serverUrl,entry]of processes)isAlive(entry.pid)?live.has(serverUrl)||live.set(serverUrl,{serverUrl,pid:entry.pid,...entry.connectorId?{connectorId:entry.connectorId}:{},...entry.name?{name:entry.name}:{}}):processes.delete(serverUrl);return Array.from(live.values())}function connectorsKey(connectors){return connectors.map(c=>`${c.serverUrl}@${c.pid}@${c.connectorId??""}@${c.name??""}`).sort().join("|")}function pushStatus(connectors){isDaemon||(lastPushedKey=connectorsKey(connectors),sendToExtensionFn({type:"cloud_connector_status_changed",data:{connectors}}))}function notifyStatusChanged(){pushStatus(reconcile())}function pushIfChanged(){let connectors=reconcile();return connectorsKey(connectors)!==lastPushedKey&&pushStatus(connectors),connectors}function startStatusWatcher(){isDaemon||statusWatcher||(statusWatcher=setInterval(()=>{try{pushIfChanged()}catch{}},STATUS_POLL_MS),statusWatcher.unref?.())}function registerConnector(serverUrl,pid,child){let record2=readRecord(recordFileFor(serverUrl)),entry={pid,serverUrl,...record2?.connectorId?{connectorId:record2.connectorId}:{},...record2?.name?{name:record2.name}:{},...child?{process:child}:{}};return processes.set(serverUrl,entry),notifyStatusChanged(),entry}function clearConnector(serverUrl,expected){let entry=processes.get(serverUrl);entry&&entry.pid!==expected.pid||expected.child&&entry?.process&&entry.process!==expected.child||(processes.delete(serverUrl),removeRecordIfPid(recordFileFor(serverUrl),expected.pid),notifyStatusChanged())}function findLiveConnector(serverUrl){let entry=processes.get(serverUrl);if(entry&&isAlive(entry.pid))return entry.pid;let record2=readRecord(recordFileFor(serverUrl));return record2&&isAlive(record2.pid)?record2.pid:(entry&&processes.delete(serverUrl),record2&&removeRecordIfPid(recordFileFor(serverUrl),record2.pid),null)}function findBin(bin,env){let lookupCommand=process.platform==="win32"?"where":"which",result=spawnSync(lookupCommand,[bin],{encoding:"utf-8",env});return result.status===0&&result.stdout.split(/\r?\n/).find(Boolean)||null}function getBinVersion(binPath){try{let result=spawnSync(process.execPath,[binPath,"--version"],{encoding:"utf-8",timeout:5e3});return result.status===0?result.stdout.trim():null}catch{return null}}function makeDirectCommand(connectorPath){return process.platform!=="win32"?{command:process.execPath,argsPrefix:[connectorPath],displayName:`${process.execPath} ${connectorPath}`}:{command:connectorPath,argsPrefix:[],displayName:connectorPath}}function resolveCloudConnectorCommand(){let connectorBin=process.platform==="win32"?"mearl-cloud-connector.cmd":"mearl-cloud-connector",pathDelimiter=process.platform==="win32"?";":":",nodeDir=path2.dirname(process.execPath),enrichedPath=[nodeDir,process.env.PATH].filter(Boolean).join(pathDelimiter),enrichedEnv={...process.env,PATH:enrichedPath},connectorPath=findBin(connectorBin,enrichedEnv);if(connectorPath){let installedVersion=getBinVersion(connectorPath);if(installedVersion===nativeHostVersion)return logFn(`Cloud connector ${installedVersion} found at ${connectorPath}`),makeDirectCommand(connectorPath);logFn(`Cloud connector version mismatch: installed=${installedVersion}, expected=${nativeHostVersion}`)}let npmBin=process.platform==="win32"?"npm.cmd":"npm",npmPath=path2.join(nodeDir,npmBin),npmCommand=fs2.existsSync(npmPath)?npmPath:npmBin,targetPackage=`@mearl/cloud-connector@${nativeHostVersion}`;logFn(`Installing ${targetPackage} globally via ${npmCommand}...`);let install=spawnSync(npmCommand,["install","-g",targetPackage,"--prefer-offline",`--registry=${OFFICIAL_NPM_REGISTRY}`],{encoding:"utf-8",env:enrichedEnv,timeout:3e4});if(install.status===0){let newPath=findBin(connectorBin,enrichedEnv);if(newPath)return logFn(`Global install succeeded: ${newPath}`),makeDirectCommand(newPath)}logFn(`Global install failed (status=${install.status}), falling back to npx`),install.stderr&&logFn(install.stderr.trim());let npxBin=process.platform==="win32"?"npx.cmd":"npx",npxPath=path2.join(nodeDir,npxBin),npxCommand=fs2.existsSync(npxPath)?npxPath:npxBin;return{command:npxCommand,argsPrefix:[`@mearl/cloud-connector@${nativeHostVersion}`],displayName:`${npxCommand} @mearl/cloud-connector@${nativeHostVersion}`,env:enrichedEnv}}function startCloudConnector(serverUrl){return new Promise(resolve3=>{let existingPid=findLiveConnector(serverUrl);if(existingPid){logFn(`Reusing existing cloud connector for ${serverUrl} (pid=${existingPid})`);let entry=registerConnector(serverUrl,existingPid);resolve3({success:!0,pid:existingPid,...entry.connectorId?{connectorId:entry.connectorId}:{},...entry.name?{name:entry.name}:{},reused:!0});return}let connectorCommand=resolveCloudConnectorCommand();logFn(`Starting cloud connector via ${connectorCommand.displayName}`);let child=spawn2(connectorCommand.command,[...connectorCommand.argsPrefix,serverUrl,"--fail-fast"],{detached:!0,env:connectorCommand.env,stdio:["ignore","pipe","pipe"],windowsHide:!0}),settled=!1,outputBuffer="",startupTimer=setTimeout(()=>{finish(!1,{error:"Cloud connector startup timeout"}),child.kill()},6e4),finish=(ok,result={})=>{if(!settled)if(settled=!0,clearTimeout(startupTimer),ok&&child.pid){let entry=registerConnector(serverUrl,child.pid,child);resolve3({success:!0,pid:child.pid,...entry.connectorId?{connectorId:entry.connectorId}:{},...entry.name?{name:entry.name}:{}})}else resolve3({success:!1,error:result.error||"Failed to spawn cloud connector"})};child.once("error",error48=>{logFn(`Failed to spawn cloud connector: ${error48.message}`),finish(!1,{error:error48.message})});let handleOutput=chunk=>{let text=chunk.toString();outputBuffer=(outputBuffer+text).slice(-2e3),logFn(`[CloudConnector] ${text.trim()}`),text.includes("[CloudConnector] Connected to")&&finish(!0)};child.stdout?.on("data",handleOutput),child.stderr?.on("data",handleOutput),child.once("spawn",()=>{child.once("exit",(code,signal)=>{child.pid&&clearConnector(serverUrl,{pid:child.pid,child}),logFn(`Cloud connector exited for ${serverUrl}: code=${code??"null"} signal=${signal??"null"}`),settled||finish(!1,{error:outputBuffer.trim()||`Cloud connector exited before connected: code=${code??"null"} signal=${signal??"null"}`})}),child.unref()})})}function stopCloudConnector(serverUrl){let pid=processes.get(serverUrl)?.pid??readRecord(recordFileFor(serverUrl))?.pid;if(!pid)return{success:!1,error:"Cloud connector not found"};try{return isAlive(pid)&&process.kill(pid),clearConnector(serverUrl,{pid}),logFn(`Stopped cloud connector for ${serverUrl} (pid=${pid})`),{success:!0}}catch(error48){let err=error48;return err.code==="ESRCH"?(clearConnector(serverUrl,{pid}),{success:!0}):(logFn(`Failed to stop cloud connector: ${err.message}`),{success:!1,error:err.message})}}function listCloudConnectors(){return{connectors:pushIfChanged()}}var SCREENSHOT_HIDDEN_DISPLAY_PROPERTIES=["--mearl-side-panel-toggle-display","--mearl-device-cutout-display"],screenshotQueueTails=new WeakMap;async function runScreenshotExclusive(session,operation){let previous=screenshotQueueTails.get(session)??Promise.resolve(),unlock,tail=new Promise(resolve3=>{unlock=resolve3});screenshotQueueTails.set(session,tail),await previous;try{return await operation()}finally{unlock(),screenshotQueueTails.get(session)===tail&&screenshotQueueTails.delete(session)}}async function hideScreenshotArtifacts(session){return(await session.client.sendCommand("Runtime.evaluate",{expression:`
|
|
1053
|
+
})`,returnByValue:!0}),width=result.result?.value?.width,height=result.result?.value?.height;return typeof width!="number"||typeof height!="number"||width<=0||height<=0?null:{width,height}}async function getCdpInputViewportSize(session){let metrics;try{metrics=await session.client.sendCommand("Page.getLayoutMetrics",{})}catch{return null}let viewport=metrics.cssVisualViewport??metrics.visualViewport??metrics.cssLayoutViewport??metrics.layoutViewport,width=viewport?.clientWidth,height=viewport?.clientHeight;return typeof width!="number"||typeof height!="number"||width<=0||height<=0?null:{width,height}}async function toCdpInputPoint(session,x,y){if(isCdpDeviceShellActive(session)){let offset=getCdpDeviceShellInputOffset(session);return{x:x+offset.x,y:y+offset.y}}let[pageViewport,cdpViewport]=await Promise.all([getPageViewportSize(session),getCdpInputViewportSize(session)]);if(!pageViewport||!cdpViewport)return{x,y};let scaleX=cdpViewport.width/pageViewport.width,scaleY=cdpViewport.height/pageViewport.height;return!Number.isFinite(scaleX)||!Number.isFinite(scaleY)||scaleX<=0||scaleY<=0||Math.abs(scaleX-1)<.01&&Math.abs(scaleY-1)<.01?{x,y}:{x:x*scaleX,y:y*scaleY}}async function dispatchCdpClick(session,x,y,pointerType){let point=await toCdpInputPoint(session,x,y);if(pointerType==="touch"){await sendCdpInputCommand(session,"Input.dispatchTouchEvent",{type:"touchStart",touchPoints:[point]}),await sendCdpInputCommand(session,"Input.dispatchTouchEvent",{type:"touchEnd",touchPoints:[]});return}await sendCdpInputCommand(session,"Input.dispatchMouseEvent",{type:"mouseMoved",x:point.x,y:point.y}),await sendCdpInputCommand(session,"Input.dispatchMouseEvent",{type:"mousePressed",x:point.x,y:point.y,button:"left",buttons:1,clickCount:1}),await sendCdpInputCommand(session,"Input.dispatchMouseEvent",{type:"mouseReleased",x:point.x,y:point.y,button:"left",buttons:0,clickCount:1})}async function dispatchCdpDrag(session,from,to,pointerType,durationMs){let[start,end]=await Promise.all([toCdpInputPoint(session,from.x,from.y),toCdpInputPoint(session,to.x,to.y)]),path23=buildPageDragPath(start,end,durationMs),waitForNextPoint=async()=>{path23.intervalMs<=0||await new Promise(resolve3=>setTimeout(resolve3,path23.intervalMs))};if(pointerType==="touch"){await sendCdpInputCommand(session,"Input.dispatchTouchEvent",{type:"touchStart",touchPoints:[start]});let primaryError2;try{for(let point of path23.points)await waitForNextPoint(),await sendCdpInputCommand(session,"Input.dispatchTouchEvent",{type:"touchMove",touchPoints:[point]})}catch(error48){throw primaryError2=error48,error48}finally{await sendCdpInputCommand(session,"Input.dispatchTouchEvent",{type:"touchEnd",touchPoints:[]}).catch(error48=>{if(primaryError2===void 0)throw error48})}return{steps:path23.points.length}}await sendCdpInputCommand(session,"Input.dispatchMouseEvent",{type:"mouseMoved",x:start.x,y:start.y}),await sendCdpInputCommand(session,"Input.dispatchMouseEvent",{type:"mousePressed",x:start.x,y:start.y,button:"left",buttons:1,clickCount:1});let primaryError;try{for(let point of path23.points)await waitForNextPoint(),await sendCdpInputCommand(session,"Input.dispatchMouseEvent",{type:"mouseMoved",x:point.x,y:point.y,button:"left",buttons:1})}catch(error48){throw primaryError=error48,error48}finally{await sendCdpInputCommand(session,"Input.dispatchMouseEvent",{type:"mouseReleased",x:end.x,y:end.y,button:"left",buttons:0,clickCount:1}).catch(error48=>{if(primaryError===void 0)throw error48})}return{steps:path23.points.length}}async function sendCdpInputCommand(session,method,params){try{await session.client.sendCommand(method,params,1e4)}catch(error48){if(error48 instanceof Error&&error48.message===`CDP command timeout: ${method}`){let eventType=typeof params.type=="string"?` (${params.type})`:"";throw new Error(`CDP ${method}${eventType} timed out after ${1e4}ms. The page may already have changed; verify its current state before retrying.`,{cause:error48})}throw error48}}async function resolveBackendNodeObjectId(session,backendNodeId){let objectId=(await sendCdpDeviceShellPageCommand(session,"DOM.resolveNode",{backendNodeId})).object?.objectId;if(!objectId)throw new Error(`Cannot resolve element for backendNodeId ${backendNodeId}`);return objectId}var SCREENSHOT_HIDDEN_DISPLAY_PROPERTIES=["--mearl-side-panel-toggle-display","--mearl-device-cutout-display"],screenshotQueueTails=new WeakMap;async function runScreenshotExclusive(session,operation){let previous=screenshotQueueTails.get(session)??Promise.resolve(),unlock,tail=new Promise(resolve3=>{unlock=resolve3});screenshotQueueTails.set(session,tail),await previous;try{return await operation()}finally{unlock(),screenshotQueueTails.get(session)===tail&&screenshotQueueTails.delete(session)}}async function hideScreenshotArtifacts(session){return(await session.client.sendCommand("Runtime.evaluate",{expression:`
|
|
782
1054
|
(() => {
|
|
783
1055
|
const root = document.documentElement;
|
|
784
1056
|
if (!root) return [];
|
|
@@ -804,7 +1076,7 @@ Content-Type: ${file2.contentType}\r
|
|
|
804
1076
|
else root.style.removeProperty(property);
|
|
805
1077
|
}
|
|
806
1078
|
})()
|
|
807
|
-
`})}async function withHiddenScreenshotArtifacts(session,capture){let states=await hideScreenshotArtifacts(session);try{return await capture()}finally{await restoreScreenshotArtifacts(session,states).catch(()=>{})}}async function capturePageScreenshot(session,data){let format=data.format==="jpeg"?"jpeg":"png",quality=typeof data.quality=="number"?Math.min(Math.max(data.quality,0),100):80,params={format};format==="jpeg"&&(params.quality=quality);let pageInfo=await session
|
|
1079
|
+
`})}async function withHiddenScreenshotArtifacts(session,capture){let states=await hideScreenshotArtifacts(session);try{return await capture()}finally{await restoreScreenshotArtifacts(session,states).catch(()=>{})}}async function capturePageScreenshot(session,data){let format=data.format==="jpeg"?"jpeg":"png",quality=typeof data.quality=="number"?Math.min(Math.max(data.quality,0),100):80,params={format};format==="jpeg"&&(params.quality=quality);let pageInfo=await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:"JSON.stringify({ url: location.href, title: document.title, w: window.innerWidth, h: window.innerHeight, dpr: window.devicePixelRatio || 1 })",returnByValue:!0}),info=JSON.parse(pageInfo.result?.value??"{}");if(data.selector){params.captureBeyondViewport=!0;let selector=data.selector,rect=(await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:`(function() {
|
|
808
1080
|
var el = document.querySelector(${JSON.stringify(selector)});
|
|
809
1081
|
if (!el) return { error: 'Element not found: ' + ${JSON.stringify(selector)} };
|
|
810
1082
|
el.scrollIntoView({ block: 'nearest', inline: 'nearest' });
|
|
@@ -816,7 +1088,7 @@ Content-Type: ${file2.contentType}\r
|
|
|
816
1088
|
height: r.height,
|
|
817
1089
|
devicePixelRatio: window.devicePixelRatio || 1
|
|
818
1090
|
};
|
|
819
|
-
})()`,returnByValue:!0})).result?.value;if(!rect||rect.error)throw new Error(rect?.error??`Element not found: ${selector}`);if(rect.width<=0||rect.height<=0)throw new Error(`Element matched by "${selector}" has no visible size`);params.clip={x:rect.x,y:rect.y,width:rect.width,height:rect.height,scale:rect.devicePixelRatio};let base64Data2=(await session.client.sendCommand("Page.captureScreenshot",params)).data,width2=Math.round(rect.width*rect.devicePixelRatio),height2=Math.round(rect.height*rect.devicePixelRatio);return{meta:{format,width:width2,height:height2,size:Math.ceil(base64Data2.length*3/4),url:info.url??"",title:info.title??""},data:base64Data2}}let base64Data=(await session.client.sendCommand("Page.captureScreenshot",params)).data,width=Math.round((info.w??1920)*(info.dpr??1)),height=Math.round((info.h??1080)*(info.dpr??1));return{meta:{format,width,height,size:Math.ceil(base64Data.length*3/4),url:info.url??"",title:info.title??""},data:base64Data}}async function cdpPageScreenshot(session,data){return runScreenshotExclusive(session,()=>withHiddenScreenshotArtifacts(session,()=>capturePageScreenshot(session,data)))}async function cdpPageSelectedElement(session,_data){return{element:(await session
|
|
1091
|
+
})()`,returnByValue:!0})).result?.value;if(!rect||rect.error)throw new Error(rect?.error??`Element not found: ${selector}`);if(rect.width<=0||rect.height<=0)throw new Error(`Element matched by "${selector}" has no visible size`);let offset=getCdpDeviceShellInputOffset(session);params.clip={x:rect.x+offset.x,y:rect.y+offset.y,width:rect.width,height:rect.height,scale:rect.devicePixelRatio};let base64Data2=(await session.client.sendCommand("Page.captureScreenshot",params)).data,width2=Math.round(rect.width*rect.devicePixelRatio),height2=Math.round(rect.height*rect.devicePixelRatio);return{meta:{format,width:width2,height:height2,size:Math.ceil(base64Data2.length*3/4),url:info.url??"",title:info.title??""},data:base64Data2}}let base64Data=(await session.client.sendCommand("Page.captureScreenshot",params)).data,width=Math.round((info.w??1920)*(info.dpr??1)),height=Math.round((info.h??1080)*(info.dpr??1));return{meta:{format,width,height,size:Math.ceil(base64Data.length*3/4),url:info.url??"",title:info.title??""},data:base64Data}}async function cdpPageScreenshot(session,data){return runScreenshotExclusive(session,()=>withHiddenScreenshotArtifacts(session,()=>capturePageScreenshot(session,data)))}async function cdpPageSelectedElement(session,_data){return{element:(await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:`(() => {
|
|
820
1092
|
const el = document.activeElement;
|
|
821
1093
|
if (!el || el === document.body) return null;
|
|
822
1094
|
const rect = el.getBoundingClientRect();
|
|
@@ -844,7 +1116,29 @@ Content-Type: ${file2.contentType}\r
|
|
|
844
1116
|
return null;
|
|
845
1117
|
}
|
|
846
1118
|
});
|
|
847
|
-
})()`,returnByValue:!0,awaitPromise:!0})).result?.value;if(!userInfo)throw new Error("Failed to parse user info from work.alibaba-inc.com");return{userId,detail:userInfo}}registerActions([{name:"page_screenshot",session:"page",handler:cdpPageScreenshot},{name:"page_selected_element",session:"page",handler:cdpPageSelectedElement},{name:"get_user_info",session:"page",handler:cdpGetUserInfo}]);
|
|
1119
|
+
})()`,returnByValue:!0,awaitPromise:!0})).result?.value;if(!userInfo)throw new Error("Failed to parse user info from work.alibaba-inc.com");return{userId,detail:userInfo}}registerActions([{name:"page_screenshot",session:"page",handler:cdpPageScreenshot},{name:"page_selected_element",session:"page",handler:cdpPageSelectedElement},{name:"get_user_info",session:"page",handler:cdpGetUserInfo}]);import{readFile}from"node:fs/promises";import{randomUUID}from"node:crypto";import{stat}from"node:fs/promises";import{basename,isAbsolute}from"node:path";async function resolveSendRequestFile(file2,index){if(!file2||typeof file2!="object")throw new Error(`files[${index}] must be an object`);let fieldName=assertSafeSendRequestMultipartValue(file2.fieldName,`files[${index}].fieldName`),hasPath=typeof file2.filePath=="string"&&file2.filePath.length>0,hasBase64=typeof file2.base64=="string";if(hasPath===hasBase64)throw new Error(`files[${index}] must provide exactly one of filePath or base64`);let filename,byteLength2,filePath,content;if(hasPath){if(filePath=file2.filePath,!isAbsolute(filePath))throw new Error(`files[${index}].filePath must be an absolute path`);let metadata;try{metadata=await stat(filePath)}catch(error48){throw new Error(`Unable to read files[${index}].filePath: ${error48 instanceof Error?error48.message:String(error48)}`,{cause:error48})}if(!metadata.isFile())throw new Error(`files[${index}].filePath is not a file`);filename=file2.filename||basename(filePath),byteLength2=metadata.size}else{if(filename=file2.filename||"",!filename)throw new Error(`files[${index}].filename is required when base64 is used`);let bytes=decodeSendRequestBase64Bytes(file2.base64,`files[${index}].base64`);content=Buffer.from(bytes),byteLength2=content.byteLength}let safeFilename=assertSafeSendRequestMultipartValue(filename,`files[${index}].filename`),contentType=typeof file2.contentType=="string"&&file2.contentType.trim()?assertSafeSendRequestMultipartValue(file2.contentType.trim(),`files[${index}].contentType`):inferSendRequestContentType(filename);return{descriptor:{fieldName,filename:safeFilename,contentType,byteLength:byteLength2},filePath,content}}async function resolveSendRequestFiles(files){assertSendRequestFileCount(files.length);let resolved=await Promise.all(files.map(resolveSendRequestFile));return assertSendRequestFileLimits(resolved.map(file2=>file2.descriptor.byteLength)),assertSendRequestBase64FileLimits(resolved.flatMap(file2=>file2.content?[file2.content.byteLength]:[])),resolved}var ALLOWED_METHODS=new Set(["GET","POST","PUT","DELETE","PATCH","HEAD","OPTIONS"]);function setHeader(headers,name,value){let existing=findSendRequestHeaderName(headers,name);existing&&existing!==name&&delete headers[existing],headers[name]=value}function removeHeader(headers,name){let existing=findSendRequestHeaderName(headers,name);existing&&delete headers[existing]}function escapeMultipartQuotedValue(value){return value.replace(/\\/g,"\\\\").replace(/"/g,"%22")}async function readMultipartFiles(files){let resolved=await resolveSendRequestFiles(files),contents=await Promise.all(resolved.map(async(file2,index)=>{if(file2.content)return file2.content;try{return await readFile(file2.filePath)}catch(error48){throw new Error(`Unable to read files[${index}].filePath: ${error48 instanceof Error?error48.message:String(error48)}`,{cause:error48})}}));return assertSendRequestFileLimits(contents.map(content=>content.byteLength)),resolved.map((file2,index)=>({fieldName:file2.descriptor.fieldName,filename:file2.descriptor.filename,contentType:file2.descriptor.contentType,content:contents[index]}))}async function buildMultipartBody(formData,files){if(formData!==void 0&&(formData===null||typeof formData!="object"||Array.isArray(formData)))throw new Error("formData must be an object");if(files!==void 0&&!Array.isArray(files))throw new Error("files must be an array");let resolvedFiles=await readMultipartFiles(files??[]),boundary=`----mearl-${randomUUID()}`,chunks=[];for(let[name,value]of Object.entries(formData??{})){if(!["string","number","boolean"].includes(typeof value))throw new Error(`formData.${name} must be a string, number, or boolean`);let safeName=escapeMultipartQuotedValue(assertSafeSendRequestMultipartValue(name,`formData field "${name}"`));chunks.push(Buffer.from(`--${boundary}\r
|
|
1120
|
+
Content-Disposition: form-data; name="${safeName}"\r
|
|
1121
|
+
\r
|
|
1122
|
+
${String(value)}\r
|
|
1123
|
+
`))}for(let file2 of resolvedFiles){let fieldName=escapeMultipartQuotedValue(file2.fieldName),filename=escapeMultipartQuotedValue(file2.filename);chunks.push(Buffer.from(`--${boundary}\r
|
|
1124
|
+
Content-Disposition: form-data; name="${fieldName}"; filename="${filename}"\r
|
|
1125
|
+
Content-Type: ${file2.contentType}\r
|
|
1126
|
+
\r
|
|
1127
|
+
`),file2.content,Buffer.from(`\r
|
|
1128
|
+
`))}return chunks.push(Buffer.from(`--${boundary}--\r
|
|
1129
|
+
`)),{contentType:`multipart/form-data; boundary=${boundary}`,body:Buffer.concat(chunks)}}function hasMultipartPayload(data){return data.formData!==void 0||data.files!==void 0}async function executeNodeSendRequest(data,cookieMap=new Map){let{url:url2,method="GET",headers={},params,body,formData,files,responseType="auto",timeout=3e4}=data;if(!url2||typeof url2!="string"||url2.trim()==="")throw new Error("Invalid url: url must be a non-empty string");let normalizedMethod=method.toUpperCase();if(!ALLOWED_METHODS.has(normalizedMethod))throw new Error(`Invalid method: ${method}. Allowed: ${[...ALLOWED_METHODS].join(", ")}`);if(!Number.isFinite(timeout)||timeout<=0)throw new Error("timeout must be a positive number");let targetUrl=new URL(url2);for(let[key,value]of Object.entries(params??{}))targetUrl.searchParams.set(key,String(value));let requestHeaders={Accept:"application/json, text/plain, */*","Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8","User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",...headers},resolvedSourceHeaders=getSendRequestSourceHeaders(targetUrl,headers);resolvedSourceHeaders.referer?setHeader(requestHeaders,"Referer",resolvedSourceHeaders.referer):removeHeader(requestHeaders,"Referer"),resolvedSourceHeaders.origin?setHeader(requestHeaders,"Origin",resolvedSourceHeaders.origin):removeHeader(requestHeaders,"Origin");let cookieHeader=[...cookieMap.entries()].map(([key,value])=>`${key}=${value}`).join("; ");cookieHeader&&setHeader(requestHeaders,"Cookie",cookieHeader);let xsrfToken=cookieMap.get("XSRF-TOKEN");xsrfToken&&!findSendRequestHeaderName(requestHeaders,"x-xsrf-token")&&setHeader(requestHeaders,"X-XSRF-TOKEN",xsrfToken);let requestBody;if(hasMultipartPayload(data)){if(body!=null)throw new Error("body cannot be combined with formData or files");if(normalizedMethod==="GET"||normalizedMethod==="HEAD")throw new Error(`${normalizedMethod} requests cannot use formData or files`);if(findSendRequestHeaderName(requestHeaders,"content-type"))throw new Error("Do not set Content-Type when using formData or files; Mearl sets the boundary");let multipart=await buildMultipartBody(formData,files);requestBody=multipart.body,setHeader(requestHeaders,"Content-Type",multipart.contentType),setHeader(requestHeaders,"Content-Length",String(multipart.body.byteLength))}else body!=null&&!["GET","HEAD"].includes(normalizedMethod)&&(typeof body=="string"?(requestBody=body,findSendRequestHeaderName(requestHeaders,"content-type")||setHeader(requestHeaders,"Content-Type","text/plain")):(requestBody=JSON.stringify(body),findSendRequestHeaderName(requestHeaders,"content-type")||setHeader(requestHeaders,"Content-Type","application/json")));let result=await nodeFetch(targetUrl.toString(),{method:normalizedMethod,headers:requestHeaders,body:requestBody,timeoutMs:timeout}),contentType=(result.headers["content-type"]??"").split(";")[0].trim().toLowerCase(),responseHeaders=Object.fromEntries(Object.entries(result.headers).filter(([name])=>name.toLowerCase()!=="set-cookie"&&name.toLowerCase()!=="set-cookie2")),responseBody,bodyType;if(responseType==="auto"&&isBinarySendRequestContentType(contentType))responseBody=result.bodyBuffer.toString("base64"),bodyType="base64";else{let trimmed=result.body.trimStart();if(responseType==="json"||responseType==="auto"&&contentType.includes("application/json")||responseType==="auto"&&(trimmed.startsWith("{")||trimmed.startsWith("[")))try{responseBody=JSON.parse(result.body),bodyType="json"}catch{if(responseType==="json")throw new Error("send_request expected a JSON response");responseBody=result.body,bodyType="text"}else responseBody=result.body,bodyType="text"}return{success:!0,status:result.status,statusText:result.statusText,headers:responseHeaders,body:responseBody,bodyType,attachedCookieCount:cookieMap.size}}async function cdpSendRequest(session,data){if(!data.url||typeof data.url!="string")throw new Error("Invalid url: url must be a non-empty string");let cookieMap=new Map;if(data.withCookies!==!1)try{cookieMap=await getCookiesForUrl(session,new URL(data.url).toString())}catch{}return executeNodeSendRequest(data,cookieMap)}async function prepareCdpMtopRequest(session,data,stream=!1){let resolved=resolveMtopRequest(data),cookieMap=await getCookiesForUrl(session,resolved.gatewayUrl.toString()),prepared=prepareSignedMtopRequest(resolved,cookieMap,stream);return{...prepared,requestHeaders:{...prepared.cookieHeader?{Cookie:prepared.cookieHeader}:{},...prepared.requestHeaders}}}async function cdpSendMtopRequest(session,data){let prepared=await prepareCdpMtopRequest(session,data),result=await nodeFetch(prepared.targetUrl.toString(),{method:prepared.normalizedMethod,headers:prepared.requestHeaders,body:prepared.body,timeoutMs:prepared.timeout});return{success:!0,response:parseMtopResponseText(result.body),requestData:prepared.requestData}}async function cdpSendMtopStreamRequest(session,data,callbacks){let prepared=await prepareCdpMtopRequest(session,data,!0),controller=new AbortController,timeoutId=setTimeout(()=>controller.abort(),prepared.timeout);try{await callbacks.onRequestPrepared?.({method:prepared.normalizedMethod,url:prepared.targetUrl.toString(),requestHeaders:Object.entries(prepared.requestHeaders).map(([name,value])=>({name,value}))});let response=await fetch(prepared.targetUrl,{method:prepared.normalizedMethod,headers:prepared.requestHeaders,body:prepared.body,signal:controller.signal}),responseHeaders=[];return response.headers.forEach((value,name)=>{name.toLowerCase()!=="set-cookie"&&responseHeaders.push({name,value})}),await callbacks.onResponse?.({status:response.status,statusText:response.statusText,responseHeaders}),{success:!0,response:await consumeMtopSseResponse(response,event=>callbacks.onReceive(event.data)),requestData:prepared.requestData}}catch(error48){throw error48 instanceof Error&&error48.name==="AbortError"?new Error(`send_mtop_stream timed out after ${prepared.timeout}ms: ${prepared.api}`,{cause:error48}):new Error(`send_mtop_stream failed: ${error48 instanceof Error?error48.message:String(error48)}`,{cause:error48})}finally{clearTimeout(timeoutId)}}async function cdpGetApiSchema(session,data){let{api,version:version2="1.0"}=data;if(!api||typeof api!="string")throw new Error("Invalid api: api must be a non-empty string");let targetUrl="https://ultramax.alibaba-inc.com/ultramax/api/query",payload=JSON.stringify({type:"RPC",rpcName:api,rpcVersion:version2}),cookieMap=await getCookiesForUrl(session,targetUrl),cookieHeader=buildCookieHeaderValue(cookieMap),result=await nodeFetch(targetUrl,{method:"POST",headers:{"Content-Type":"application/json",...cookieHeader?{Cookie:cookieHeader}:{}},body:payload,timeoutMs:15e3});if(result.status!==200)throw new Error(`Ultramax API returned status ${result.status}`);let responseBody;try{responseBody=JSON.parse(result.body)}catch{throw new Error(`Failed to parse Ultramax response: ${result.body.slice(0,200)}`)}return responseBody}registerActions([{name:"send_request",session:"page",handler:cdpSendRequest},{name:"send_mtop_request",session:"page",handler:cdpSendMtopRequest},{name:"get_api_schema",session:"page",handler:cdpGetApiSchema}]);var registries=new WeakMap;function getPageRefRegistry(session){let registry2=registries.get(session);if(!registry2){registry2=new BackendNodeRefRegistry,registries.set(session,registry2);let activeRegistry=registry2;session.client.on("Page.frameNavigated",params=>{params.frame?.parentId||activeRegistry.clearDocument()})}return registry2}function beginPageSnapshotRefs(session){return getPageRefRegistry(session).beginSnapshot()}function resolvePageRef(session,ref){return registries.get(session)?.resolve(ref)}function deletePageRef(session,ref){registries.get(session)?.delete(ref)}function clearPageRefsForNavigation(session){registries.get(session)?.clearDocument()}async function enrichCdpPageChangeSetWithRefs(session,observation){return enrichPageChangeSetWithRefs(observation,getPageRefRegistry(session),selectors=>resolveUniqueBackendNodeIds((method,params)=>sendCdpDeviceShellPageCommand(session,method,params),selectors),(node,backendNodeId)=>({backendNodeId,role:node.role??"",name:node.name??""}))}var APP_PROFILE_BINDING="__mearlCdpAppProfileRelay",appProfileStates=new WeakMap;function serializeForSource2(value){return JSON.stringify(value).replace(/[\u2028\u2029]/g,character=>character==="\u2028"?"\\u2028":"\\u2029")}function installCdpAppProfileRelay(bindingName){let browser=globalThis,target=globalThis;target.__mearlCdpAppProfileRelayInstalled__||(target.__mearlCdpAppProfileRelayInstalled__=!0,browser.addEventListener("message",event=>{if(event.source!==globalThis)return;let message=event.data;if(!message||message.source!=="mearl-app-bridge")return;let requestId=message.requestId;if(typeof requestId!="number")return;if(message.type==="prepareWebView"){browser.postMessage({source:"mearl-content",type:"APP_BRIDGE_PREPARE_WEBVIEW_RESPONSE",requestId,result:{success:!0}},"*");return}if(message.type!=="mtop"&&message.type!=="mtopStream"&&message.type!=="userInfo"&&message.type!=="screenshot")return;let binding=target[bindingName];if(typeof binding=="function")try{binding(JSON.stringify({type:message.type,requestId,payload:message.payload}))}catch{}}))}function installEarlyAppProfileEnvironment(config2){let browser=globalThis,target=globalThis;for(let[key,value]of Object.entries(config2.globals))try{target[key]=value}catch{}let insets=config2.safeAreaInsets??{top:config2.statusBarHeight,right:0,bottom:0,left:0};target.__STATUS_BAR_HEIGHT__=config2.statusBarHeight,target.__SAFE_AREA_INSET_BOTTOM__=insets.bottom;for(let[key,value]of[["userAgent",config2.userAgent],["platform",config2.navigatorPlatform],["vendor","Apple Computer, Inc."],["appVersion",config2.userAgent.replace(/^Mozilla\//,"")],["maxTouchPoints",config2.maxTouchPoints]])try{Object.defineProperty(browser.navigator,key,{configurable:!0,get:()=>value})}catch{}}function installWhenDocumentElementExists(install){let browser=globalThis;if(browser.document.documentElement){install();return}let observer=new browser.MutationObserver(()=>{browser.document.documentElement&&(observer.disconnect(),install())});observer.observe(browser.document,{childList:!0})}function buildDocumentSource(config2){return`;(() => {const config=${serializeForSource2(config2)};(${installCdpAppProfileRelay.toString()})(${JSON.stringify(APP_PROFILE_BINDING)});(${installEarlyAppProfileEnvironment.toString()})(config);(${installWhenDocumentElementExists.toString()})(() => {${buildAppProfileRuntimeCallSource("config")};});})();`}function appProfileEmulationCommands(config2,userAgent){return buildEnableEmulationCommands(config2).map(command=>command.method==="Emulation.setUserAgentOverride"?{...command,params:{userAgent,platform:config2.platform}}:command)}async function sendCommands(client2,commands){for(let{method,params,optional:optional2}of commands)await client2.sendCommand(method,params).catch(error48=>{if(!optional2)throw error48})}async function postRuntimeMessage(client2,executionContextId,message){await client2.sendCommand("Runtime.evaluate",{expression:`window.postMessage(${serializeForSource2(message)}, '*')`,...typeof executionContextId=="number"?{contextId:executionContextId}:{}})}function listenForBridgeRequests(session,client2,state){return client2.on("Runtime.bindingCalled",params=>{if(params?.name!==APP_PROFILE_BINDING||appProfileStates.get(session)!==state)return;let request;try{request=JSON.parse(params.payload)}catch{return}if(typeof request.requestId!="number")return;let requestId=request.requestId,contextId=typeof params.executionContextId=="number"?params.executionContextId:void 0,reply=message=>postRuntimeMessage(client2,contextId,{requestId,source:"mearl-content",...message});(async()=>{if(request.type==="screenshot"){if(client2!==session.client)return;try{let result=await cdpPageScreenshot(session,{format:"png"});await reply({type:"APP_BRIDGE_SCREENSHOT_RESPONSE",result:{success:!0,...result}})}catch(error48){await reply({type:"APP_BRIDGE_SCREENSHOT_RESPONSE",result:{success:!1,error:error48 instanceof Error?error48.message:String(error48)}})}return}if(request.type==="userInfo"){try{let result=await session.client.sendCommand("Network.getCookies",{urls:[session.url]}),response=resolveAppProfileUserInfo(session.url,(result.cookies??[]).map(cookie=>({name:cookie.name,value:cookie.value})));await reply({type:"APP_BRIDGE_USER_INFO_RESPONSE",result:{success:!0,response}})}catch(error48){await reply({type:"APP_BRIDGE_USER_INFO_RESPONSE",result:{success:!1,error:error48 instanceof Error?error48.message:String(error48)}})}return}let payload=request.payload??{},mtopPayload={...payload,...typeof payload.v=="string"&&payload.version===void 0?{version:payload.v}:{}},streamCapture;try{if(request.type==="mtopStream"){await cdpSendMtopStreamRequest(session,mtopPayload,{onRequestPrepared:metadata=>{streamCapture=recordCdpMtopStreamStart(session.buffers,{api:String(mtopPayload.api??""),url:metadata.url,method:metadata.method,requestHeaders:metadata.requestHeaders,requestData:mtopPayload.data??null})},onResponse:metadata=>{streamCapture&&recordCdpMtopStreamResponse(session.buffers,streamCapture,metadata)},onReceive:async data=>{streamCapture&&recordCdpMtopStreamChunk(session.buffers,streamCapture,data),await reply({type:"APP_BRIDGE_MTOP_STREAM_EVENT",eventType:"onReceive",data})}}),streamCapture&&recordCdpMtopStreamEnd(session.buffers,streamCapture),await reply({type:"APP_BRIDGE_MTOP_STREAM_EVENT",eventType:"onFinish",data:{}});return}let result=await cdpSendMtopRequest(session,mtopPayload);await reply({type:"APP_BRIDGE_MTOP_RESPONSE",result})}catch(error48){let message=error48 instanceof Error?error48.message:String(error48);request.type==="mtopStream"?(streamCapture&&recordCdpMtopStreamEnd(session.buffers,streamCapture,{error:message}),await reply({type:"APP_BRIDGE_MTOP_STREAM_EVENT",eventType:"onError",data:{ret:["HY_FAILED"],msg:message}})):await reply({type:"APP_BRIDGE_MTOP_RESPONSE",result:{success:!1,error:message}})}})().catch(()=>{})})}async function installChildTarget2(session,state,params,source){let sessionId=params.sessionId;if(typeof sessionId!="string")return;let child=session.client.createChildSession(sessionId);try{if(params.targetInfo?.type!=="iframe"||appProfileStates.get(session)!==state)return;await child.sendCommand("Runtime.enable");let frameName=(await child.sendCommand("Runtime.evaluate",{expression:"window.name",returnByValue:!0})).result?.value;if(frameName!=="__mearl_root__"&&frameName!=="__mearl_layer__")return;state.emulation?await sendCommands(child,appProfileEmulationCommands(state.emulation,state.config.userAgent)):await child.sendCommand("Emulation.setUserAgentOverride",{userAgent:state.config.userAgent,platform:state.config.navigatorPlatform}),await child.sendCommand("Runtime.addBinding",{name:APP_PROFILE_BINDING}),state.disposeListeners.push(listenForBridgeRequests(session,child,state)),state.childClients.push(child),await child.sendCommand("Page.addScriptToEvaluateOnNewDocument",{source}).catch(()=>{}),await child.sendCommand("Runtime.evaluate",{expression:source})}finally{await child.sendCommand("Runtime.runIfWaitingForDebugger").catch(()=>{})}}async function disposeState(session,state){appProfileStates.get(session)===state&&appProfileStates.delete(session),setCdpDeviceShellChildEnvironmentManagedByApp(session,!1);for(let dispose of state.disposeListeners.splice(0))dispose();isCdpDeviceShellActive(session)||await session.client.sendCommand("Target.setAutoAttach",{autoAttach:!1,waitForDebuggerOnStart:!1,flatten:!0}).catch(()=>{}),await session.client.sendCommand("Page.removeScriptToEvaluateOnNewDocument",{identifier:state.documentScriptIdentifier}).catch(()=>{}),await Promise.allSettled([session.client,...state.childClients].map(client2=>client2.sendCommand("Runtime.removeBinding",{name:APP_PROFILE_BINDING})));let deviceEmulation=session.emulation?.config;if(deviceEmulation){let commands=buildEnableEmulationCommands(deviceEmulation);await sendCommands(session.client,commands),await Promise.allSettled(state.childClients.map(client2=>sendCommands(client2,commands)))}else await Promise.allSettled([session.client,...state.childClients].map(client2=>client2.sendCommand("Emulation.setUserAgentOverride",{userAgent:""})))}function resolveCdpAppProfile(profile,options={}){return{profile:resolveAppProfile(profile,{os:options.os,appVersion:options.appVersion,deviceModel:options.deviceModel,devicePreset:options.devicePreset,orientation:options.orientation,bridgeConfig:options.bridgeConfig})}}async function applyResolvedCdpAppProfile(session,resolved){let previous=appProfileStates.get(session);previous&&await disposeState(session,previous);let source=buildDocumentSource(resolved.profile.injected),deviceEmulation=session.emulation?.config;deviceEmulation?await sendCommands(session.client,appProfileEmulationCommands(deviceEmulation,resolved.profile.ua)):await session.client.sendCommand("Emulation.setUserAgentOverride",{userAgent:resolved.profile.ua,platform:resolved.profile.injected.navigatorPlatform}),await session.client.sendCommand("Runtime.enable"),await session.client.sendCommand("Runtime.addBinding",{name:APP_PROFILE_BINDING});let script=await session.client.sendCommand("Page.addScriptToEvaluateOnNewDocument",{source});if(typeof script.identifier!="string"||!script.identifier)throw deviceEmulation?await sendCommands(session.client,buildEnableEmulationCommands(deviceEmulation)):await session.client.sendCommand("Emulation.setUserAgentOverride",{userAgent:""}).catch(()=>{}),new Error("Chrome did not return an app profile bootstrap script identifier");let state={config:resolved.profile.injected,documentScriptIdentifier:script.identifier,emulation:deviceEmulation,disposeListeners:[],childClients:[]};appProfileStates.set(session,state),setCdpDeviceShellChildEnvironmentManagedByApp(session,!0),state.disposeListeners.push(listenForBridgeRequests(session,session.client,state)),state.disposeListeners.push(session.client.on("Target.attachedToTarget",params=>{installChildTarget2(session,state,params,source).catch(()=>{})})),state.disposeListeners.push(session.client.on("Target.detachedFromTarget",params=>{let sessionId=params?.sessionId;typeof sessionId!="string"||appProfileStates.get(session)!==state||(state.childClients=state.childClients.filter(client2=>client2.sessionId!==sessionId))})),await session.client.sendCommand("Target.setAutoAttach",{autoAttach:!0,waitForDebuggerOnStart:!0,flatten:!0,filter:[{type:"iframe"},{exclude:!0}]})}async function updateCdpAppProfileDeviceEmulation(session,emulation){let state=appProfileStates.get(session);if(state)return state.emulation=emulation??void 0,await Promise.allSettled(state.childClients.map(client2=>emulation?sendCommands(client2,appProfileEmulationCommands(emulation,state.config.userAgent)):client2.sendCommand("Emulation.setUserAgentOverride",{userAgent:state.config.userAgent,platform:state.config.navigatorPlatform}))),{userAgent:state.config.userAgent,platform:state.config.navigatorPlatform}}function isCdpAppProfileActive(session){return appProfileStates.has(session)}async function waitForCdpAppProfileLoad(session,timeoutMs=3e4){if(isCdpDeviceShellActive(session)){await waitForCdpDeviceShellLoad(session,Math.min(timeoutMs,15e3));return}await waitForPageLoad(session,timeoutMs)}async function clearCdpAppProfile(session,reload=!0){let state=appProfileStates.get(session);if(!state)return{enabled:!1,reloaded:!1};await disposeState(session,state);let reloaded=!1;return reload&&(clearPageRefsForNavigation(session),await session.client.sendCommand("Page.reload",{}),await waitForCdpAppProfileLoad(session),reloaded=!0),{enabled:!1,reloaded}}async function cdpSetAppProfile(session,data){if(typeof data?.enabled!="boolean")throw new Error('set_app_profile: "enabled" is required (true to enable, false to clear)');if(!data.enabled){if(data.emulation===void 0)return clearCdpAppProfile(session,data.reload!==!1);let hadDeviceShell=await clearCdpDeviceShell(session),appResult=await clearCdpAppProfile(session,!1);await sendCommands(session.client,buildDisableEmulationCommands()),session.emulation=void 0;let reloaded2=!1;return(data.reload!==!1||hadDeviceShell)&&(clearPageRefsForNavigation(session),await session.client.sendCommand("Page.reload",{}),await waitForPageLoad(session,3e4),reloaded2=!0),{...appResult,device:{enabled:!1,deviceShell:!1,reloaded:reloaded2},reloaded:reloaded2}}if(!data.profile||typeof data.profile!="string")throw new Error('set_app_profile: "profile" is required when enabled=true');let resolved=resolveCdpAppProfile(data.profile,{...data,devicePreset:session.emulation?.config?.presetName,orientation:session.emulation?.config?.orientation});if(data.emulation!==void 0){let emulation=resolveEmulationConfig({enabled:!0,preset:resolved.profile.recommendedPreset,...data.emulation}),targetOs=emulation.platform==="Android"||emulation.platform==="OpenHarmony"?"android":"ios",targetDeviceModel=data.deviceModel??(emulation.presetName?DEVICE_PRESETS[emulation.presetName].appProfileModel:resolved.profile.injected.globals.__DEVICE_MODEL__),appResolved=resolveCdpAppProfile(data.profile,{...data,os:targetOs,deviceModel:targetDeviceModel}),deviceShell=data.emulation.deviceShell??!0;session.emulation={mobile:emulation.mobile,touch:emulation.touch,config:emulation,deviceShell},await applyResolvedCdpAppProfile(session,appResolved);let shellChanged=deviceShell?await applyCdpDeviceShell(session,emulation):await clearCdpDeviceShell(session);deviceShell&&setCdpDeviceShellChildEnvironmentManagedByApp(session,!0);let reloaded2=!1;return(data.reload!==!1||shellChanged)&&(clearPageRefsForNavigation(session),await session.client.sendCommand("Page.reload",{}),deviceShell?await waitForCdpDeviceShellLoad(session):await waitForPageLoad(session,3e4),reloaded2=!0),{enabled:!0,profile:appResolved.profile.profile,label:appResolved.profile.label,userAgent:appResolved.profile.ua,os:appResolved.profile.injected.platform==="Android"?"android":"ios",device:{enabled:!0,preset:emulation.presetName,viewport:{width:emulation.width,height:emulation.height,deviceScaleFactor:emulation.deviceScaleFactor,scale:emulation.scale??1},userAgent:emulation.userAgent,mobile:emulation.mobile,touch:emulation.touch,orientation:emulation.orientation,deviceShell,reloaded:reloaded2},reloaded:reloaded2}}await applyResolvedCdpAppProfile(session,resolved);let reloaded=!1;return data.reload!==!1&&(clearPageRefsForNavigation(session),await session.client.sendCommand("Page.reload",{}),await waitForCdpAppProfileLoad(session),reloaded=!0),{enabled:!0,profile:resolved.profile.profile,label:resolved.profile.label,userAgent:resolved.profile.ua,os:resolved.profile.injected.platform==="Android"?"android":"ios",reloaded}}registerActions([{name:"set_app_profile",session:"page",handler:cdpSetAppProfile}]);async function releaseCdpControl(session){let pageSessions=session.listOpenPageSessions(),targetIds=new Set(pageSessions.map(pageSession=>pageSession.targetId)),affectedTabIds=session.listRegisteredTabIds(targetIds).sort((a,b)=>a-b),hadActiveControl=session.hasActiveConnections();try{await releaseCdpRecordings(pageSessions)}finally{await Promise.allSettled(pageSessions.map(async pageSession=>{let[,deviceShell]=await Promise.allSettled([clearCdpAppProfile(pageSession,!1),clearCdpDeviceShell(pageSession),releaseControlledIndicator(pageSession)]);deviceShell.status==="fulfilled"&&deviceShell.value&&await pageSession.client.sendCommand("Page.reload",{}).catch(()=>{})})),clearCdpMockState(),session.close()}return{released:!0,hadActiveControl,affectedTabIds}}var SAMPLE_PAGE_READINESS_SRC=samplePageReadinessInPage.toString(),DISPOSE_PAGE_READINESS_SRC=disposePageReadinessObserverInPage.toString();async function startCdpNavigationObserver(cdpSession2,pageSession,urlBefore,options={}){let pageEndpoint=await resolveCdpDeviceShellPageEndpoint(pageSession),pageClient=pageEndpoint.client;await ensureCdpDomain(pageClient,"Page"),await ensureCdpDomain(pageClient,"Runtime"),options.trackNetwork&&await ensureCdpDomain(pageClient,"Network");let browserClient=null,baselineTargetIds=new Set;if(options.trackOpenedTabs)try{browserClient=await cdpSession2.getBrowserClient();let targets=await browserClient.sendCommand("Target.getTargets");for(let target of targets.targetInfos??[])baselineTargetIds.add(target.targetId)}catch{browserClient=null}let frameTree=await pageClient.sendCommand("Page.getFrameTree"),observedFrameId=pageEndpoint.frameId??frameTree.frameTree?.frame?.id,observesParentTargetSubframe=pageClient===pageSession.client&&pageEndpoint.frameId!==void 0,tracker=createNavigationSettlementTracker({urlBefore,trackNetwork:options.trackNetwork,networkAvailable:options.trackNetwork===!0,networkIdleMs:options.networkIdleMs,contentReadyAfterMs:options.contentReadyAfterMs,sampleContent:async()=>(await sendCdpDeviceShellPageCommand(pageSession,"Runtime.evaluate",{expression:`(${SAMPLE_PAGE_READINESS_SRC})(${options.networkIdleMs??500})`,returnByValue:!0})).result?.value}),removeFrameNavigated=pageClient.on("Page.frameNavigated",params=>{observedFrameId&¶ms.frame?.id!==observedFrameId||tracker.markStarted(params.frame?.url)}),removeWithinDocument=pageClient.on("Page.navigatedWithinDocument",params=>{observedFrameId&¶ms.frameId!==observedFrameId||(tracker.markStarted(params.url),tracker.markDocumentComplete(params.url))}),removeLoad=pageClient.on("Page.loadEventFired",()=>{observesParentTargetSubframe||tracker.hasStarted()&&tracker.markDocumentComplete()}),removeFrameStoppedLoading=pageClient.on("Page.frameStoppedLoading",params=>{observedFrameId&¶ms.frameId!==observedFrameId||tracker.hasStarted()&&tracker.markDocumentComplete()}),removeRequestStarted=options.trackNetwork?pageClient.on("Network.requestWillBeSent",params=>{isPotentialNavigationRequest(params.type??"",params.request?.url??"")&&tracker.requestStarted(params.requestId)}):()=>{},onRequestFinished=params=>tracker.requestFinished(params.requestId),removeRequestFinished=options.trackNetwork?pageClient.on("Network.loadingFinished",onRequestFinished):()=>{},removeRequestFailed=options.trackNetwork?pageClient.on("Network.loadingFailed",onRequestFinished):()=>{};return{hasStarted:tracker.hasStarted,hasNetworkActivity:tracker.hasNetworkActivity,waitForStart:tracker.waitForStart,waitForNetworkIdle:tracker.waitForNetworkIdle,waitForResult:async timeoutMs=>{let result=await tracker.waitForResult(timeoutMs);try{let pageState=await sendCdpDeviceShellPageCommand(pageSession,"Runtime.evaluate",{expression:"({ title: document.title, url: location.href })",returnByValue:!0});return{...result,title:pageState.result?.value?.title??result.title,urlAfter:pageState.result?.value?.url??result.urlAfter}}catch{return result}},getOpenedTabs:async timeoutMs=>{if(!browserClient||options.sourceTabId===void 0)return[];let candidates=((await browserClient.sendCommand("Target.getTargets")).targetInfos??[]).filter(target=>target.type==="page"&&target.openerId===pageSession.targetId&&!baselineTargetIds.has(target.targetId));return(await Promise.all(candidates.map(async candidate=>{let tabId=await cdpSession2.ensureTargetRegistered(candidate.targetId),ready=!1;try{let openedPageSession=await cdpSession2.getPageSession(tabId);await ensureCdpDomain(openedPageSession.client,"Page"),await waitForPageLoad(openedPageSession,timeoutMs),ready=!0}catch{}let targetInfo=await browserClient.sendCommand("Target.getTargetInfo",{targetId:candidate.targetId}).then(result=>result.targetInfo).catch(()=>null);return targetInfo?{tabId,openerTabId:options.sourceTabId,url:targetInfo.url??candidate.url??"",title:targetInfo.title??candidate.title??"",ready,settledBy:ready?"load":"timeout"}:null}))).filter(tab=>tab!==null)},dispose:async()=>{removeFrameNavigated(),removeWithinDocument(),removeLoad(),removeFrameStoppedLoading(),removeRequestStarted(),removeRequestFinished(),removeRequestFailed(),tracker.dispose(),await sendCdpDeviceShellPageCommand(pageSession,"Runtime.evaluate",{expression:`(${DISPOSE_PAGE_READINESS_SRC})()`,returnByValue:!1}).catch(()=>{})}}}var INSTALL_PAGE_OBSERVER_SRC=installPageObserverInPage.toString(),DISPOSE_PAGE_OBSERVER_SRC=disposePageObserverInPage.toString(),PAGE_OBSERVER_GLOBAL="__MEARL_PAGE_OBSERVER__",observationTargets=new WeakMap;function evaluationError(result){return result.exceptionDetails?result.exceptionDetails.exception?.description??result.exceptionDetails.text??"Page observation evaluation failed":null}async function startPageObservation(session){let result=await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:`(${INSTALL_PAGE_OBSERVER_SRC})()`,returnByValue:!0}),error48=evaluationError(result);if(error48)throw new Error(error48);let checkpoint=result.result?.value;if(!checkpoint||typeof checkpoint.version!="number")throw new Error("Page observer did not return a checkpoint");let endpoint=await resolveCdpDeviceShellPageEndpoint(session);return observationTargets.set(checkpoint,{...endpoint,startedAt:Date.now()}),checkpoint}async function finishPageObservation(session,checkpoint,options={}){let startedTarget=observationTargets.get(checkpoint),currentTarget=await resolveCdpDeviceShellPageEndpoint(session);if(startedTarget&¤tTarget.url&&(currentTarget.client!==startedTarget.client||currentTarget.frameId!==startedTarget.frameId||currentTarget.url!==(startedTarget.url??checkpoint.url))){let title=await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:"document.title",returnByValue:!0}).then(result2=>typeof result2.result?.value=="string"?result2.result.value:"").catch(()=>"");return{mode:"navigation",urlBefore:checkpoint.url,urlAfter:currentTarget.url,title,elapsed:Date.now()-startedTarget.startedAt,loaded:!0,ready:!0,settledBy:"load",pendingRequests:0,fullSnapshotRecommended:!0,snapshotReasons:["navigation"]}}let{quietMs,firstChangeTimeoutMs,timeoutMs}=resolvePageObservationWaitOptions(options),expression=`(() => {
|
|
1130
|
+
const state = globalThis[${JSON.stringify(PAGE_OBSERVER_GLOBAL)}];
|
|
1131
|
+
if (!state || typeof state.waitSince !== 'function') {
|
|
1132
|
+
throw new Error('Page observer is unavailable after the action');
|
|
1133
|
+
}
|
|
1134
|
+
return state.waitSince(
|
|
1135
|
+
${checkpoint.version},
|
|
1136
|
+
${JSON.stringify(checkpoint.focus)},
|
|
1137
|
+
${quietMs},
|
|
1138
|
+
${firstChangeTimeoutMs},
|
|
1139
|
+
${timeoutMs}
|
|
1140
|
+
);
|
|
1141
|
+
})()`,result=await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression,returnByValue:!0,awaitPromise:!0},timeoutMs+2e3),error48=evaluationError(result);if(error48)throw new Error(error48);let changeSet=result.result?.value;if(!changeSet||changeSet.mode!=="delta")throw new Error("Page observer did not return a change set");return changeSet}async function disposePageObservation(session){await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:`(${DISPOSE_PAGE_OBSERVER_SRC})()`,returnByValue:!1}).catch(()=>{})}function filterRequests(buffers,opts){let pattern=opts.filter?compileTextPattern(opts.filter):void 0;return queryCapturedEntries(buffers.requests.filter(request=>Number.isSafeInteger(request.captureSequence)),buffers.capture,{after:opts.after,since:opts.since,limit:opts.count??10},request=>(!opts.source||opts.source==="all"||request.source===opts.source)&&(!pattern||matchesTextPattern(request.url,pattern)||matchesTextPattern(request.apiName,pattern)),buffers.capture.droppedRequestsThroughSequence,"requests")}async function cdpGetRequests(session,data){let opts={count:data.count??10,filter:data.filter,since:data.since,after:data.after,source:data.source,applyHiddenFilter:data.applyHiddenFilter!==!1},captured=filterRequests(session.buffers,opts),serializeOpts={includeBody:data.includeBody!==!1,includeHeaders:data.includeHeaders===!0,maxBodySize:data.maxBodySize??5e4,fields:data.fields,keysOnly:data.keysOnly===!0};return{meta:{count:captured.entries.length,totalMatched:captured.totalMatched,totalInBuffer:session.buffers.requests.length,filter:data.filter,since:data.since,after:data.after,nextCursor:captured.nextCursor,hasMore:captured.hasMore,gap:captured.gap,source:"cdp"},requests:captured.entries.map(r=>serializeRequest(r,serializeOpts))}}async function cdpGetLogs(session,data){let{level,since,after,limit=100,filter}=data,pattern=filter?compileTextPattern(filter):void 0,captured=queryCapturedEntries(session.buffers.logs,session.buffers.capture,{after,since,limit},log3=>(!level||level==="all"||log3.level===level)&&(!pattern||matchesTextPattern(log3.message,pattern)||log3.args.some(arg=>matchesTextPattern(arg,pattern))),session.buffers.capture.droppedLogsThroughSequence,"logs"),captureStatus=session.buffers.logs.length===0?"armed":"active";return{meta:{count:captured.entries.length,totalMatched:captured.totalMatched,totalInBuffer:session.buffers.logs.length,level:level||"all",since,after,filter,nextCursor:captured.nextCursor,hasMore:captured.hasMore,gap:captured.gap,captureStatus,...captureStatus==="armed"&&{hint:"Log capture is active, but this tab has no captured history yet. Reload the current tab or repeat the triggering action, then call get_logs again."},source:"cdp"},logs:captured.entries}}async function cdpCaptureCheckpoint(session,_data){return{tabId:session.tabId,cursor:captureCheckpoint(session.buffers.capture),timestampMs:Date.now(),captureStatus:session.buffers.capture.currentSequence===0?"armed":"active"}}async function collectCdpPageDiagnostics(session,after,diagnostics){let result={};if(diagnostics.logs){let options=diagnostics.logs===!0?{level:"error",limit:100}:{level:"error",limit:100,...diagnostics.logs};result.logs=await cdpGetLogs(session,{...options,after})}if(diagnostics.requests){let options=diagnostics.requests===!0?{source:"all",includeBody:!1,count:100}:{source:"all",includeBody:!1,count:100,...diagnostics.requests};result.requests=await cdpGetRequests(session,{...options,after})}if(diagnostics.events){let options=diagnostics.events===!0?{source:"all",limit:100}:{source:"all",limit:100,...diagnostics.events};result.events=await cdpGetEvents(session,{...options,after})}return result}async function cdpGetEvents(session,data){let{source="all",event_type,since,after,limit=20,filter,includeRaw=!1}=data,response=queryCapturedTrackingEvents(session.buffers.events,session.buffers.capture,{source,event_type,since,after,limit,filter},session.buffers.capture.droppedEventsThroughSequence),captureStatus=response.totalInBuffer===0?"armed":"active",hint=response.events.length===0&&captureStatus==="armed"?TRACKING_CAPTURE_ARMED_HINT:void 0;return{meta:{count:response.events.length,totalMatched:response.totalMatched,totalInBuffer:response.totalInBuffer,source,captureStatus,captureSource:"cdp",includeRaw,after,nextCursor:response.nextCursor,hasMore:response.hasMore,gap:response.gap,hint},events:response.events.map(event=>formatTrackingEvent(event,includeRaw))}}registerActions([{name:"tab_checkpoint",session:"page",handler:cdpCaptureCheckpoint},{name:"capture_checkpoint",session:"page",handler:cdpCaptureCheckpoint},{name:"get_requests",session:"page",handler:cdpGetRequests},{name:"get_logs",session:"page",handler:cdpGetLogs},{name:"get_events",session:"page",handler:cdpGetEvents}]);async function cdpRunActions(session,data,controlSource="local"){let{actions,tabId}=data;if(!Array.isArray(actions)||actions.length===0)throw new Error("actions must be a non-empty array");if(actions.length>50)throw new Error("actions array exceeds maximum of 50 steps");let results=[];for(let i=0;i<actions.length;i++){let step=actions[i],stepAction=String(step.action??"");if(!stepAction)return{results,completedSteps:results.length,totalSteps:actions.length,error:`Step ${i}: action must be a non-empty string`,failedStep:i};if(!isBrowserCommandAction(stepAction))return{results,completedSteps:results.length,totalSteps:actions.length,error:`Step ${i}: unsupported action "${stepAction}"`,failedStep:i};if(stepAction==="run_actions")return{results,completedSteps:results.length,totalSteps:actions.length,error:`Step ${i}: composite action "${stepAction}" is not allowed in run_actions`,failedStep:i};if(stepAction==="browser_release")return{results,completedSteps:results.length,totalSteps:actions.length,error:`Step ${i}: browser-level action "${stepAction}" is not allowed in run_actions`,failedStep:i};let mergedData={...step.data};tabId!==void 0&&mergedData.tabId===void 0&&(mergedData.tabId=tabId);try{let result=await dispatchCdpAction(session,stepAction,mergedData,controlSource);results.push({step:i,action:stepAction,success:!0,data:result})}catch(error48){let errorMessage2=error48 instanceof Error?error48.message:String(error48);return results.push({step:i,action:stepAction,success:!1,error:errorMessage2}),{results,completedSteps:i,totalSteps:actions.length,error:errorMessage2,failedStep:i}}}return{results,completedSteps:actions.length,totalSteps:actions.length}}async function cdpObservedPageAction(session,action,data,controlSource="local"){let{actionData,observe,diagnostics}=splitObservedActionPayload(action,data),{tabId}=actionData;if(typeof tabId!="number")throw new Error(`${action} requires a numeric tabId`);let pageSession=await session.getPageSession(tabId);if(await ensureControlledIndicator(pageSession,controlSource),observe===!1){if(!diagnostics)return dispatchCdpAction(session,action,actionData,controlSource);let cursor=captureCheckpoint(pageSession.buffers.capture),actionResult,actionFailure;try{actionResult=await dispatchCdpAction(session,action,actionData,controlSource)}catch(error48){actionFailure=describePageActionFailure(error48)}let result2={action:{name:action,success:actionFailure===void 0,...actionResult!==void 0?{data:actionResult}:{},...actionFailure||{}}};return actionFailure?.stage==="precondition"?result2:{...result2,diagnostics:await collectCdpPageDiagnostics(pageSession,cursor,diagnostics)}}let diagnosticsCursor,result=await runPageAct({action,actionData,observe},{startObservation:()=>startPageObservation(pageSession),finishObservation:(checkpoint,options)=>finishPageObservation(pageSession,checkpoint,options),startNavigationObserver:options=>startCdpNavigationObserver(session,pageSession,options.urlBefore,options),executeAction:(name,params)=>(diagnostics&&(diagnosticsCursor=captureCheckpoint(pageSession.buffers.capture)),dispatchCdpAction(session,name,{...params,tabId},controlSource)),finalizeObservation:observation=>observation.mode==="delta"?enrichCdpPageChangeSetWithRefs(pageSession,observation):Promise.resolve(observation),disposeObservation:()=>disposePageObservation(pageSession)});return!diagnostics||!diagnosticsCursor||result.action.stage==="precondition"?result:{...result,diagnostics:await collectCdpPageDiagnostics(pageSession,diagnosticsCursor,diagnostics)}}registerActions([{name:"run_actions",session:"browser",handler:cdpRunActions}]);import{randomUUID as randomUUID2}from"node:crypto";import{createReadStream}from"node:fs";var FILE_CHUNK_BYTES=256*1024,TRANSFER_ACTION_TIMEOUT_MS=15e3;async function sendFileChunks(transferId,fileIndex,file2,send){let chunkIndex=0,sendChunk=async chunk=>{await send("__send_request_file_chunk",{transferId,fileIndex,chunkIndex,base64:chunk.toString("base64")},TRANSFER_ACTION_TIMEOUT_MS),chunkIndex+=1};if(file2.filePath){for await(let chunk of createReadStream(file2.filePath,{highWaterMark:FILE_CHUNK_BYTES}))await sendChunk(Buffer.isBuffer(chunk)?chunk:Buffer.from(chunk));return}let content=file2.content;for(let offset=0;offset<content.byteLength;offset+=FILE_CHUNK_BYTES)await sendChunk(content.subarray(offset,offset+FILE_CHUNK_BYTES))}async function prepareFileTransfer(data,send){let files=await resolveSendRequestFiles(data.files??[]);if(files.length===0)throw new Error("files must contain at least one file");let transferId=randomUUID2();await send("__send_request_file_start",{transferId,files:files.map(file2=>file2.descriptor),url:data.url,withCookies:data.withCookies},TRANSFER_ACTION_TIMEOUT_MS);try{for(let index=0;index<files.length;index+=1)await sendFileChunks(transferId,index,files[index],send)}catch(error48){throw await send("__send_request_file_abort",{transferId},TRANSFER_ACTION_TIMEOUT_MS).catch(()=>{}),error48}let{files:_files,...request}=data;return{transferId,request}}async function abortFileTransfer(transferId,send){await send("__send_request_file_abort",{transferId},TRANSFER_ACTION_TIMEOUT_MS).catch(()=>{})}function hasSendRequestFiles(data){return!!data&&typeof data=="object"&&Array.isArray(data.files)&&data.files.length>0}function hasRunActionsSendRequestFiles(data){if(!data||typeof data!="object")return!1;let actions=data.actions;return Array.isArray(actions)&&actions.some(step=>step?.action==="send_request"&&hasSendRequestFiles(step.data))}async function sendRequestWithTransferredFiles(data,send){let prepared=await prepareFileTransfer(data,send);try{let requestTimeout=Number(data.timeout??3e4);return await send("__send_request_with_files",{...prepared.request,transferId:prepared.transferId},(Number.isFinite(requestTimeout)&&requestTimeout>0?requestTimeout:3e4)+5e3)}catch(error48){throw await abortFileTransfer(prepared.transferId,send),error48}}async function sendRunActionsWithTransferredFiles(data,send,resolveTimeoutMs){if(!Array.isArray(data.actions))throw new Error("actions must be an array");let preparedTransferIds=[];try{let actions=[];for(let index=0;index<data.actions.length;index+=1){let step=data.actions[index],action=String(step.action??"");if(action.startsWith("__"))throw new Error(`Step ${index}: internal action "${action}" is not available to clients`);if(action!=="send_request"||!hasSendRequestFiles(step.data)){actions.push(step);continue}let prepared=await prepareFileTransfer(step.data,send);preparedTransferIds.push(prepared.transferId),actions.push({action:"__send_request_with_files",data:{...prepared.request,transferId:prepared.transferId}})}let transformed={...data,actions};return await send("run_actions",transformed,resolveTimeoutMs(transformed))}finally{await Promise.all(preparedTransferIds.map(transferId=>abortFileTransfer(transferId,send)))}}import fs2 from"node:fs";import path2 from"node:path";import{spawn as spawn2,spawnSync}from"node:child_process";function isAlive(pid){if(!pid||pid<=0)return!1;try{return process.kill(pid,0),!0}catch(error48){return error48.code==="EPERM"}}import{join}from"node:path";import{homedir}from"node:os";import{createHash}from"node:crypto";var DAEMON_HOME=join(homedir(),".mearl");function hashKey(key){return createHash("sha256").update(key).digest("hex").slice(0,16)}function keyedDir(subdir){return join(DAEMON_HOME,subdir)}function keyedConfigFile(subdir,key){return join(keyedDir(subdir),`${hashKey(key)}.json`)}import{closeSync,existsSync,linkSync,openSync,statSync,mkdirSync,readFileSync,writeFileSync,renameSync,rmSync,readdirSync}from"node:fs";import{dirname,join as join2}from"node:path";import{randomUUID as randomUUID3}from"node:crypto";var LOCK_WAIT_MS=10,LOCK_TIMEOUT_MS=5e3,OWNER_WRITE_GRACE_MS=1e3,lockWaitBuffer=new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));function ensureDir(dir){existsSync(dir)||mkdirSync(dir,{recursive:!0,mode:448})}function pauseForLock(){Atomics.wait(lockWaitBuffer,0,0,LOCK_WAIT_MS)}function readRecordUnlocked(file2){try{if(!existsSync(file2))return null;let parsed=JSON.parse(readFileSync(file2,"utf-8"));return parsed&&typeof parsed.pid=="number"?parsed:null}catch{return null}}function removeRecordUnlocked(file2){rmSync(file2,{force:!0})}function writeRecordUnlocked(file2,record2){let tmp=`${file2}.${process.pid}.${randomUUID3()}.tmp`;try{writeFileSync(tmp,JSON.stringify(record2),{mode:384}),renameSync(tmp,file2)}catch(error48){try{rmSync(tmp,{force:!0})}catch{}throw error48}}function removeStaleLock(lockDir){let ownerFile=join2(lockDir,"owner.json"),owner=readRecordUnlocked(ownerFile);if(owner){if(isAlive(owner.pid))return!1}else try{if(Date.now()-statSync(lockDir).mtimeMs<OWNER_WRITE_GRACE_MS)return!1}catch{return!0}try{return rmSync(lockDir,{recursive:!0,force:!0}),!0}catch{return!1}}function withRecordLock(file2,operation){ensureDir(dirname(file2));let lockDir=`${file2}.registry.lock`,ownerFile=join2(lockDir,"owner.json"),token=randomUUID3(),deadline=Date.now()+LOCK_TIMEOUT_MS;for(;;){try{mkdirSync(lockDir,{mode:448})}catch(error48){if(error48.code!=="EEXIST")throw error48;if(!removeStaleLock(lockDir)){if(Date.now()>=deadline)throw new Error(`Timed out waiting for registry lock: ${file2}`,{cause:error48});pauseForLock()}continue}let ownerFd=null;try{ownerFd=openSync(ownerFile,"wx",384),writeFileSync(ownerFd,JSON.stringify({pid:process.pid,token}))}catch(error48){if(ownerFd!==null&&closeSync(ownerFd),ownerFd=null,error48.code==="EEXIST"){if(Date.now()>=deadline)throw new Error(`Timed out acquiring registry lock: ${file2}`,{cause:error48});pauseForLock();continue}throw error48}finally{ownerFd!==null&&closeSync(ownerFd)}try{return operation()}finally{readRecordUnlocked(ownerFile)?.token===token&&rmSync(lockDir,{recursive:!0,force:!0})}}}function writeRecord(file2,record2){withRecordLock(file2,()=>writeRecordUnlocked(file2,record2))}function readRecord(file2){return readRecordUnlocked(file2)}function removeRecord(file2){try{withRecordLock(file2,()=>removeRecordUnlocked(file2))}catch{}}function removeRecordIfPid(file2,pid){try{return withRecordLock(file2,()=>readRecordUnlocked(file2)?.pid!==pid?!1:(removeRecordUnlocked(file2),!0))}catch{return!1}}function removeInvalidRecord(file2){try{return withRecordLock(file2,()=>!existsSync(file2)||readRecordUnlocked(file2)?!1:(removeRecordUnlocked(file2),!0))}catch{return!1}}function listRecordFiles(dir){try{return readdirSync(dir).filter(name=>name.endsWith(".json")).map(name=>join2(dir,name))}catch{return[]}}function readLiveRecords(dir){let out=[];for(let file2 of listRecordFiles(dir)){let rec=readRecord(file2);rec&&isAlive(rec.pid)?out.push(rec):rec?removeRecordIfPid(file2,rec.pid):removeInvalidRecord(file2)}return out}import{existsSync as existsSync2,statSync as statSync2,renameSync as renameSync2,readFileSync as readFileSync2}from"node:fs";var DEFAULT_MAX_LOG_BYTES=5*1024*1024;import{spawn}from"node:child_process";import{closeSync as closeSync2,openSync as openSync2}from"node:fs";import{dirname as dirname2}from"node:path";var processes=new Map,CONNECTORS_SUBDIR="connectors",REGISTRY_DIR=keyedDir(CONNECTORS_SUBDIR),OFFICIAL_NPM_REGISTRY="https://registry.npmjs.org",STATUS_POLL_MS=5e3;function recordFileFor(serverUrl){return keyedConfigFile(CONNECTORS_SUBDIR,serverUrl)}var logFn=()=>{},isDaemon=!1,sendToExtensionFn=()=>{},nativeHostVersion="unknown",lastPushedKey="",statusWatcher=null;function initCloudConnector(deps){logFn=deps.log,isDaemon=deps.isDaemonMode,sendToExtensionFn=deps.sendToExtension,nativeHostVersion=deps.version,startStatusWatcher()}function liveRecords(){return readLiveRecords(REGISTRY_DIR)}function reconcile(){let live=new Map;for(let record2 of liveRecords())live.set(record2.serverUrl,{serverUrl:record2.serverUrl,pid:record2.pid,...record2.connectorId?{connectorId:record2.connectorId}:{},...record2.name?{name:record2.name}:{}});for(let[serverUrl,entry]of processes)isAlive(entry.pid)?live.has(serverUrl)||live.set(serverUrl,{serverUrl,pid:entry.pid,...entry.connectorId?{connectorId:entry.connectorId}:{},...entry.name?{name:entry.name}:{}}):processes.delete(serverUrl);return Array.from(live.values())}function connectorsKey(connectors){return connectors.map(c=>`${c.serverUrl}@${c.pid}@${c.connectorId??""}@${c.name??""}`).sort().join("|")}function pushStatus(connectors){isDaemon||(lastPushedKey=connectorsKey(connectors),sendToExtensionFn({type:"cloud_connector_status_changed",data:{connectors}}))}function notifyStatusChanged(){pushStatus(reconcile())}function pushIfChanged(){let connectors=reconcile();return connectorsKey(connectors)!==lastPushedKey&&pushStatus(connectors),connectors}function startStatusWatcher(){isDaemon||statusWatcher||(statusWatcher=setInterval(()=>{try{pushIfChanged()}catch{}},STATUS_POLL_MS),statusWatcher.unref?.())}function registerConnector(serverUrl,pid,child){let record2=readRecord(recordFileFor(serverUrl)),entry={pid,serverUrl,...record2?.connectorId?{connectorId:record2.connectorId}:{},...record2?.name?{name:record2.name}:{},...child?{process:child}:{}};return processes.set(serverUrl,entry),notifyStatusChanged(),entry}function clearConnector(serverUrl,expected){let entry=processes.get(serverUrl);entry&&entry.pid!==expected.pid||expected.child&&entry?.process&&entry.process!==expected.child||(processes.delete(serverUrl),removeRecordIfPid(recordFileFor(serverUrl),expected.pid),notifyStatusChanged())}function findLiveConnector(serverUrl){let entry=processes.get(serverUrl);if(entry&&isAlive(entry.pid))return entry.pid;let record2=readRecord(recordFileFor(serverUrl));return record2&&isAlive(record2.pid)?record2.pid:(entry&&processes.delete(serverUrl),record2&&removeRecordIfPid(recordFileFor(serverUrl),record2.pid),null)}function findBin(bin,env){let lookupCommand=process.platform==="win32"?"where":"which",result=spawnSync(lookupCommand,[bin],{encoding:"utf-8",env});return result.status===0&&result.stdout.split(/\r?\n/).find(Boolean)||null}function getBinVersion(binPath){try{let result=spawnSync(process.execPath,[binPath,"--version"],{encoding:"utf-8",timeout:5e3});return result.status===0?result.stdout.trim():null}catch{return null}}function makeDirectCommand(connectorPath){return process.platform!=="win32"?{command:process.execPath,argsPrefix:[connectorPath],displayName:`${process.execPath} ${connectorPath}`}:{command:connectorPath,argsPrefix:[],displayName:connectorPath}}function resolveCloudConnectorCommand(){let connectorBin=process.platform==="win32"?"mearl-cloud-connector.cmd":"mearl-cloud-connector",pathDelimiter=process.platform==="win32"?";":":",nodeDir=path2.dirname(process.execPath),enrichedPath=[nodeDir,process.env.PATH].filter(Boolean).join(pathDelimiter),enrichedEnv={...process.env,PATH:enrichedPath},connectorPath=findBin(connectorBin,enrichedEnv);if(connectorPath){let installedVersion=getBinVersion(connectorPath);if(installedVersion===nativeHostVersion)return logFn(`Cloud connector ${installedVersion} found at ${connectorPath}`),makeDirectCommand(connectorPath);logFn(`Cloud connector version mismatch: installed=${installedVersion}, expected=${nativeHostVersion}`)}let npmBin=process.platform==="win32"?"npm.cmd":"npm",npmPath=path2.join(nodeDir,npmBin),npmCommand=fs2.existsSync(npmPath)?npmPath:npmBin,targetPackage=`@mearl/cloud-connector@${nativeHostVersion}`;logFn(`Installing ${targetPackage} globally via ${npmCommand}...`);let install=spawnSync(npmCommand,["install","-g",targetPackage,"--prefer-offline",`--registry=${OFFICIAL_NPM_REGISTRY}`],{encoding:"utf-8",env:enrichedEnv,timeout:3e4});if(install.status===0){let newPath=findBin(connectorBin,enrichedEnv);if(newPath)return logFn(`Global install succeeded: ${newPath}`),makeDirectCommand(newPath)}logFn(`Global install failed (status=${install.status}), falling back to npx`),install.stderr&&logFn(install.stderr.trim());let npxBin=process.platform==="win32"?"npx.cmd":"npx",npxPath=path2.join(nodeDir,npxBin),npxCommand=fs2.existsSync(npxPath)?npxPath:npxBin;return{command:npxCommand,argsPrefix:[`@mearl/cloud-connector@${nativeHostVersion}`],displayName:`${npxCommand} @mearl/cloud-connector@${nativeHostVersion}`,env:enrichedEnv}}function startCloudConnector(serverUrl){return new Promise(resolve3=>{let existingPid=findLiveConnector(serverUrl);if(existingPid){logFn(`Reusing existing cloud connector for ${serverUrl} (pid=${existingPid})`);let entry=registerConnector(serverUrl,existingPid);resolve3({success:!0,pid:existingPid,...entry.connectorId?{connectorId:entry.connectorId}:{},...entry.name?{name:entry.name}:{},reused:!0});return}let connectorCommand=resolveCloudConnectorCommand();logFn(`Starting cloud connector via ${connectorCommand.displayName}`);let child=spawn2(connectorCommand.command,[...connectorCommand.argsPrefix,serverUrl,"--fail-fast"],{detached:!0,env:connectorCommand.env,stdio:["ignore","pipe","pipe"],windowsHide:!0}),settled=!1,outputBuffer="",startupTimer=setTimeout(()=>{finish(!1,{error:"Cloud connector startup timeout"}),child.kill()},6e4),finish=(ok,result={})=>{if(!settled)if(settled=!0,clearTimeout(startupTimer),ok&&child.pid){let entry=registerConnector(serverUrl,child.pid,child);resolve3({success:!0,pid:child.pid,...entry.connectorId?{connectorId:entry.connectorId}:{},...entry.name?{name:entry.name}:{}})}else resolve3({success:!1,error:result.error||"Failed to spawn cloud connector"})};child.once("error",error48=>{logFn(`Failed to spawn cloud connector: ${error48.message}`),finish(!1,{error:error48.message})});let handleOutput=chunk=>{let text=chunk.toString();outputBuffer=(outputBuffer+text).slice(-2e3),logFn(`[CloudConnector] ${text.trim()}`),text.includes("[CloudConnector] Connected to")&&finish(!0)};child.stdout?.on("data",handleOutput),child.stderr?.on("data",handleOutput),child.once("spawn",()=>{child.once("exit",(code,signal)=>{child.pid&&clearConnector(serverUrl,{pid:child.pid,child}),logFn(`Cloud connector exited for ${serverUrl}: code=${code??"null"} signal=${signal??"null"}`),settled||finish(!1,{error:outputBuffer.trim()||`Cloud connector exited before connected: code=${code??"null"} signal=${signal??"null"}`})}),child.unref()})})}function stopCloudConnector(serverUrl){let pid=processes.get(serverUrl)?.pid??readRecord(recordFileFor(serverUrl))?.pid;if(!pid)return{success:!1,error:"Cloud connector not found"};try{return isAlive(pid)&&process.kill(pid),clearConnector(serverUrl,{pid}),logFn(`Stopped cloud connector for ${serverUrl} (pid=${pid})`),{success:!0}}catch(error48){let err=error48;return err.code==="ESRCH"?(clearConnector(serverUrl,{pid}),{success:!0}):(logFn(`Failed to stop cloud connector: ${err.message}`),{success:!1,error:err.message})}}function listCloudConnectors(){return{connectors:pushIfChanged()}}var TdbankLoginRequiredError=class extends Error{},tdbankLoginAttempts=new WeakMap;async function cdpFetchTdbankRequest(session,path23,options={}){let url2=new URL(`https://tdbank.alibaba-inc.com${path23}`);for(let[key,value]of Object.entries(options.params??{}))value!=null&&url2.searchParams.set(key,String(value));let cookies=await getCookiesForUrl(session,url2.toString()),cookieHeader=buildCookieHeaderValue(cookies),headers={Accept:"application/json, text/plain, */*","Accept-Language":"en"};cookieHeader&&(headers.Cookie=cookieHeader);let method="GET",body;if(options.formBody){method="POST";let form=buildMultipartFormBody(options.formBody);headers["Content-Type"]=form.contentType,body=form.body}else options.body&&(method="POST",headers["Content-Type"]="application/json",body=JSON.stringify(options.body));let response=await nodeFetch(url2.toString(),{method,headers,body,timeoutMs:options.timeoutMs});if(response.status===401||response.status===403||response.status>=300&&response.status<400)throw new TdbankLoginRequiredError(TDBANK_LOGIN_REQUIRED_MESSAGE);if(response.status<200||response.status>=300)throw new Error(`TDBank request failed (${response.status} ${response.statusText})`);let text=response.body;if(text.trimStart().startsWith("<"))throw new TdbankLoginRequiredError(TDBANK_LOGIN_REQUIRED_MESSAGE);let payload;try{payload=JSON.parse(text)}catch{throw new Error("TDBank returned a non-JSON response")}if(payload?.success)return payload.data;throw new Error(payload?.message||`TDBank request failed (${payload?.code??"unknown"})`)}async function cdpGetTracknick(session){let cookies=await getCookiesForUrl(session,"https://www.taobao.com/");return decodeTracknick(cookies.get("tracknick")??"")}async function cdpWaitForTracknick(session,options={}){let{previous="",expected="",timeoutMs=1e4}=options,startedAt=Date.now(),latest="";for(;Date.now()-startedAt<timeoutMs;){if(latest=await cdpGetTracknick(session),expected&&latest===expected||!expected&&latest&&latest!==previous)return latest;await new Promise(resolve3=>setTimeout(resolve3,500))}return latest||await cdpGetTracknick(session)}async function cdpOpenAndCloseTarget(cdpSession2,url2,inspect=!1){let browser=await cdpSession2.getBrowserClient(),{targetId}=await browser.sendCommand("Target.createTarget",{url:url2,background:!0});try{if(await new Promise(resolve3=>setTimeout(resolve3,3500)),!inspect)return;let tabId=await cdpSession2.registerTarget(targetId);return(await(await cdpSession2.getPageSession(tabId)).client.sendCommand("Runtime.evaluate",{expression:`({
|
|
848
1142
|
finalUrl: location.href,
|
|
849
1143
|
bodyText: document.body?.innerText?.trim().slice(0, 2000) ?? ''
|
|
850
1144
|
})`,returnByValue:!0})).result?.value}finally{await browser.sendCommand("Target.closeTarget",{targetId}).catch(()=>{})}}async function cdpOpenTdbankQrLogin(cdpSession2){let browser=await cdpSession2.getBrowserClient(),{targetId}=await browser.sendCommand("Target.createTarget",{url:"about:blank",background:!0});try{let tabId=await cdpSession2.registerTarget(targetId),pageSession=await cdpSession2.getPageSession(tabId);await pageSession.client.sendCommand("Page.navigate",{url:TDBANK_QR_LOGIN_URL}),await waitForPageLoad(pageSession,1e4).catch(()=>{});let evaluation=await pageSession.client.sendCommand("Runtime.evaluate",{expression:`(async () => {
|
|
@@ -888,7 +1182,7 @@ Content-Type: ${file2.contentType}\r
|
|
|
888
1182
|
: undefined
|
|
889
1183
|
);
|
|
890
1184
|
return { success: true, next };
|
|
891
|
-
})()`,returnByValue:!0,awaitPromise:!0});if(evaluation.exceptionDetails)throw new Error(evaluation.exceptionDetails.exception?.description??evaluation.exceptionDetails.text??"TDBank identity selection failed");let result=evaluation.result?.value;if(!result?.success)throw new Error(result?.error||"TDBank identity selection failed");return result.next?.action!=="redirect"||!result.next.data?.url?{loginStatus:"verification_required",tabId:pageSession.tabId,identity:identity2,nextAction:result.next?.action??"unknown"}:cdpFinalizeTdbankQrLogin(pageSession,result.next.data.url,identity2)}async function cdpContinueTdbankQrLogin(cdpSession2,data){if(typeof data.tabId!="number")return cdpOpenTdbankQrLogin(cdpSession2);let pageSession=await cdpSession2.getPageSession(data.tabId),requests=pageSession.buffers.requests,prompt=findLatestTdbankLoginIdentityPrompt(requests);if(prompt){let identityId=String(data.identityId??"").trim();return identityId?cdpSubmitTdbankLoginIdentity(pageSession,prompt,identityId):{loginStatus:"identity_required",tabId:data.tabId,identities:prompt.identities}}let continuation=findLatestTdbankLoginContinuation(requests);if(continuation?.action==="redirect"&&continuation.redirectUrl)return await cdpWaitForTdbankLoginAccountCount(pageSession)===null?{loginStatus:"verification_required",tabId:data.tabId,nextAction:"redirect"}:authenticatedTdbankLoginResult(data.tabId);if(continuation&&continuation.action!=="switchIdentity")return{loginStatus:"verification_required",tabId:data.tabId,nextAction:continuation.action};if(data.identityId!==void 0)throw new Error("TDBank login identities are not available yet; retry after scanning the QR code");let check2=findLatestTdbankLoginQrCheck(requests),loginStatus=check2?.status??"waiting_for_scan",qrcode=loginStatus==="waiting_for_scan"?findLatestTdbankLoginQrCode(requests):null;return loginStatus==="waiting_for_scan"&&!qrcode?cdpOpenTdbankQrLogin(cdpSession2):{loginStatus,tabId:data.tabId,...qrcode?{qrcodeImageUrl:buildTdbankQrImageUrl(qrcode.qrcode)}:{},...check2?.message?{message:check2.message}:{}}}async function cdpSwitchWithPasswordlessCredentials(cdpSession2,pageSession,havanaId,ssoKey){let previousNickname=await cdpGetTracknick(pageSession),page=await cdpOpenAndCloseTarget(cdpSession2,buildTdbankPasswordlessSsoUrl(havanaId,ssoKey),!0),businessError=page?.bodyText.match(/apiSso\+exception[^\n]*/)?.[0];if(businessError)throw new Error(`TDBank passwordless switch failed: ${businessError}`);if(page?.finalUrl){let finalHost=new URL(page.finalUrl).hostname;if(finalHost==="err.taobao.com"||finalHost==="error.taobao.com")throw new Error("TDBank passwordless switch failed: TDBank redirected to an error page")}let nickname=await cdpWaitForTracknick(pageSession,{previous:previousNickname});if(!nickname)throw new Error("TDBank passwordless switch failed: no test-account login was established");return{loginMethod:"passwordless",havanaId:String(havanaId),nickname}}async function refreshTdbankLogin(cdpSession2){let existing=tdbankLoginAttempts.get(cdpSession2);if(existing)return existing;let attempt=cdpOpenAndCloseTarget(cdpSession2,TDBANK_ORIGIN).then(()=>{}).finally(()=>{tdbankLoginAttempts.get(cdpSession2)===attempt&&tdbankLoginAttempts.delete(cdpSession2)});return tdbankLoginAttempts.set(cdpSession2,attempt),attempt}async function cdpFetchTdbank(cdpSession2,session,path23,options={}){try{return await cdpFetchTdbankRequest(session,path23,options)}catch(error48){if(!(error48 instanceof TdbankLoginRequiredError))throw error48}return await refreshTdbankLogin(cdpSession2),cdpFetchTdbankRequest(session,path23,options)}async function cdpFetchTdbankAccounts(cdpSession2,pageSession,pageIndex=1){let data=sanitizeTdbankSecrets(await cdpFetchTdbank(cdpSession2,pageSession,"/findPagedUsingAccountsByUser.do",{params:{_input_charset:"utf-8",pageIndex,searchKey:"",searchVal:""}}));return{...data,accountList:Array.isArray(data?.accountList)?data.accountList:[]}}async function cdpSwitchTdbankAccount(cdpSession2,pageSession,account){let previousNickname=await cdpGetTracknick(pageSession),ssoUrl=await cdpFetchTdbank(cdpSession2,pageSession,"/accountSso.do",{params:{_input_charset:"utf-8"},formBody:{havanaId:String(account.havanaId),site:String(account.site)}});await cdpOpenAndCloseTarget(cdpSession2,String(ssoUrl));let nickname=await cdpWaitForTracknick(pageSession,{previous:account.loginId?previousNickname:"",expected:account.loginId});return{...account.id!==void 0?{accountId:String(account.id)}:{},nickname}}async function cdpCreateTdbankSsoUrl(cdpSession2,pageSession,account){return String(await cdpFetchTdbank(cdpSession2,pageSession,"/accountSso.do",{params:{_input_charset:"utf-8"},formBody:{havanaId:String(account.havanaId),site:String(account.site)}}))}async function cdpResolveTdbankAccount(cdpSession2,pageSession,data){if(data.accountId!==void 0){let account=(await cdpFetchTdbankAccounts(cdpSession2,pageSession,1)).accountList.find(account2=>String(account2.id)===String(data.accountId));if(!account)throw new Error(`TDBank account not found: ${data.accountId}`);if(account.site===void 0||account.site===null)throw new Error(`TDBank account ${data.accountId} has no site`);return account}if(data.havanaId!==void 0&&data.site!==void 0)return{id:data.havanaId,havanaId:data.havanaId,site:data.site};throw new Error("accountId or havanaId + site is required")}async function cdpBorrowAndResolveTdbankAccount(cdpSession2,pageSession,query){let searchResult=await cdpFetchTdbank(cdpSession2,pageSession,"/searchAccountByInputV2.do",{params:{_input_charset:"utf-8",loginId:query,site:0}});if(!Array.isArray(searchResult)||searchResult.length===0)throw new Error(`No TDBank account found for: ${query}`);let account=searchResult[0],{havanaId,accountBucId,site}=account;if(!havanaId||!accountBucId||site===void 0||site===null)throw new Error("TDBank search result is missing havanaId/accountBucId/site");try{await cdpFetchTdbank(cdpSession2,pageSession,"/quickApplyAccountV2.do",{params:{_input_charset:"utf-8",accountBucId,accreditType:7,havanaId,site}})}catch(error48){if(!(error48 instanceof Error?error48.message:String(error48)).includes("厞įģåį¨"))throw error48}return account}async function cdpPrepareTdbankSso(cdpSession2,data){let pageSession=await cdpSession2.getPageSession(typeof data?.tabId=="number"?data.tabId:void 0),query=String(data?.query??"").trim(),account=query?await cdpBorrowAndResolveTdbankAccount(cdpSession2,pageSession,query):await cdpResolveTdbankAccount(cdpSession2,pageSession,data),havanaId=account.havanaId??account.id;return{ssoUrl:await cdpCreateTdbankSsoUrl(cdpSession2,pageSession,{havanaId,site:account.site}),account:{accountId:account.id!==void 0?String(account.id):void 0,havanaId:String(havanaId),site:String(account.site),loginId:data.havanaId===void 0&&account.loginId?String(account.loginId):void 0}}}async function cdpConsumeTdbankSso(cdpSession2,ssoUrl,expectedLoginId){let browser=await cdpSession2.getBrowserClient(),{targetId}=await browser.sendCommand("Target.createTarget",{url:ssoUrl,background:!0});try{let tabId=await cdpSession2.registerTarget(targetId),pageSession=await cdpSession2.getPageSession(tabId),nickname=await cdpWaitForTracknick(pageSession,{expected:expectedLoginId,timeoutMs:15e3});if(!nickname)throw new Error("TDBank SSO completed without a tracknick cookie");if(expectedLoginId&&nickname!==expectedLoginId)throw new Error(`TDBank SSO account mismatch: expected ${expectedLoginId}, got ${nickname}`);return{nickname}}finally{await browser.sendCommand("Target.closeTarget",{targetId}).catch(()=>{})}}async function cdpTdbankAccount(cdpSession2,data){let operation=data?.operation??"current";if(operation==="login")return cdpContinueTdbankQrLogin(cdpSession2,data);let pageSession=await cdpSession2.getPageSession(typeof data?.tabId=="number"?data.tabId:void 0);if(operation==="current"){let nickname=await cdpGetTracknick(pageSession),account=null;if(nickname)try{account=(await cdpFetchTdbankAccounts(cdpSession2,pageSession,1)).accountList.find(account2=>account2.loginId===nickname)??null}catch(error48){if(error48 instanceof TdbankLoginRequiredError)throw error48;account=null}return{nickname,account,source:"cdp"}}if(operation==="list")return{...await cdpFetchTdbankAccounts(cdpSession2,pageSession,data?.pageIndex??1),nickname:await cdpGetTracknick(pageSession),source:"cdp"};if(operation==="switch"){if(data.ssoKey!==void 0){let havanaId=String(data.havanaId??"").trim(),ssoKey=data.ssoKey?.trim();if(!havanaId||!ssoKey)throw new Error("havanaId and ssoKey are both required for passwordless TDBank switch");if(data.accountId!==void 0)throw new Error("havanaId + ssoKey cannot be combined with accountId");if(data.site!==void 0&&String(data.site)!=="taobao")throw new Error('passwordless TDBank switch only supports site "taobao"');return cdpSwitchWithPasswordlessCredentials(cdpSession2,pageSession,havanaId,ssoKey)}let account=await cdpResolveTdbankAccount(cdpSession2,pageSession,data);return cdpSwitchTdbankAccount(cdpSession2,pageSession,{id:account.id,havanaId:account.havanaId??account.id,site:account.site,loginId:account.loginId})}if(operation==="borrow"){let query=String(data?.query??"").trim();if(!query)throw new Error("query is required for TDBank borrow");let account=await cdpBorrowAndResolveTdbankAccount(cdpSession2,pageSession,query),{havanaId,site}=account,switchResult=await cdpSwitchTdbankAccount(cdpSession2,pageSession,{havanaId,site,loginId:account.loginId});return{account:sanitizeTdbankSecrets(account),switchResult}}throw new Error(`Unknown TDBank operation: ${operation}`)}registerActions([{name:"tdbank_account",session:"browser",handler:cdpTdbankAccount}]);function currentCapture(pageSession){return{tabId:pageSession.tabId,cursor:captureCheckpoint(pageSession.buffers.capture),timestampMs:Date.now(),captureStatus:pageSession.buffers.capture.currentSequence===0?"armed":"active"}}async function cdpTabOpen(session,data,controlSource="local"){let{url:url2,active=!1,emulation,reuse="never",match,appProfile}=data;if(!url2||typeof url2!="string")throw new Error("Invalid url: url must be a non-empty string");if(!["never","prefer","require"].includes(reuse))throw new Error('Invalid reuse: expected "never", "prefer", or "require"');if(data.os!==void 0&&data.os!=="ios"&&data.os!=="android")throw new Error('Invalid os: expected "ios" or "android"');if(data.os!==void 0&&!appProfile)throw new Error("tab_open os requires appProfile.");if(data.bridgeConfig!==void 0&&!appProfile)throw new Error("tab_open bridgeConfig requires appProfile.");let resolvedProfile=appProfile?resolveCdpAppProfile(appProfile,{os:data.os,simulateSystemBars:data.simulateSystemBars,bridgeConfig:data.bridgeConfig,emulation}):void 0,emulationConfig=resolvedProfile?.emulation??(emulation?resolveEmulationConfig({...emulation,enabled:!0}):void 0),browserClient=await session.getBrowserClient();if(reuse!=="never"){let pages=((await browserClient.sendCommand("Target.getTargets")).targetInfos??[]).filter(target=>target.type==="page"&&!target.url.startsWith("chrome-extension://")&&!target.url.startsWith("about:")&&!target.url.startsWith("chrome://")),existing=selectMatchingTab(pages,url2,match);if(existing){if(emulation||appProfile)throw new Error("tab_open cannot apply pre-navigation emulation or appProfile to a reused tab.");active&&await browserClient.sendCommand("Target.activateTarget",{targetId:existing.targetId});let tabId2=await session.ensureTargetRegistered(existing.targetId),pageSession2=await session.getPageSession(tabId2);await ensureControlledIndicator(pageSession2,controlSource);let capture2=currentCapture(pageSession2);return{tabId:tabId2,url:existing.url??url2,title:existing.title??"",opened:!1,reused:!0,capture:capture2}}if(reuse==="require")throw new Error('tab_open did not find a matching existing tab and reuse is "require".')}let targetId=(await browserClient.sendCommand("Target.createTarget",{url:"about:blank",background:!active})).targetId,tabId=await session.registerTarget(targetId),pageSession=await session.getPageSession(tabId);await ensureControlledIndicator(pageSession,controlSource);let capture=currentCapture(pageSession);if(resolvedProfile)await applyResolvedCdpAppProfile(pageSession,resolvedProfile);else if(emulationConfig){for(let{method,params,optional:optional2}of buildEnableEmulationCommands(emulationConfig))await pageSession.client.sendCommand(method,params).catch(error48=>{if(!optional2)throw error48});pageSession.emulation={mobile:emulationConfig.mobile,touch:emulationConfig.touch}}await pageSession.client.sendCommand("Page.navigate",{url:url2}),resolvedProfile?await waitForCdpAppProfileLoad(pageSession):await waitForPageLoad(pageSession,3e4);let targetInfo=await browserClient.sendCommand("Target.getTargetInfo",{targetId}).then(result2=>result2.targetInfo).catch(()=>null);return{tabId,url:targetInfo?.url??url2,title:targetInfo?.title??"",opened:!0,reused:!1,capture,...emulationConfig&&{emulation:{preset:emulationConfig.presetName,viewport:{width:emulationConfig.width,height:emulationConfig.height,deviceScaleFactor:emulationConfig.deviceScaleFactor},userAgent:emulationConfig.userAgent,mobile:emulationConfig.mobile,touch:emulationConfig.touch,orientation:emulationConfig.orientation}},...resolvedProfile&&{appProfile:{profile:resolvedProfile.profile.profile,label:resolvedProfile.profile.label,userAgent:resolvedProfile.profile.ua,os:resolvedProfile.profile.injected.platform==="Android"?"android":"ios",simulateSystemBars:resolvedProfile.profile.injected.simulateSystemBars!==!1}}}}async function cdpTabClose(session,data){let{tabId}=data;if(typeof tabId!="number")throw new Error("Invalid tabId: tabId must be a number");let browserClient=await session.getBrowserClient(),pageSession=await session.getPageSession(tabId);return await browserClient.sendCommand("Target.closeTarget",{targetId:pageSession.targetId}),{success:!0}}async function cdpTabList(session,_data){let pages=((await(await session.getBrowserClient()).sendCommand("Target.getTargets")).targetInfos??[]).filter(t=>t.type==="page"&&!t.url.startsWith("chrome-extension://")&&!t.url.startsWith("about:")&&!t.url.startsWith("chrome://")),tabs=await Promise.all(pages.map(async t=>{let tabId=await session.ensureTargetRegistered(t.targetId);return{id:tabId,tabId,url:t.url,title:t.title??"",active:!1}}));return{tabs,count:tabs.length}}registerActions([{name:"tab_open",session:"browser",handler:cdpTabOpen},{name:"tab_close",session:"browser",handler:cdpTabClose},{name:"tab_list",session:"browser",handler:cdpTabList}]);var GET_DRAG_COORDS_FROM_NODE_SRC=getDragCoordsFromNode.toString();function resolveSnapshotRef(session,ref){let entry=resolvePageRef(session,ref);if(!entry)throw new PageActionPreconditionError(`Ref ${ref} not found. Run page_snapshot first to get fresh refs.`);return entry}async function withSnapshotRef(session,ref,operation){let entry=resolveSnapshotRef(session,ref);try{return await operation(entry)}catch(error48){throw deletePageRef(session,ref),error48}}async function clickBySelectorJs(session,selector){let value=(await session.client.sendCommand("Runtime.evaluate",{expression:`(() => {
|
|
1185
|
+
})()`,returnByValue:!0,awaitPromise:!0});if(evaluation.exceptionDetails)throw new Error(evaluation.exceptionDetails.exception?.description??evaluation.exceptionDetails.text??"TDBank identity selection failed");let result=evaluation.result?.value;if(!result?.success)throw new Error(result?.error||"TDBank identity selection failed");return result.next?.action!=="redirect"||!result.next.data?.url?{loginStatus:"verification_required",tabId:pageSession.tabId,identity:identity2,nextAction:result.next?.action??"unknown"}:cdpFinalizeTdbankQrLogin(pageSession,result.next.data.url,identity2)}async function cdpContinueTdbankQrLogin(cdpSession2,data){if(typeof data.tabId!="number")return cdpOpenTdbankQrLogin(cdpSession2);let pageSession=await cdpSession2.getPageSession(data.tabId),requests=pageSession.buffers.requests,prompt=findLatestTdbankLoginIdentityPrompt(requests);if(prompt){let identityId=String(data.identityId??"").trim();return identityId?cdpSubmitTdbankLoginIdentity(pageSession,prompt,identityId):{loginStatus:"identity_required",tabId:data.tabId,identities:prompt.identities}}let continuation=findLatestTdbankLoginContinuation(requests);if(continuation?.action==="redirect"&&continuation.redirectUrl)return await cdpWaitForTdbankLoginAccountCount(pageSession)===null?{loginStatus:"verification_required",tabId:data.tabId,nextAction:"redirect"}:authenticatedTdbankLoginResult(data.tabId);if(continuation&&continuation.action!=="switchIdentity")return{loginStatus:"verification_required",tabId:data.tabId,nextAction:continuation.action};if(data.identityId!==void 0)throw new Error("TDBank login identities are not available yet; retry after scanning the QR code");let check2=findLatestTdbankLoginQrCheck(requests),loginStatus=check2?.status??"waiting_for_scan",qrcode=loginStatus==="waiting_for_scan"?findLatestTdbankLoginQrCode(requests):null;return loginStatus==="waiting_for_scan"&&!qrcode?cdpOpenTdbankQrLogin(cdpSession2):{loginStatus,tabId:data.tabId,...qrcode?{qrcodeImageUrl:buildTdbankQrImageUrl(qrcode.qrcode)}:{},...check2?.message?{message:check2.message}:{}}}async function cdpSwitchWithPasswordlessCredentials(cdpSession2,pageSession,havanaId,ssoKey){let previousNickname=await cdpGetTracknick(pageSession),page=await cdpOpenAndCloseTarget(cdpSession2,buildTdbankPasswordlessSsoUrl(havanaId,ssoKey),!0),businessError=page?.bodyText.match(/apiSso\+exception[^\n]*/)?.[0];if(businessError)throw new Error(`TDBank passwordless switch failed: ${businessError}`);if(page?.finalUrl){let finalHost=new URL(page.finalUrl).hostname;if(finalHost==="err.taobao.com"||finalHost==="error.taobao.com")throw new Error("TDBank passwordless switch failed: TDBank redirected to an error page")}let nickname=await cdpWaitForTracknick(pageSession,{previous:previousNickname});if(!nickname)throw new Error("TDBank passwordless switch failed: no test-account login was established");return{loginMethod:"passwordless",havanaId:String(havanaId),nickname}}async function refreshTdbankLogin(cdpSession2){let existing=tdbankLoginAttempts.get(cdpSession2);if(existing)return existing;let attempt=cdpOpenAndCloseTarget(cdpSession2,TDBANK_ORIGIN).then(()=>{}).finally(()=>{tdbankLoginAttempts.get(cdpSession2)===attempt&&tdbankLoginAttempts.delete(cdpSession2)});return tdbankLoginAttempts.set(cdpSession2,attempt),attempt}async function cdpFetchTdbank(cdpSession2,session,path23,options={}){try{return await cdpFetchTdbankRequest(session,path23,options)}catch(error48){if(!(error48 instanceof TdbankLoginRequiredError))throw error48}return await refreshTdbankLogin(cdpSession2),cdpFetchTdbankRequest(session,path23,options)}async function cdpFetchTdbankAccounts(cdpSession2,pageSession,pageIndex=1){let data=sanitizeTdbankSecrets(await cdpFetchTdbank(cdpSession2,pageSession,"/findPagedUsingAccountsByUser.do",{params:{_input_charset:"utf-8",pageIndex,searchKey:"",searchVal:""}}));return{...data,accountList:Array.isArray(data?.accountList)?data.accountList:[]}}async function cdpSwitchTdbankAccount(cdpSession2,pageSession,account){let previousNickname=await cdpGetTracknick(pageSession),ssoUrl=await cdpFetchTdbank(cdpSession2,pageSession,"/accountSso.do",{params:{_input_charset:"utf-8"},formBody:{havanaId:String(account.havanaId),site:String(account.site)}});await cdpOpenAndCloseTarget(cdpSession2,String(ssoUrl));let nickname=await cdpWaitForTracknick(pageSession,{previous:account.loginId?previousNickname:"",expected:account.loginId});return{...account.id!==void 0?{accountId:String(account.id)}:{},nickname}}async function cdpCreateTdbankSsoUrl(cdpSession2,pageSession,account){return String(await cdpFetchTdbank(cdpSession2,pageSession,"/accountSso.do",{params:{_input_charset:"utf-8"},formBody:{havanaId:String(account.havanaId),site:String(account.site)}}))}async function cdpResolveTdbankAccount(cdpSession2,pageSession,data){if(data.accountId!==void 0){let account=(await cdpFetchTdbankAccounts(cdpSession2,pageSession,1)).accountList.find(account2=>String(account2.id)===String(data.accountId));if(!account)throw new Error(`TDBank account not found: ${data.accountId}`);if(account.site===void 0||account.site===null)throw new Error(`TDBank account ${data.accountId} has no site`);return account}if(data.havanaId!==void 0&&data.site!==void 0)return{id:data.havanaId,havanaId:data.havanaId,site:data.site};throw new Error("accountId or havanaId + site is required")}async function cdpBorrowAndResolveTdbankAccount(cdpSession2,pageSession,query){let searchResult=await cdpFetchTdbank(cdpSession2,pageSession,"/searchAccountByInputV2.do",{params:{_input_charset:"utf-8",loginId:query,site:0}});if(!Array.isArray(searchResult)||searchResult.length===0)throw new Error(`No TDBank account found for: ${query}`);let account=searchResult[0],{havanaId,accountBucId,site}=account;if(!havanaId||!accountBucId||site===void 0||site===null)throw new Error("TDBank search result is missing havanaId/accountBucId/site");try{await cdpFetchTdbank(cdpSession2,pageSession,"/quickApplyAccountV2.do",{params:{_input_charset:"utf-8",accountBucId,accreditType:7,havanaId,site}})}catch(error48){if(!(error48 instanceof Error?error48.message:String(error48)).includes("厞įģåį¨"))throw error48}return account}async function cdpPrepareTdbankSso(cdpSession2,data){let pageSession=await cdpSession2.getPageSession(typeof data?.tabId=="number"?data.tabId:void 0),query=String(data?.query??"").trim(),account=query?await cdpBorrowAndResolveTdbankAccount(cdpSession2,pageSession,query):await cdpResolveTdbankAccount(cdpSession2,pageSession,data),havanaId=account.havanaId??account.id;return{ssoUrl:await cdpCreateTdbankSsoUrl(cdpSession2,pageSession,{havanaId,site:account.site}),account:{accountId:account.id!==void 0?String(account.id):void 0,havanaId:String(havanaId),site:String(account.site),loginId:data.havanaId===void 0&&account.loginId?String(account.loginId):void 0}}}async function cdpConsumeTdbankSso(cdpSession2,ssoUrl,expectedLoginId){let browser=await cdpSession2.getBrowserClient(),{targetId}=await browser.sendCommand("Target.createTarget",{url:ssoUrl,background:!0});try{let tabId=await cdpSession2.registerTarget(targetId),pageSession=await cdpSession2.getPageSession(tabId),nickname=await cdpWaitForTracknick(pageSession,{expected:expectedLoginId,timeoutMs:15e3});if(!nickname)throw new Error("TDBank SSO completed without a tracknick cookie");if(expectedLoginId&&nickname!==expectedLoginId)throw new Error(`TDBank SSO account mismatch: expected ${expectedLoginId}, got ${nickname}`);return{nickname}}finally{await browser.sendCommand("Target.closeTarget",{targetId}).catch(()=>{})}}async function cdpTdbankAccount(cdpSession2,data){let operation=data?.operation??"current";if(operation==="login")return cdpContinueTdbankQrLogin(cdpSession2,data);let pageSession=await cdpSession2.getPageSession(typeof data?.tabId=="number"?data.tabId:void 0);if(operation==="current"){let nickname=await cdpGetTracknick(pageSession),account=null;if(nickname)try{account=(await cdpFetchTdbankAccounts(cdpSession2,pageSession,1)).accountList.find(account2=>account2.loginId===nickname)??null}catch(error48){if(error48 instanceof TdbankLoginRequiredError)throw error48;account=null}return{nickname,account,source:"cdp"}}if(operation==="list")return{...await cdpFetchTdbankAccounts(cdpSession2,pageSession,data?.pageIndex??1),nickname:await cdpGetTracknick(pageSession),source:"cdp"};if(operation==="switch"){if(data.ssoKey!==void 0){let havanaId=String(data.havanaId??"").trim(),ssoKey=data.ssoKey?.trim();if(!havanaId||!ssoKey)throw new Error("havanaId and ssoKey are both required for passwordless TDBank switch");if(data.accountId!==void 0)throw new Error("havanaId + ssoKey cannot be combined with accountId");if(data.site!==void 0&&String(data.site)!=="taobao")throw new Error('passwordless TDBank switch only supports site "taobao"');return cdpSwitchWithPasswordlessCredentials(cdpSession2,pageSession,havanaId,ssoKey)}let account=await cdpResolveTdbankAccount(cdpSession2,pageSession,data);return cdpSwitchTdbankAccount(cdpSession2,pageSession,{id:account.id,havanaId:account.havanaId??account.id,site:account.site,loginId:account.loginId})}if(operation==="borrow"){let query=String(data?.query??"").trim();if(!query)throw new Error("query is required for TDBank borrow");let account=await cdpBorrowAndResolveTdbankAccount(cdpSession2,pageSession,query),{havanaId,site}=account,switchResult=await cdpSwitchTdbankAccount(cdpSession2,pageSession,{havanaId,site,loginId:account.loginId});return{account:sanitizeTdbankSecrets(account),switchResult}}throw new Error(`Unknown TDBank operation: ${operation}`)}registerActions([{name:"tdbank_account",session:"browser",handler:cdpTdbankAccount}]);function currentCapture(pageSession){return{tabId:pageSession.tabId,cursor:captureCheckpoint(pageSession.buffers.capture),timestampMs:Date.now(),captureStatus:pageSession.buffers.capture.currentSequence===0?"armed":"active"}}async function cdpTabOpen(session,data,controlSource="local"){let{url:url2,active=!1,emulation,reuse="never",match,appProfile}=data;if(!url2||typeof url2!="string")throw new Error("Invalid url: url must be a non-empty string");if(!["never","prefer","require"].includes(reuse))throw new Error('Invalid reuse: expected "never", "prefer", or "require"');if(data.os!==void 0&&data.os!=="ios"&&data.os!=="android")throw new Error('Invalid os: expected "ios" or "android"');if(data.os!==void 0&&!appProfile)throw new Error("tab_open os requires appProfile.");if(data.bridgeConfig!==void 0&&!appProfile)throw new Error("tab_open bridgeConfig requires appProfile.");let resolvedProfile=appProfile?resolveCdpAppProfile(appProfile,{os:data.os,devicePreset:emulation?.preset,orientation:emulation?.orientation,bridgeConfig:data.bridgeConfig}):void 0,emulationConfig=emulation?resolveEmulationConfig({...emulation,enabled:!0}):void 0,browserClient=await session.getBrowserClient();if(reuse!=="never"){let pages=((await browserClient.sendCommand("Target.getTargets")).targetInfos??[]).filter(target=>target.type==="page"&&!target.url.startsWith("chrome-extension://")&&!target.url.startsWith("about:")&&!target.url.startsWith("chrome://")),existing=selectMatchingTab(pages,url2,match);if(existing){if(emulation||appProfile)throw new Error("tab_open cannot apply pre-navigation emulation or appProfile to a reused tab.");active&&await browserClient.sendCommand("Target.activateTarget",{targetId:existing.targetId});let tabId2=await session.ensureTargetRegistered(existing.targetId),pageSession2=await session.getPageSession(tabId2);await ensureControlledIndicator(pageSession2,controlSource);let capture2=currentCapture(pageSession2);return{tabId:tabId2,url:existing.url??url2,title:existing.title??"",opened:!1,reused:!0,capture:capture2}}if(reuse==="require")throw new Error('tab_open did not find a matching existing tab and reuse is "require".')}let targetId=(await browserClient.sendCommand("Target.createTarget",{url:"about:blank",background:!active})).targetId,tabId=await session.registerTarget(targetId),pageSession=await session.getPageSession(tabId);await ensureControlledIndicator(pageSession,controlSource);let capture=currentCapture(pageSession);if(emulationConfig){for(let{method,params,optional:optional2}of buildEnableEmulationCommands(emulationConfig))await pageSession.client.sendCommand(method,params).catch(error48=>{if(!optional2)throw error48});pageSession.emulation={mobile:emulationConfig.mobile,touch:emulationConfig.touch,config:emulationConfig,deviceShell:emulation?.deviceShell===!0},emulation?.deviceShell&&await applyCdpDeviceShell(pageSession,emulationConfig)}resolvedProfile&&await applyResolvedCdpAppProfile(pageSession,resolvedProfile),await pageSession.client.sendCommand("Page.navigate",{url:url2}),emulation?.deviceShell?await waitForCdpDeviceShellLoad(pageSession):resolvedProfile?await waitForCdpAppProfileLoad(pageSession):await waitForPageLoad(pageSession,3e4);let targetInfo=await browserClient.sendCommand("Target.getTargetInfo",{targetId}).then(result2=>result2.targetInfo).catch(()=>null);return{tabId,url:targetInfo?.url??url2,title:targetInfo?.title??"",opened:!0,reused:!1,capture,...emulationConfig&&{emulation:{preset:emulationConfig.presetName,viewport:{width:emulationConfig.width,height:emulationConfig.height,deviceScaleFactor:emulationConfig.deviceScaleFactor,scale:emulationConfig.scale??1},userAgent:emulationConfig.userAgent,mobile:emulationConfig.mobile,touch:emulationConfig.touch,orientation:emulationConfig.orientation,deviceShell:emulation?.deviceShell===!0}},...resolvedProfile&&{appProfile:{profile:resolvedProfile.profile.profile,label:resolvedProfile.profile.label,userAgent:resolvedProfile.profile.ua,os:resolvedProfile.profile.injected.platform==="Android"?"android":"ios"}}}}async function cdpTabClose(session,data){let{tabId}=data;if(typeof tabId!="number")throw new Error("Invalid tabId: tabId must be a number");let browserClient=await session.getBrowserClient(),pageSession=await session.getPageSession(tabId);return await browserClient.sendCommand("Target.closeTarget",{targetId:pageSession.targetId}),{success:!0}}async function cdpTabList(session,_data){let pages=((await(await session.getBrowserClient()).sendCommand("Target.getTargets")).targetInfos??[]).filter(t=>t.type==="page"&&!t.url.startsWith("chrome-extension://")&&!t.url.startsWith("about:")&&!t.url.startsWith("chrome://")),tabs=await Promise.all(pages.map(async t=>{let tabId=await session.ensureTargetRegistered(t.targetId);return{id:tabId,tabId,url:t.url,title:t.title??"",active:!1}}));return{tabs,count:tabs.length}}registerActions([{name:"tab_open",session:"browser",handler:cdpTabOpen},{name:"tab_close",session:"browser",handler:cdpTabClose},{name:"tab_list",session:"browser",handler:cdpTabList}]);var GET_DRAG_COORDS_FROM_NODE_SRC=getDragCoordsFromNode.toString();function resolveSnapshotRef(session,ref){let entry=resolvePageRef(session,ref);if(!entry)throw new PageActionPreconditionError(`Ref ${ref} not found. Run page_snapshot first to get fresh refs.`);return entry}async function withSnapshotRef(session,ref,operation){let entry=resolveSnapshotRef(session,ref);try{return await operation(entry)}catch(error48){throw deletePageRef(session,ref),error48}}async function clickBySelectorJs(session,selector){let value=(await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:`(() => {
|
|
892
1186
|
const sel = ${JSON.stringify(selector)};
|
|
893
1187
|
const el = document.querySelector(sel);
|
|
894
1188
|
if (!el) return { clicked: false, error: 'Element not found: ' + sel };
|
|
@@ -907,38 +1201,38 @@ Content-Type: ${file2.contentType}\r
|
|
|
907
1201
|
: {}),
|
|
908
1202
|
...(r.controlState ? { controlState: r.controlState } : {})
|
|
909
1203
|
};
|
|
910
|
-
})()`,returnByValue:!0})).result?.value;if(!value)throw new Error("click evaluation returned no value");if(value.error)throw new PageActionPreconditionError(value.error);return{...value,dispatchMode:"dom"}}async function clickByBackendNodeJs(session,backendNodeId){let objectId=await resolveBackendNodeObjectId(session,backendNodeId),value=(await session
|
|
1204
|
+
})()`,returnByValue:!0})).result?.value;if(!value)throw new Error("click evaluation returned no value");if(value.error)throw new PageActionPreconditionError(value.error);return{...value,dispatchMode:"dom"}}async function clickByBackendNodeJs(session,backendNodeId){let objectId=await resolveBackendNodeObjectId(session,backendNodeId),value=(await sendCdpDeviceShellPageCommand(session,"Runtime.callFunctionOn",{objectId,functionDeclaration:CLICK_ELEMENT_VIA_JS_SRC,returnByValue:!0})).result?.value;if(value===null)throw new PageActionPreconditionError("Cannot resolve clickable element");if(!value)throw new Error("click evaluation returned no value");return{tag:value.tag,text:value.text,sourceTarget:value.sourceTarget,strategy:value.strategy,distance:value.distance,...value.actionableAncestorCandidates?{actionableAncestorCandidates:value.actionableAncestorCandidates}:{},dispatchMode:"dom",...value.controlState?{controlState:value.controlState}:{}}}async function clickByPointJs(session,point){let value=(await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:`(() => {
|
|
911
1205
|
const element = document.elementFromPoint(${JSON.stringify(point.x)}, ${JSON.stringify(point.y)});
|
|
912
1206
|
if (!element) return null;
|
|
913
1207
|
return (${CLICK_ELEMENT_VIA_JS_SRC}).call(element);
|
|
914
|
-
})()`,returnByValue:!0})).result?.value;if(value===null)throw new PageActionPreconditionError(`page_click: no element found at point (${point.x}, ${point.y}) in the current viewport.`);if(!value)throw new Error("click evaluation returned no value");return{tag:value.tag,text:value.text,sourceTarget:value.sourceTarget,strategy:value.strategy,distance:value.distance,...value.actionableAncestorCandidates?{actionableAncestorCandidates:value.actionableAncestorCandidates}:{},dispatchMode:"dom",...value.controlState?{controlState:value.controlState}:{}}}function isNativeToggleControl(role,inputType){return/^(checkbox|radio)$/i.test(role??"")||/^(checkbox|radio)$/i.test(inputType??"")}async function prefersTouchInput(session){return session.emulation?session.emulation.touch:(await session
|
|
1208
|
+
})()`,returnByValue:!0})).result?.value;if(value===null)throw new PageActionPreconditionError(`page_click: no element found at point (${point.x}, ${point.y}) in the current viewport.`);if(!value)throw new Error("click evaluation returned no value");return{tag:value.tag,text:value.text,sourceTarget:value.sourceTarget,strategy:value.strategy,distance:value.distance,...value.actionableAncestorCandidates?{actionableAncestorCandidates:value.actionableAncestorCandidates}:{},dispatchMode:"dom",...value.controlState?{controlState:value.controlState}:{}}}function isNativeToggleControl(role,inputType){return/^(checkbox|radio)$/i.test(role??"")||/^(checkbox|radio)$/i.test(inputType??"")}async function prefersTouchInput(session){return session.emulation?session.emulation.touch:(await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:`navigator.maxTouchPoints > 0 && (
|
|
915
1209
|
Boolean(navigator.userAgentData && navigator.userAgentData.mobile) ||
|
|
916
1210
|
/Android|Mobi|iPhone|iPad|iPod/i.test(navigator.userAgent)
|
|
917
|
-
)`,returnByValue:!0})).result?.value===!0}async function getElementCoordsBySelector(session,selector){let value=(await session
|
|
1211
|
+
)`,returnByValue:!0})).result?.value===!0}async function getElementCoordsBySelector(session,selector){let value=(await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:`(() => {
|
|
918
1212
|
const el = document.querySelector(${JSON.stringify(selector)});
|
|
919
1213
|
if (!el) return { error: 'Element not found: ' + ${JSON.stringify(selector)} };
|
|
920
1214
|
const fn = (${GET_CLICK_COORDS_FROM_NODE_SRC});
|
|
921
1215
|
const r = fn.call(el);
|
|
922
1216
|
if (!r) return { error: 'Cannot resolve element coordinates' };
|
|
923
1217
|
return r;
|
|
924
|
-
})()`,returnByValue:!0})).result?.value;if(!value)throw new Error("coord evaluation returned no value");if(value.error)throw new PageActionPreconditionError(value.error);return value}async function getElementCoordsByBackendNodeId(session,backendNodeId){let objectId=await resolveBackendNodeObjectId(session,backendNodeId),value=(await session
|
|
925
|
-
${candidates}`)}let hit=hits[0],dispatchTarget;if(effectiveClickMode==="dom"||policy.stateAwareControls&&isNativeToggleControl(hit.role))dispatchTarget=await clickByBackendNodeJs(session,hit.backendNodeId);else{let coord=await getElementCoordsByBackendNodeId(session,hit.backendNodeId);await dispatchCdpClick(session,coord.x,coord.y,effectiveClickMode),dispatchTarget={...coord,dispatchMode:"trusted-input",pointerType:effectiveClickMode}}return finalize2(createPageClickResult({kind:"text",name:hit.name,role:hit.role||void 0,...scope?{scope}:{}},dispatchTarget))}if(!point)throw new PageActionPreconditionError("page_click point is required");if(effectiveClickMode==="dom"){let dispatchTarget=await clickByPointJs(session,point);return finalize2(createPageClickResult({kind:"point",point},dispatchTarget))}return await dispatchCdpClick(session,point.x,point.y,effectiveClickMode),finalize2(createPageClickResult({kind:"point",point},{tag:"",text:"",dispatchMode:"trusted-input",pointerType:effectiveClickMode}))}async function scrollDragSourceIntoView(session,endpoint){if(typeof endpoint!="string")return;if(validatePageElementSelector(endpoint,"page_drag from"),endpoint.startsWith("@e")){let entry=resolveSnapshotRef(session,endpoint),objectId=await resolveBackendNodeObjectId(session,entry.backendNodeId);await session
|
|
1218
|
+
})()`,returnByValue:!0})).result?.value;if(!value)throw new Error("coord evaluation returned no value");if(value.error)throw new PageActionPreconditionError(value.error);return value}async function getElementCoordsByBackendNodeId(session,backendNodeId){let objectId=await resolveBackendNodeObjectId(session,backendNodeId),value=(await sendCdpDeviceShellPageCommand(session,"Runtime.callFunctionOn",{objectId,functionDeclaration:GET_CLICK_COORDS_FROM_NODE_SRC,returnByValue:!0})).result?.value;if(value===null)throw new PageActionPreconditionError(`Cannot resolve clickable element for backendNodeId ${backendNodeId}`);if(!value)throw new Error("coord evaluation returned no value");return value}async function resolveScopeBackendNodeId(session,scope){if(checkPageActionPrecondition(()=>validatePageElementSelector(scope,"page_click scope")),scope.startsWith("@e"))return resolveSnapshotRef(session,scope).backendNodeId;let evaluated=await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:`document.querySelector(${JSON.stringify(scope)})`,returnByValue:!1});if(evaluated.exceptionDetails){let message=evaluated.exceptionDetails.exception?.description??evaluated.exceptionDetails.text??"invalid selector";throw new PageActionPreconditionError(`page_click: invalid scope "${scope}": ${message}`)}let objectId=evaluated.result?.objectId;if(!objectId||evaluated.result?.subtype==="null")throw new PageActionPreconditionError(`page_click: scope not found: ${scope}`);try{let backendNodeId=(await sendCdpDeviceShellPageCommand(session,"DOM.describeNode",{objectId})).node?.backendNodeId;if(backendNodeId===void 0)throw new PageActionPreconditionError(`page_click: cannot resolve scope: ${scope}`);return backendNodeId}finally{await sendCdpDeviceShellPageCommand(session,"Runtime.releaseObject",{objectId}).catch(()=>{})}}async function cdpPageClick(session,data){let{selector,text,role,exact,scope,clickMode,point,frameId,coordinateSpace}=data??{},hasSelector=typeof selector=="string"&&selector.length>0,hasText=typeof text=="string"&&text.length>0,hasPoint=point&&Number.isFinite(point.x)&&Number.isFinite(point.y)&&point.x>=0&&point.y>=0,provided=[hasSelector&&"selector",hasText&&"text",hasPoint&&"point"].filter(Boolean);if(clickMode!==void 0&&!["auto","dom","mouse","touch"].includes(clickMode))throw new PageActionPreconditionError('page_click: "clickMode" must be one of auto, dom, mouse, touch');if(scope!==void 0&&!hasText)throw new PageActionPreconditionError('page_click: "scope" is only supported with the "text" target');if(coordinateSpace!==void 0&&!["outer-viewport","active-frame"].includes(coordinateSpace))throw new PageActionPreconditionError('page_click: "coordinateSpace" must be one of outer-viewport, active-frame');if(coordinateSpace!==void 0&&!hasPoint)throw new PageActionPreconditionError('page_click: "coordinateSpace" is only supported with the "point" target');if(frameId!==void 0||coordinateSpace==="active-frame")throw new PageActionPreconditionError("page_click: frameId and active-frame coordinates require the browser extension backend");if(scope!==void 0&&checkPageActionPrecondition(()=>validatePageElementSelector(scope,"page_click scope")),hasSelector&&checkPageActionPrecondition(()=>validatePageElementSelector(selector,"page_click")),provided.length===0)throw new PageActionPreconditionError('page_click: provide exactly one of "selector", "text", or "point". For text matching, pass "text" (and optionally "role"/"exact"). For coordinate clicks, pass "point": { x, y } in viewport pixels.');if(provided.length>1)throw new PageActionPreconditionError(`page_click: provide exactly one of "selector", "text", or "point" â got ${provided.length} (${provided.join(", ")}).`);let requestedMode=clickMode??"auto",[visibilityResult,touchEmulationEnabled]=requestedMode==="auto"?await Promise.all([sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:"document.visibilityState",returnByValue:!0}),prefersTouchInput(session)]):[void 0,!1],policy=resolvePageClickDispatchPolicy(requestedMode,visibilityResult?.result?.value,touchEmulationEnabled),effectiveClickMode=policy.clickMode,finalize2=result=>policy.fallbackReason?{...result,fallbackReason:policy.fallbackReason}:result;if(hasSelector){if(selector.startsWith("@e")){let ref=selector,result=await withSnapshotRef(session,ref,async entry=>{let dispatchTarget2;if(effectiveClickMode==="dom"||policy.stateAwareControls&&isNativeToggleControl(entry.role))dispatchTarget2=await clickByBackendNodeJs(session,entry.backendNodeId);else{let coord=await getElementCoordsByBackendNodeId(session,entry.backendNodeId);policy.stateAwareControls&&isNativeToggleControl(void 0,coord.inputType)?dispatchTarget2=await clickByBackendNodeJs(session,entry.backendNodeId):(await dispatchCdpClick(session,coord.x,coord.y,effectiveClickMode),dispatchTarget2={...coord,dispatchMode:"trusted-input",pointerType:effectiveClickMode})}return createPageClickResult({kind:"ref",selector:ref,role:entry.role,name:entry.name},dispatchTarget2)});return finalize2(result)}if(effectiveClickMode!=="dom"){let coord=await getElementCoordsBySelector(session,selector);if(policy.stateAwareControls&&isNativeToggleControl(void 0,coord.inputType)){let dispatchTarget2=await clickBySelectorJs(session,selector);return finalize2(createPageClickResult({kind:"selector",selector},dispatchTarget2))}return await dispatchCdpClick(session,coord.x,coord.y,effectiveClickMode),finalize2(createPageClickResult({kind:"selector",selector},{...coord,dispatchMode:"trusted-input",pointerType:effectiveClickMode}))}let dispatchTarget=await clickBySelectorJs(session,selector);return finalize2(createPageClickResult({kind:"selector",selector},dispatchTarget))}if(hasText){let scopeBackendNodeId=scope?await resolveScopeBackendNodeId(session,scope):void 0,nodes=(await sendCdpDeviceShellPageCommand(session,scopeBackendNodeId===void 0?"Accessibility.getFullAXTree":"Accessibility.queryAXTree",scopeBackendNodeId===void 0?{}:{backendNodeId:scopeBackendNodeId})).nodes??[],{hits}=matchAXNodesByText(nodes,{text,role,exact});if(hits.length===0){let exactSuffix=exact===!1?" (substring match)":"",roleSuffix=role?` with role "${role}"`:"";throw new PageActionPreconditionError(`page_click: text "${text}"${roleSuffix}${exactSuffix}${scope?` in scope "${scope}"`:""} not found. Run page_snapshot to inspect the page, or try exact: false for substring matching.`)}if(hits.length>1){let candidates=formatAXTextMatchCandidates(hits);throw new PageActionPreconditionError(`page_click: text "${text}"${scope?` in scope "${scope}"`:""} matched ${hits.length} elements. Refine with "role" or "exact: true", or run page_snapshot and use an "@eN" ref:
|
|
1219
|
+
${candidates}`)}let hit=hits[0],dispatchTarget;if(effectiveClickMode==="dom"||policy.stateAwareControls&&isNativeToggleControl(hit.role))dispatchTarget=await clickByBackendNodeJs(session,hit.backendNodeId);else{let coord=await getElementCoordsByBackendNodeId(session,hit.backendNodeId);await dispatchCdpClick(session,coord.x,coord.y,effectiveClickMode),dispatchTarget={...coord,dispatchMode:"trusted-input",pointerType:effectiveClickMode}}return finalize2(createPageClickResult({kind:"text",name:hit.name,role:hit.role||void 0,...scope?{scope}:{}},dispatchTarget))}if(!point)throw new PageActionPreconditionError("page_click point is required");if(effectiveClickMode==="dom"){let dispatchTarget=await clickByPointJs(session,point);return finalize2(createPageClickResult({kind:"point",point},dispatchTarget))}return await dispatchCdpClick(session,point.x,point.y,effectiveClickMode),finalize2(createPageClickResult({kind:"point",point},{tag:"",text:"",dispatchMode:"trusted-input",pointerType:effectiveClickMode}))}async function scrollDragSourceIntoView(session,endpoint){if(typeof endpoint!="string")return;if(validatePageElementSelector(endpoint,"page_drag from"),endpoint.startsWith("@e")){let entry=resolveSnapshotRef(session,endpoint),objectId=await resolveBackendNodeObjectId(session,entry.backendNodeId);await sendCdpDeviceShellPageCommand(session,"Runtime.callFunctionOn",{objectId,functionDeclaration:`function() {
|
|
926
1220
|
const el = this.nodeType === Node.TEXT_NODE ? this.parentElement : this;
|
|
927
1221
|
if (!el) return false;
|
|
928
1222
|
el.scrollIntoView({ block: 'center', inline: 'center', behavior: 'instant' });
|
|
929
1223
|
return true;
|
|
930
|
-
}`,returnByValue:!0});return}let value=(await session
|
|
1224
|
+
}`,returnByValue:!0});return}let value=(await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:`(() => {
|
|
931
1225
|
const selector = ${JSON.stringify(endpoint)};
|
|
932
1226
|
const el = document.querySelector(selector);
|
|
933
1227
|
if (!el) return { error: 'Element not found: ' + selector };
|
|
934
1228
|
el.scrollIntoView({ block: 'center', inline: 'center', behavior: 'instant' });
|
|
935
1229
|
return { scrolled: true };
|
|
936
|
-
})()`,returnByValue:!0})).result?.value;if(value?.error)throw new Error(`page_drag: ${value.error}`)}function unwrapDragElementCoords(value,endpoint){if(!value)throw new Error(`page_drag: cannot resolve element coordinates for "${endpoint}"`);if(value.error)throw new Error(`page_drag: ${value.error}: "${endpoint}"`);return value}async function resolveDragEndpoint(session,endpoint){if(typeof endpoint!="string")return{requested:endpoint,point:endpoint};validatePageElementSelector(endpoint,"page_drag endpoint");let coords;if(endpoint.startsWith("@e")){let entry=resolveSnapshotRef(session,endpoint),objectId=await resolveBackendNodeObjectId(session,entry.backendNodeId),result=await session
|
|
1230
|
+
})()`,returnByValue:!0})).result?.value;if(value?.error)throw new Error(`page_drag: ${value.error}`)}function unwrapDragElementCoords(value,endpoint){if(!value)throw new Error(`page_drag: cannot resolve element coordinates for "${endpoint}"`);if(value.error)throw new Error(`page_drag: ${value.error}: "${endpoint}"`);return value}async function resolveDragEndpoint(session,endpoint){if(typeof endpoint!="string")return{requested:endpoint,point:endpoint};validatePageElementSelector(endpoint,"page_drag endpoint");let coords;if(endpoint.startsWith("@e")){let entry=resolveSnapshotRef(session,endpoint),objectId=await resolveBackendNodeObjectId(session,entry.backendNodeId),result=await sendCdpDeviceShellPageCommand(session,"Runtime.callFunctionOn",{objectId,functionDeclaration:GET_DRAG_COORDS_FROM_NODE_SRC,returnByValue:!0});coords=unwrapDragElementCoords(result.result?.value,endpoint)}else{let result=await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:`(() => {
|
|
937
1231
|
const selector = ${JSON.stringify(endpoint)};
|
|
938
1232
|
const el = document.querySelector(selector);
|
|
939
1233
|
if (!el) return { error: 'Element not found: ' + selector };
|
|
940
1234
|
return (${GET_DRAG_COORDS_FROM_NODE_SRC}).call(el);
|
|
941
|
-
})()`,returnByValue:!0});coords=unwrapDragElementCoords(result.result?.value,endpoint)}return{requested:endpoint,point:{x:coords.x,y:coords.y},tag:coords.tag,text:coords.text}}async function cdpPageDrag(session,data){let input=checkPageActionPrecondition(()=>resolvePageDragInput(data)),visibilityResult=input.dragMode==="auto"?await session
|
|
1235
|
+
})()`,returnByValue:!0});coords=unwrapDragElementCoords(result.result?.value,endpoint)}return{requested:endpoint,point:{x:coords.x,y:coords.y},tag:coords.tag,text:coords.text}}async function cdpPageDrag(session,data){let input=checkPageActionPrecondition(()=>resolvePageDragInput(data)),visibilityResult=input.dragMode==="auto"?await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:"document.visibilityState",returnByValue:!0}):void 0,touchEmulationEnabled=input.dragMode==="auto"||input.dragMode==="dom"?await prefersTouchInput(session):input.dragMode==="touch",policy=resolvePageDragDispatchPolicy(input.dragMode,visibilityResult?.result?.value,touchEmulationEnabled);await scrollDragSourceIntoView(session,input.from);let from=await resolveDragEndpoint(session,input.from),to=await resolveDragEndpoint(session,input.to);if(Math.hypot(to.point.x-from.point.x,to.point.y-from.point.y)<1)throw new Error("page_drag: resolved endpoints must be at least 1 viewport pixel apart");if(policy.dispatchMode==="dom"){let path23=buildPageDragPath(from.point,to.point,input.durationMs),result=await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:buildPageDragDomExpression(from.point,path23.points,policy.pointerType),returnByValue:!0});if(result.exceptionDetails)throw new Error(result.exceptionDetails.exception?.description??result.exceptionDetails.text??"page_drag: DOM simulation failed");let{steps:steps2}=unwrapPageDragDomResult(result.result?.value);return{dragged:!0,from,to,dispatchMode:"dom",pointerType:policy.pointerType,durationMs:input.durationMs,steps:steps2,...policy.fallbackReason?{fallbackReason:policy.fallbackReason}:{}}}let{steps}=await dispatchCdpDrag(session,from.point,to.point,policy.pointerType,input.durationMs);return{dragged:!0,from,to,dispatchMode:"trusted-input",pointerType:policy.pointerType,durationMs:input.durationMs,steps}}async function cdpPageType(session,data){let{selector,text,clearFirst=!0}=data;if(!selector||typeof selector!="string")throw new PageActionPreconditionError(`"selector" must be a non-empty string. Pass a native CSS selector (e.g. "[aria-label='æäē¤']") or a snapshot ref like "@e3". Note: the field name is "selector", not "ref".`);if(checkPageActionPrecondition(()=>validatePageElementSelector(selector,"page_type")),typeof text!="string")throw new PageActionPreconditionError('"text" must be a string.');if(selector.startsWith("@e"))return withSnapshotRef(session,selector,async entry=>{let objectId=await resolveBackendNodeObjectId(session,entry.backendNodeId),value2=(await sendCdpDeviceShellPageCommand(session,"Runtime.callFunctionOn",{objectId,functionDeclaration:`function(inputValue, shouldClear) {
|
|
942
1236
|
return (${TYPE_INTO_ELEMENT_SRC})(this, inputValue, shouldClear);
|
|
943
1237
|
}`,arguments:[{value:text},{value:clearFirst}],returnByValue:!0})).result?.value;if(!value2)throw new Error("cdp_page_type: evaluation returned no value");if(value2.error)throw new PageActionPreconditionError(value2.error);return{typed:!0,tag:value2.tag}});let expression=`((sel, v, c) => {
|
|
944
1238
|
let el;
|
|
@@ -947,7 +1241,7 @@ ${candidates}`)}let hit=hits[0],dispatchTarget;if(effectiveClickMode==="dom"||po
|
|
|
947
1241
|
if (!el) return { typed: false, tag: '', error: 'Element not found: ' + sel };
|
|
948
1242
|
const fn = (${TYPE_INTO_ELEMENT_SRC});
|
|
949
1243
|
return fn(el, v, c);
|
|
950
|
-
})(${JSON.stringify(selector)}, ${JSON.stringify(text)}, ${JSON.stringify(clearFirst)})`,value=(await session.client.sendCommand("Runtime.evaluate",{expression,returnByValue:!0})).result?.value;if(!value)throw new Error("cdp_page_type: evaluation returned no value");if(value.error)throw new PageActionPreconditionError(value.error);if(!value.typed)throw new PageActionPreconditionError("cdp_page_type: failed to type");return{typed:!0,tag:value.tag}}async function cdpPageScroll(session,data){let input=checkPageActionPrecondition(()=>resolvePageScrollInput(data??{}));if(input.selector?.startsWith("@e"))return withSnapshotRef(session,input.selector,async entry=>{let objectId=await resolveBackendNodeObjectId(session,entry.backendNodeId),result2=await session.client.sendCommand("Runtime.callFunctionOn",{objectId,functionDeclaration:SCROLL_ELEMENT_IN_PAGE_SOURCE,arguments:[{value:input.direction},{value:input.distance},{value:input.selector},{value:input.containerPolicy}],returnByValue:!0});return unwrapPageScrollResult(result2.result?.value,`Cannot resolve scroll container for ref ${input.selector}`)});let result=await session.client.sendCommand("Runtime.evaluate",{expression:buildPageScrollExpression(input),returnByValue:!0});if(result.exceptionDetails)throw new Error(result.exceptionDetails.exception?.description??result.exceptionDetails.text??"page_scroll evaluation failed");return unwrapPageScrollResult(result.result?.value,"page_scroll evaluation returned no value")}async function cdpPageEval(session,data){let{expression,awaitPromise=!0}=data;if(!expression||typeof expression!="string")throw new PageActionPreconditionError("Invalid expression");let result=await session.client.sendCommand("Runtime.evaluate",{expression,returnByValue:!0,awaitPromise});if(result.exceptionDetails)throw new Error(result.exceptionDetails.exception?.description??result.exceptionDetails.text??"Evaluation error");return{result:result.result?.value}}async function cdpPagePress(session,data){let{key}=data;if(!key||typeof key!="string")throw new PageActionPreconditionError("Invalid key");return await session.client.sendCommand("Input.dispatchKeyEvent",{type:"keyDown",key}),await session.client.sendCommand("Input.dispatchKeyEvent",{type:"keyUp",key}),{success:!0,key}}async function cdpPageWait(session,data){let options=resolvePageWaitInput(data),startedAt=Date.now();if(options.mode==="time")return await new Promise(resolve3=>setTimeout(resolve3,options.time)),{success:!0,waited:!0,elapsed:options.time,mode:options.mode};let expression=options.mode==="selector"?`!!document.querySelector(${JSON.stringify(options.selector)})`:options.condition;for(;Date.now()-startedAt<options.timeout;){let result=await session.client.sendCommand("Runtime.evaluate",{expression,returnByValue:!0,awaitPromise:options.mode==="condition"});if(result.exceptionDetails)throw new Error(result.exceptionDetails.exception?.description??result.exceptionDetails.text??`page_wait ${options.mode} evaluation failed`);let value=result.result?.value;if(value)return{success:!0,waited:!0,elapsed:Date.now()-startedAt,mode:options.mode,value};await new Promise(resolve3=>setTimeout(resolve3,options.interval))}throw options.mode==="selector"?new Error(`page_wait selector ${JSON.stringify(options.selector)} was not found after ${options.timeout}ms.`):new Error(`page_wait condition was not met after ${options.timeout}ms.`)}async function cdpPageNavigate(session,data){let input=resolvePageNavigateInput(data);if(input.mode==="refresh")return clearPageRefsForNavigation(session),await session.client.sendCommand("Page.reload",{},35e3),await waitForPageLoad(session,3e4),{success:!0,...await readPageIdentity(session),refreshed:!0};if(input.mode==="history"){let navigationHistory=await session.client.sendCommand("Page.getNavigationHistory"),targetIndex=navigationHistory.currentIndex+(input.history==="back"?-1:1),targetEntry=navigationHistory.entries?.[targetIndex];if(!targetEntry)throw new Error(`page_navigate: no ${input.history==="back"?"previous":"next"} history entry`);return clearPageRefsForNavigation(session),await session.client.sendCommand("Page.navigateToHistoryEntry",{entryId:targetEntry.id},35e3),await waitForHistoryIndex(session,targetIndex,3e4),{success:!0,...await readPageIdentity(session),history:input.history}}clearPageRefsForNavigation(session);let result=await session.client.sendCommand("Page.navigate",{url:input.url},35e3);return await waitForPageLoad(session,3e4),{success:!0,url:result.url??input.url,frameId:result.frameId}}async function readPageIdentity(session){let evaluated=await session.client.sendCommand("Runtime.evaluate",{expression:"({ url: location.href, title: document.title })",returnByValue:!0});return{url:evaluated.result?.value?.url??"",title:evaluated.result?.value?.title??""}}async function waitForHistoryIndex(session,targetIndex,timeoutMs){let deadline=Date.now()+timeoutMs;for(;Date.now()<deadline;){try{if((await session.client.sendCommand("Page.getNavigationHistory")).currentIndex===targetIndex&&(await session.client.sendCommand("Runtime.evaluate",{expression:"document.readyState",returnByValue:!0})).result?.value!=="loading")return}catch{}await new Promise(resolve3=>setTimeout(resolve3,50))}throw new Error(`Page history navigation timeout after ${timeoutMs}ms`)}async function cdpPageUpload(session,data){let{selector,filePaths}=data??{};if(typeof selector!="string"||selector.length===0)throw new PageActionPreconditionError('page_upload: "selector" is required (CSS selector or @eN snapshot ref)');if(checkPageActionPrecondition(()=>validatePageElementSelector(selector,"page_upload")),!Array.isArray(filePaths)||filePaths.length===0||filePaths.some(filePath=>typeof filePath!="string"||filePath.length===0))throw new PageActionPreconditionError("Invalid filePaths: must be a non-empty array of file path strings");let described;if(selector.startsWith("@e"))described=await withSnapshotRef(session,selector,entry=>session.client.sendCommand("DOM.describeNode",{backendNodeId:entry.backendNodeId}));else{let documentResult=await session.client.sendCommand("DOM.getDocument",{depth:0}),queryResult=await session.client.sendCommand("DOM.querySelector",{nodeId:documentResult.root?.nodeId,selector});if(!queryResult.nodeId)throw new PageActionPreconditionError(`Element not found: ${selector}`);described=await session.client.sendCommand("DOM.describeNode",{nodeId:queryResult.nodeId})}let backendNodeId=described.node?.backendNodeId,tag=String(described.node?.nodeName??"").toLowerCase();if(backendNodeId===void 0)throw new PageActionPreconditionError(`Cannot resolve file input: ${selector}`);if(tag!=="input")throw new PageActionPreconditionError(`Element <${tag||"unknown"}> is not a file input. selector must point to an <input type="file"> element.`);return await session.client.sendCommand("DOM.setFileInputFiles",{files:filePaths,backendNodeId}),{uploaded:!0,fileCount:filePaths.length,tag}}async function cdpSetDeviceEmulation(session,data){let{enabled}=data??{};if(typeof enabled!="boolean")throw new Error('set_device_emulation: "enabled" is required (true to enable, false to clear)');if(enabled===!1){let appEnvironment2=updateCdpAppProfileDeviceEmulation(session,null);for(let{method,params}of buildDisableEmulationCommands())await session.client.sendCommand(method,params).catch(()=>{});return appEnvironment2&&await session.client.sendCommand("Emulation.setUserAgentOverride",{userAgent:appEnvironment2.userAgent,platform:appEnvironment2.platform}),session.emulation=void 0,{enabled:!1,reloaded:!1}}let config2=resolveEmulationConfig(data),appEnvironment=updateCdpAppProfileDeviceEmulation(session,config2),commands=buildEnableEmulationCommands(config2).map(command=>command.method==="Emulation.setUserAgentOverride"&&appEnvironment?{...command,params:{userAgent:appEnvironment.userAgent,platform:config2.platform}}:command);for(let{method,params,optional:optional2}of commands)await session.client.sendCommand(method,params).catch(error48=>{if(!optional2)throw error48});session.emulation={mobile:config2.mobile,touch:config2.touch};let reloaded=!1;if(data?.reload!==!1){clearPageRefsForNavigation(session);try{await session.client.sendCommand("Page.reload",{}),isCdpAppProfileActive(session)?await waitForCdpAppProfileLoad(session):await waitForPageLoad(session,3e4),reloaded=!0}catch{}}return{enabled:!0,preset:config2.presetName,viewport:{width:config2.width,height:config2.height,deviceScaleFactor:config2.deviceScaleFactor},userAgent:config2.userAgent,mobile:config2.mobile,touch:config2.touch,orientation:config2.orientation,reloaded}}async function cdpPageHover(session,data){let{selector}=data??{};if(typeof selector!="string"||selector.length===0)throw new PageActionPreconditionError('page_hover: "selector" is required (CSS selector or @eN snapshot ref)');checkPageActionPrecondition(()=>validatePageElementSelector(selector,"page_hover"));let coord=selector.startsWith("@e")?await withSnapshotRef(session,selector,entry=>getElementCoordsByBackendNodeId(session,entry.backendNodeId)):await getElementCoordsBySelector(session,selector);return await session.client.sendCommand("Input.dispatchMouseEvent",{type:"mouseMoved",x:coord.x,y:coord.y}),{hovered:!0,tag:coord.tag,text:coord.text}}registerActions([{name:"page_click",session:"page",handler:cdpPageClick},{name:"page_drag",session:"page",handler:cdpPageDrag},{name:"page_type",session:"page",handler:cdpPageType},{name:"page_hover",session:"page",handler:cdpPageHover},{name:"page_scroll",session:"page",handler:cdpPageScroll},{name:"page_eval",session:"page",handler:cdpPageEval},{name:"page_press",session:"page",handler:cdpPagePress},{name:"page_wait",session:"page",handler:cdpPageWait},{name:"page_navigate",session:"page",handler:cdpPageNavigate},{name:"page_upload",session:"page",handler:cdpPageUpload},{name:"set_device_emulation",session:"page",handler:cdpSetDeviceEmulation}]);async function cdpSetTimezone(session,data){if(typeof data?.timezone!="string")throw new Error('set_timezone: "timezone" is required (IANA timezone or empty string to clear)');let timezone=data.timezone.trim();return await session.client.sendCommand("Emulation.setTimezoneOverride",{timezoneId:timezone}),{enabled:timezone.length>0,timezone:timezone||null}}registerActions([{name:"set_timezone",session:"page",handler:cdpSetTimezone}]);async function readCurrentUrl(session,action){let url2=(await session.client.sendCommand("Runtime.evaluate",{expression:"location.href",returnByValue:!0})).result?.value;if(typeof url2!="string"||!url2)throw new Error(`${action}: could not read the current page URL`);return url2}function reloadPageAndWait(session,timeoutMs){return new Promise((resolve3,reject)=>{let settled=!1,removeListener=()=>{},finish=error48=>{settled||(settled=!0,clearTimeout(timer),removeListener(),error48?reject(error48):resolve3())},timer=setTimeout(()=>{finish(new Error(`Page load timeout after ${timeoutMs}ms`))},timeoutMs);removeListener=session.client.on("Page.loadEventFired",()=>finish()),session.client.sendCommand("Page.reload").catch(error48=>{finish(error48 instanceof Error?error48:new Error(String(error48)))})})}async function cdpSetCookie(session,data){let url2=await readCurrentUrl(session,"set_cookie"),target=resolveSetCookieTarget(url2,data??{});if((await session.client.sendCommand("Network.setCookie",{name:target.cookieName,value:target.cookieValue,url:target.cookieUrl,path:target.path,secure:target.cookieUrl.startsWith("https:"),...target.cookieDomain?{domain:target.cookieDomain}:{}})).success===!1)throw new Error(`set_cookie: failed to set ${target.cookieName}`);return target.reload&&await reloadPageAndWait(session,3e4),{...typeof data?.tabId=="number"?{tabId:data.tabId}:{},url:url2,name:target.cookieName,domain:target.domain,path:target.path,reloaded:target.reload}}async function cdpGetCookie(session,data){let url2=await readCurrentUrl(session,"get_cookie"),target=resolveGetCookieTarget(url2,data??{}),result=await session.client.sendCommand("Network.getCookies",{urls:[target.cookieUrl]}),cookie=selectReadableCookie(result.cookies??[],target);return{...typeof data?.tabId=="number"?{tabId:data.tabId}:{},url:url2,name:target.cookieName,found:!!cookie,...cookie?{value:cookie.value,domain:cookie.domain,path:cookie.path}:{}}}registerActions([{name:"get_cookie",session:"page",handler:cdpGetCookie},{name:"set_cookie",session:"page",handler:cdpSetCookie}]);var READ_DOM_CHECKED_STATE_SOURCE=readDOMCheckedState.toString();async function readDOMCheckedState2(session,backendNodeId){let objectId=(await session.client.sendCommand("DOM.resolveNode",{backendNodeId})).object?.objectId;if(objectId)try{let value=(await session.client.sendCommand("Runtime.callFunctionOn",{objectId,functionDeclaration:READ_DOM_CHECKED_STATE_SOURCE,returnByValue:!0})).result?.value;return value===!0||value===!1||value==="mixed"?value:void 0}finally{await session.client.sendCommand("Runtime.releaseObject",{objectId}).catch(()=>{})}}function buildSnapshotTree(nodeMap,nodeId,snapshotRefs){let node=nodeMap.get(nodeId);if(!node)return null;let role=node.role?.value??"generic",name=node.name?.value??"",value=node.value?.value,description=node.description?.value;if(ALWAYS_SKIP_ROLES.has(role)||role==="StaticText"&&!name)return null;if(role==="SvgRoot"){let ref2;node.backendDOMNodeId!==void 0&&(ref2=snapshotRefs.register({backendNodeId:node.backendDOMNodeId,role,name}));let svgChildCount=node.childIds?.length??0;return{role:"SvgRoot",name:name||`(${svgChildCount} elements)`,backendDOMNodeId:node.backendDOMNodeId,ref:ref2}}let children2=[];if(node.childIds)for(let childId of node.childIds){let child=buildSnapshotTree(nodeMap,childId,snapshotRefs);child&&children2.push(child)}if(node.ignored)return children2.length===0?null:children2.length===1?children2[0]:{role:"group",name:"",children:children2};if(SKIP_ROLES.has(role)&&!name)return children2.length===0?null:children2.length===1?children2[0]:{role:"group",name:"",children:children2};children2.length===1&&children2[0].role==="StaticText"&&children2[0].name===name&&!children2[0].children&&(children2.length=0);let ref;node.backendDOMNodeId!==void 0&&(ref=snapshotRefs.register({backendNodeId:node.backendDOMNodeId,role,name}));let props=extractAXProperties(node),result={role,name,backendDOMNodeId:node.backendDOMNodeId};return ref&&(result.ref=ref),value!==void 0&&value!==""&&(result.value=String(value)),description&&(result.description=description),props.focused&&(result.focused=!0),props.checked!==void 0&&(result.checked=props.checked),props.disabled&&(result.disabled=!0),props.required&&(result.required=!0),props.expanded!==void 0&&(result.expanded=props.expanded),props.selected&&(result.selected=!0),props.level!==void 0&&(result.level=props.level),children2.length>0&&(result.children=children2),result}async function resolveRootBackendNodeId(session,selector){let evaluated=await session.client.sendCommand("Runtime.evaluate",{expression:`document.querySelector(${JSON.stringify(selector)})`,returnByValue:!1});if(evaluated.exceptionDetails){let message=evaluated.exceptionDetails.exception?.description??evaluated.exceptionDetails.text??"invalid selector";throw new Error(`page_snapshot: invalid rootSelector "${selector}": ${message}`)}let objectId=evaluated.result?.objectId;if(!objectId||evaluated.result?.subtype==="null")throw new Error(`page_snapshot: rootSelector not found: ${selector}`);try{let backendNodeId=(await session.client.sendCommand("DOM.describeNode",{objectId})).node?.backendNodeId;if(backendNodeId===void 0)throw new Error(`page_snapshot: cannot resolve rootSelector: ${selector}`);return backendNodeId}finally{await session.client.sendCommand("Runtime.releaseObject",{objectId}).catch(()=>{})}}async function resolveAncestorBackendNodeId(session,backendNodeId,ancestorDepth){if(ancestorDepth===0)return backendNodeId;let objectId=(await session.client.sendCommand("DOM.resolveNode",{backendNodeId})).object?.objectId;if(!objectId)throw new Error("page_snapshot: cannot resolve rootRef in the current document");let ancestorObjectId;try{let ancestor=await session.client.sendCommand("Runtime.callFunctionOn",{objectId,functionDeclaration:`function(depth) {
|
|
1244
|
+
})(${JSON.stringify(selector)}, ${JSON.stringify(text)}, ${JSON.stringify(clearFirst)})`,value=(await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression,returnByValue:!0})).result?.value;if(!value)throw new Error("cdp_page_type: evaluation returned no value");if(value.error)throw new PageActionPreconditionError(value.error);if(!value.typed)throw new PageActionPreconditionError("cdp_page_type: failed to type");return{typed:!0,tag:value.tag}}async function cdpPageScroll(session,data){let input=checkPageActionPrecondition(()=>resolvePageScrollInput(data??{}));if(input.selector?.startsWith("@e"))return withSnapshotRef(session,input.selector,async entry=>{let objectId=await resolveBackendNodeObjectId(session,entry.backendNodeId),result2=await sendCdpDeviceShellPageCommand(session,"Runtime.callFunctionOn",{objectId,functionDeclaration:SCROLL_ELEMENT_IN_PAGE_SOURCE,arguments:[{value:input.direction},{value:input.distance},{value:input.selector},{value:input.containerPolicy}],returnByValue:!0});return unwrapPageScrollResult(result2.result?.value,`Cannot resolve scroll container for ref ${input.selector}`)});let result=await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:buildPageScrollExpression(input),returnByValue:!0});if(result.exceptionDetails)throw new Error(result.exceptionDetails.exception?.description??result.exceptionDetails.text??"page_scroll evaluation failed");return unwrapPageScrollResult(result.result?.value,"page_scroll evaluation returned no value")}async function cdpPageEval(session,data){let{expression,awaitPromise=!0}=data;if(!expression||typeof expression!="string")throw new PageActionPreconditionError("Invalid expression");let result=await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression,returnByValue:!0,awaitPromise});if(result.exceptionDetails)throw new Error(result.exceptionDetails.exception?.description??result.exceptionDetails.text??"Evaluation error");return{result:result.result?.value}}async function cdpPagePress(session,data){let{key}=data;if(!key||typeof key!="string")throw new PageActionPreconditionError("Invalid key");return await session.client.sendCommand("Input.dispatchKeyEvent",{type:"keyDown",key}),await session.client.sendCommand("Input.dispatchKeyEvent",{type:"keyUp",key}),{success:!0,key}}async function cdpPageWait(session,data){let options=resolvePageWaitInput(data),startedAt=Date.now();if(options.mode==="time")return await new Promise(resolve3=>setTimeout(resolve3,options.time)),{success:!0,waited:!0,elapsed:options.time,mode:options.mode};let expression=options.mode==="selector"?`!!document.querySelector(${JSON.stringify(options.selector)})`:options.condition;for(;Date.now()-startedAt<options.timeout;){let result=await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression,returnByValue:!0,awaitPromise:options.mode==="condition"});if(result.exceptionDetails)throw new Error(result.exceptionDetails.exception?.description??result.exceptionDetails.text??`page_wait ${options.mode} evaluation failed`);let value=result.result?.value;if(value)return{success:!0,waited:!0,elapsed:Date.now()-startedAt,mode:options.mode,value};await new Promise(resolve3=>setTimeout(resolve3,options.interval))}throw options.mode==="selector"?new Error(`page_wait selector ${JSON.stringify(options.selector)} was not found after ${options.timeout}ms.`):new Error(`page_wait condition was not met after ${options.timeout}ms.`)}async function cdpPageNavigate(session,data){let input=resolvePageNavigateInput(data);if(input.mode==="refresh")return clearPageRefsForNavigation(session),await sendCdpDeviceShellPageCommand(session,"Page.reload",{},35e3),await waitForPageLoad(session,3e4),{success:!0,...await readPageIdentity(session),refreshed:!0};if(input.mode==="history"){let navigationHistory=await sendCdpDeviceShellPageCommand(session,"Page.getNavigationHistory"),targetIndex=navigationHistory.currentIndex+(input.history==="back"?-1:1),targetEntry=navigationHistory.entries?.[targetIndex];if(!targetEntry)throw new Error(`page_navigate: no ${input.history==="back"?"previous":"next"} history entry`);return clearPageRefsForNavigation(session),await sendCdpDeviceShellPageCommand(session,"Page.navigateToHistoryEntry",{entryId:targetEntry.id},35e3),await waitForHistoryIndex(session,targetIndex,3e4),{success:!0,...await readPageIdentity(session),history:input.history}}clearPageRefsForNavigation(session);let result=await sendCdpDeviceShellPageCommand(session,"Page.navigate",{url:input.url},35e3);return await waitForPageLoad(session,3e4),{success:!0,url:result.url??input.url,frameId:result.frameId}}async function readPageIdentity(session){let evaluated=await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:"({ url: location.href, title: document.title })",returnByValue:!0});return{url:evaluated.result?.value?.url??"",title:evaluated.result?.value?.title??""}}async function waitForHistoryIndex(session,targetIndex,timeoutMs){let deadline=Date.now()+timeoutMs;for(;Date.now()<deadline;){try{if((await sendCdpDeviceShellPageCommand(session,"Page.getNavigationHistory")).currentIndex===targetIndex&&(await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:"document.readyState",returnByValue:!0})).result?.value!=="loading")return}catch{}await new Promise(resolve3=>setTimeout(resolve3,50))}throw new Error(`Page history navigation timeout after ${timeoutMs}ms`)}async function cdpPageUpload(session,data){let{selector,filePaths}=data??{};if(typeof selector!="string"||selector.length===0)throw new PageActionPreconditionError('page_upload: "selector" is required (CSS selector or @eN snapshot ref)');if(checkPageActionPrecondition(()=>validatePageElementSelector(selector,"page_upload")),!Array.isArray(filePaths)||filePaths.length===0||filePaths.some(filePath=>typeof filePath!="string"||filePath.length===0))throw new PageActionPreconditionError("Invalid filePaths: must be a non-empty array of file path strings");let described;if(selector.startsWith("@e"))described=await withSnapshotRef(session,selector,entry=>sendCdpDeviceShellPageCommand(session,"DOM.describeNode",{backendNodeId:entry.backendNodeId}));else{let evaluated=await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:`document.querySelector(${JSON.stringify(selector)})`,returnByValue:!1}),objectId=evaluated.result?.objectId;if(!objectId||evaluated.result?.subtype==="null")throw new PageActionPreconditionError(`Element not found: ${selector}`);try{described=await sendCdpDeviceShellPageCommand(session,"DOM.describeNode",{objectId})}finally{await sendCdpDeviceShellPageCommand(session,"Runtime.releaseObject",{objectId}).catch(()=>{})}}let backendNodeId=described.node?.backendNodeId,tag=String(described.node?.nodeName??"").toLowerCase();if(backendNodeId===void 0)throw new PageActionPreconditionError(`Cannot resolve file input: ${selector}`);if(tag!=="input")throw new PageActionPreconditionError(`Element <${tag||"unknown"}> is not a file input. selector must point to an <input type="file"> element.`);return await sendCdpDeviceShellPageCommand(session,"DOM.setFileInputFiles",{files:filePaths,backendNodeId}),{uploaded:!0,fileCount:filePaths.length,tag}}async function cdpSetDeviceEmulation(session,data){let{enabled}=data??{};if(typeof enabled!="boolean")throw new Error('set_device_emulation: "enabled" is required (true to enable, false to clear)');if(enabled===!1){let hadDeviceShell2=await clearCdpDeviceShell(session),appEnvironment2=await updateCdpAppProfileDeviceEmulation(session,null);for(let{method,params}of buildDisableEmulationCommands())await session.client.sendCommand(method,params).catch(()=>{});appEnvironment2&&await session.client.sendCommand("Emulation.setUserAgentOverride",{userAgent:appEnvironment2.userAgent,platform:appEnvironment2.platform}),session.emulation=void 0;let reloaded2=!1;if(hadDeviceShell2){clearPageRefsForNavigation(session);try{await session.client.sendCommand("Page.reload",{}),await waitForPageLoad(session,3e4),reloaded2=!0}catch{}}return{enabled:!1,reloaded:reloaded2}}let config2=resolveEmulationConfig(data),deviceShell=data.deviceShell===!0,hadDeviceShell=isCdpDeviceShellActive(session),appEnvironment=await updateCdpAppProfileDeviceEmulation(session,config2),commands=buildEnableEmulationCommands(config2).map(command=>command.method==="Emulation.setUserAgentOverride"&&appEnvironment?{...command,params:{userAgent:appEnvironment.userAgent,platform:config2.platform}}:command);for(let{method,params,optional:optional2}of commands)await session.client.sendCommand(method,params).catch(error48=>{if(!optional2)throw error48});session.emulation={mobile:config2.mobile,touch:config2.touch,config:config2,deviceShell};let deviceShellChanged=deviceShell?await applyCdpDeviceShell(session,config2):await clearCdpDeviceShell(session);deviceShell&&appEnvironment&&setCdpDeviceShellChildEnvironmentManagedByApp(session,!0);let reloaded=!1;if(data?.reload!==!1||deviceShellChanged||hadDeviceShell!==deviceShell){clearPageRefsForNavigation(session);try{await session.client.sendCommand("Page.reload",{}),deviceShell?await waitForCdpDeviceShellLoad(session):isCdpAppProfileActive(session)?await waitForCdpAppProfileLoad(session):await waitForPageLoad(session,3e4),reloaded=!0}catch{}}return{enabled:!0,preset:config2.presetName,viewport:{width:config2.width,height:config2.height,deviceScaleFactor:config2.deviceScaleFactor,scale:config2.scale??1},userAgent:config2.userAgent,mobile:config2.mobile,touch:config2.touch,orientation:config2.orientation,deviceShell,reloaded}}async function cdpPageHover(session,data){let{selector}=data??{};if(typeof selector!="string"||selector.length===0)throw new PageActionPreconditionError('page_hover: "selector" is required (CSS selector or @eN snapshot ref)');checkPageActionPrecondition(()=>validatePageElementSelector(selector,"page_hover"));let coord=selector.startsWith("@e")?await withSnapshotRef(session,selector,entry=>getElementCoordsByBackendNodeId(session,entry.backendNodeId)):await getElementCoordsBySelector(session,selector),offset=getCdpDeviceShellInputOffset(session);return await session.client.sendCommand("Input.dispatchMouseEvent",{type:"mouseMoved",x:coord.x+offset.x,y:coord.y+offset.y}),{hovered:!0,tag:coord.tag,text:coord.text}}registerActions([{name:"page_click",session:"page",handler:cdpPageClick},{name:"page_drag",session:"page",handler:cdpPageDrag},{name:"page_type",session:"page",handler:cdpPageType},{name:"page_hover",session:"page",handler:cdpPageHover},{name:"page_scroll",session:"page",handler:cdpPageScroll},{name:"page_eval",session:"page",handler:cdpPageEval},{name:"page_press",session:"page",handler:cdpPagePress},{name:"page_wait",session:"page",handler:cdpPageWait},{name:"page_navigate",session:"page",handler:cdpPageNavigate},{name:"page_upload",session:"page",handler:cdpPageUpload},{name:"set_device_emulation",session:"page",handler:cdpSetDeviceEmulation}]);async function cdpSetTimezone(session,data){if(typeof data?.timezone!="string")throw new Error('set_timezone: "timezone" is required (IANA timezone or empty string to clear)');let timezone=data.timezone.trim();return await session.client.sendCommand("Emulation.setTimezoneOverride",{timezoneId:timezone}),{enabled:timezone.length>0,timezone:timezone||null}}registerActions([{name:"set_timezone",session:"page",handler:cdpSetTimezone}]);async function readCurrentUrl(session,action){let url2=(await session.client.sendCommand("Runtime.evaluate",{expression:"location.href",returnByValue:!0})).result?.value;if(typeof url2!="string"||!url2)throw new Error(`${action}: could not read the current page URL`);return url2}function reloadPageAndWait(session,timeoutMs){return new Promise((resolve3,reject)=>{let settled=!1,removeListener=()=>{},finish=error48=>{settled||(settled=!0,clearTimeout(timer),removeListener(),error48?reject(error48):resolve3())},timer=setTimeout(()=>{finish(new Error(`Page load timeout after ${timeoutMs}ms`))},timeoutMs);removeListener=session.client.on("Page.loadEventFired",()=>finish()),session.client.sendCommand("Page.reload").catch(error48=>{finish(error48 instanceof Error?error48:new Error(String(error48)))})})}async function cdpSetCookie(session,data){let url2=await readCurrentUrl(session,"set_cookie"),target=resolveSetCookieTarget(url2,data??{});if((await session.client.sendCommand("Network.setCookie",{name:target.cookieName,value:target.cookieValue,url:target.cookieUrl,path:target.path,secure:target.cookieUrl.startsWith("https:"),...target.cookieDomain?{domain:target.cookieDomain}:{}})).success===!1)throw new Error(`set_cookie: failed to set ${target.cookieName}`);return target.reload&&await reloadPageAndWait(session,3e4),{...typeof data?.tabId=="number"?{tabId:data.tabId}:{},url:url2,name:target.cookieName,domain:target.domain,path:target.path,reloaded:target.reload}}async function cdpGetCookie(session,data){let url2=await readCurrentUrl(session,"get_cookie"),target=resolveGetCookieTarget(url2,data??{}),result=await session.client.sendCommand("Network.getCookies",{urls:[target.cookieUrl]}),cookie=selectReadableCookie(result.cookies??[],target);return{...typeof data?.tabId=="number"?{tabId:data.tabId}:{},url:url2,name:target.cookieName,found:!!cookie,...cookie?{value:cookie.value,domain:cookie.domain,path:cookie.path}:{}}}registerActions([{name:"get_cookie",session:"page",handler:cdpGetCookie},{name:"set_cookie",session:"page",handler:cdpSetCookie}]);var READ_DOM_CHECKED_STATE_SOURCE=readDOMCheckedState.toString();async function readDOMCheckedState2(session,backendNodeId){let objectId=(await sendCdpDeviceShellPageCommand(session,"DOM.resolveNode",{backendNodeId})).object?.objectId;if(objectId)try{let value=(await sendCdpDeviceShellPageCommand(session,"Runtime.callFunctionOn",{objectId,functionDeclaration:READ_DOM_CHECKED_STATE_SOURCE,returnByValue:!0})).result?.value;return value===!0||value===!1||value==="mixed"?value:void 0}finally{await sendCdpDeviceShellPageCommand(session,"Runtime.releaseObject",{objectId}).catch(()=>{})}}function buildSnapshotTree(nodeMap,nodeId,snapshotRefs){let node=nodeMap.get(nodeId);if(!node)return null;let role=node.role?.value??"generic",name=node.name?.value??"",value=node.value?.value,description=node.description?.value;if(ALWAYS_SKIP_ROLES.has(role)||role==="StaticText"&&!name)return null;if(role==="SvgRoot"){let ref2;node.backendDOMNodeId!==void 0&&(ref2=snapshotRefs.register({backendNodeId:node.backendDOMNodeId,role,name}));let svgChildCount=node.childIds?.length??0;return{role:"SvgRoot",name:name||`(${svgChildCount} elements)`,backendDOMNodeId:node.backendDOMNodeId,ref:ref2}}let children2=[];if(node.childIds)for(let childId of node.childIds){let child=buildSnapshotTree(nodeMap,childId,snapshotRefs);child&&children2.push(child)}if(node.ignored)return children2.length===0?null:children2.length===1?children2[0]:{role:"group",name:"",children:children2};if(SKIP_ROLES.has(role)&&!name)return children2.length===0?null:children2.length===1?children2[0]:{role:"group",name:"",children:children2};children2.length===1&&children2[0].role==="StaticText"&&children2[0].name===name&&!children2[0].children&&(children2.length=0);let ref;node.backendDOMNodeId!==void 0&&(ref=snapshotRefs.register({backendNodeId:node.backendDOMNodeId,role,name}));let props=extractAXProperties(node),result={role,name,backendDOMNodeId:node.backendDOMNodeId};return ref&&(result.ref=ref),value!==void 0&&value!==""&&(result.value=String(value)),description&&(result.description=description),props.focused&&(result.focused=!0),props.checked!==void 0&&(result.checked=props.checked),props.disabled&&(result.disabled=!0),props.required&&(result.required=!0),props.expanded!==void 0&&(result.expanded=props.expanded),props.selected&&(result.selected=!0),props.level!==void 0&&(result.level=props.level),children2.length>0&&(result.children=children2),result}async function resolveRootBackendNodeId(session,selector){let evaluated=await sendCdpDeviceShellPageCommand(session,"Runtime.evaluate",{expression:`document.querySelector(${JSON.stringify(selector)})`,returnByValue:!1});if(evaluated.exceptionDetails){let message=evaluated.exceptionDetails.exception?.description??evaluated.exceptionDetails.text??"invalid selector";throw new Error(`page_snapshot: invalid rootSelector "${selector}": ${message}`)}let objectId=evaluated.result?.objectId;if(!objectId||evaluated.result?.subtype==="null")throw new Error(`page_snapshot: rootSelector not found: ${selector}`);try{let backendNodeId=(await sendCdpDeviceShellPageCommand(session,"DOM.describeNode",{objectId})).node?.backendNodeId;if(backendNodeId===void 0)throw new Error(`page_snapshot: cannot resolve rootSelector: ${selector}`);return backendNodeId}finally{await sendCdpDeviceShellPageCommand(session,"Runtime.releaseObject",{objectId}).catch(()=>{})}}async function resolveAncestorBackendNodeId(session,backendNodeId,ancestorDepth){if(ancestorDepth===0)return backendNodeId;let objectId=(await sendCdpDeviceShellPageCommand(session,"DOM.resolveNode",{backendNodeId})).object?.objectId;if(!objectId)throw new Error("page_snapshot: cannot resolve rootRef in the current document");let ancestorObjectId;try{let ancestor=await sendCdpDeviceShellPageCommand(session,"Runtime.callFunctionOn",{objectId,functionDeclaration:`function(depth) {
|
|
951
1245
|
let element = this && this.nodeType === 3 ? this.parentElement : this;
|
|
952
1246
|
let remaining = depth;
|
|
953
1247
|
while (element && element.parentElement && remaining > 0) {
|
|
@@ -955,7 +1249,7 @@ ${candidates}`)}let hit=hits[0],dispatchTarget;if(effectiveClickMode==="dom"||po
|
|
|
955
1249
|
remaining -= 1;
|
|
956
1250
|
}
|
|
957
1251
|
return element;
|
|
958
|
-
}`,arguments:[{value:ancestorDepth}],returnByValue:!1});if(ancestorObjectId=ancestor.result?.objectId,!ancestorObjectId||ancestor.result?.subtype==="null")throw new Error("page_snapshot: cannot resolve an ancestor for rootRef");let ancestorBackendNodeId=(await session.client.sendCommand("DOM.describeNode",{objectId:ancestorObjectId})).node?.backendNodeId;if(ancestorBackendNodeId===void 0)throw new Error("page_snapshot: cannot resolve an ancestor for rootRef");return ancestorBackendNodeId}finally{ancestorObjectId&&await session.client.sendCommand("Runtime.releaseObject",{objectId:ancestorObjectId}).catch(()=>{}),await session.client.sendCommand("Runtime.releaseObject",{objectId}).catch(()=>{})}}async function getViewportBackendNodeIds(session){let[metrics,captured]=await Promise.all([session.client.sendCommand("Page.getLayoutMetrics",{}),session.client.sendCommand("DOMSnapshot.captureSnapshot",{computedStyles:[],includeDOMRects:!0,includePaintOrder:!1})]),viewport=resolveDOMSnapshotViewportBounds(metrics);if(!viewport)throw new Error("page_snapshot: viewport metrics are unavailable");let{left,top,width,height}=viewport,right=left+width,bottom=top+height,visible=new Set;for(let document2 of captured.documents??[]){let backendNodeIds=document2.nodes?.backendNodeId??[],nodeIndexes=document2.layout?.nodeIndex??[],bounds=document2.layout?.bounds??[];for(let index=0;index<nodeIndexes.length;index+=1){let box=bounds[index],backendNodeId=backendNodeIds[nodeIndexes[index]];if(!box||backendNodeId===void 0)continue;let[x,y,boxWidth,boxHeight]=box;boxWidth<=0||boxHeight<=0||x<right&&x+boxWidth>left&&y<bottom&&y+boxHeight>top&&visible.add(backendNodeId)}}return visible}async function cdpPageSnapshot(session,data){let mode=data?.mode??"full",rootSelector=data?.rootSelector,rootRef=data?.rootRef,ancestorDepth=data?.ancestorDepth??0,query=resolvePageSnapshotQuery(data?.query);if(!["full","interactive","viewport"].includes(mode))throw new Error("page_snapshot: mode must be one of full, interactive, viewport");if(rootSelector!==void 0&&(typeof rootSelector!="string"||!rootSelector.trim()))throw new Error("page_snapshot: rootSelector must be a non-empty CSS selector");if(rootRef!==void 0&&(typeof rootRef!="string"||!/^@e\d+$/.test(rootRef)))throw new Error('page_snapshot: rootRef must be a snapshot ref like "@e3"');if(rootSelector!==void 0&&rootRef!==void 0)throw new Error("page_snapshot: rootSelector and rootRef are mutually exclusive");if(!Number.isInteger(ancestorDepth)||ancestorDepth<0||ancestorDepth>20)throw new Error("page_snapshot: ancestorDepth must be an integer between 0 and 20");if(ancestorDepth>0&&rootRef===void 0)throw new Error("page_snapshot: ancestorDepth requires rootRef");let rootBackendNodeId;if(rootSelector)rootBackendNodeId=await resolveRootBackendNodeId(session,rootSelector);else if(rootRef){let entry=resolvePageRef(session,rootRef);if(!entry)throw new Error(`Ref ${rootRef} not found. Run page_snapshot first to get fresh refs.`);rootBackendNodeId=await resolveAncestorBackendNodeId(session,entry.backendNodeId,ancestorDepth)}let snapshotRefs=beginPageSnapshotRefs(session),[result,visibleBackendNodeIds]=await Promise.all([session.client.sendCommand(rootBackendNodeId===void 0?"Accessibility.getFullAXTree":"Accessibility.queryAXTree",rootBackendNodeId===void 0?{depth:data?.depth}:{backendNodeId:rootBackendNodeId}),mode==="viewport"||mode==="interactive"?getViewportBackendNodeIds(session):Promise.resolve(void 0)]),nodes=result.nodes??[];await reconcileAXCheckedStates(nodes,backendNodeId=>readDOMCheckedState2(session,backendNodeId));let nodeMap=new Map;for(let node of nodes)nodeMap.set(node.nodeId,node);let rootNode=nodes[0];if(!rootNode)return snapshotRefs.commit(new Set),{snapshot:"(empty page)",refs:{},elementCount:0,outputNodeCount:1,mode,...rootSelector?{rootSelector}:{},...rootRef?{rootRef,ancestorDepth}:{},...query?{query,matches:[],matchCount:0}:{}};let rawTree=buildSnapshotTree(nodeMap,rootNode.nodeId,snapshotRefs),viewportFilteredTree=mode==="interactive"?filterSnapshotTree(rawTree,"viewport",visibleBackendNodeIds):rawTree,effectiveMode=mode;mode==="interactive"&&!hasInteractiveSnapshotNode(viewportFilteredTree)&&(effectiveMode="viewport");let modeFilteredTree=mode==="interactive"?effectiveMode==="interactive"?filterSnapshotTree(viewportFilteredTree,"interactive"):viewportFilteredTree:filterSnapshotTree(rawTree,effectiveMode,visibleBackendNodeIds),queryResult=query?filterSnapshotTreeByQuery(modeFilteredTree,query):{tree:modeFilteredTree,matches:[]},limitedMatches=query?limitPageSnapshotQueryMatches(queryResult.matches):{matches:[],truncated:!1},tree=queryResult.tree,lines=[];tree&&formatSnapshotNode(tree,0,lines);let formatted=formatSnapshotWithLimits(lines.length>0?lines:[query?"(no matches)":"(empty page)"],{maxChars:data?.maxChars,maxNodes:data?.maxNodes}),refs={},outputRefKeys=new Set(Array.from(formatted.snapshot.matchAll(/(?:^|\n)\s*(@e\d+)\s/g),match=>match[1]));for(let match of limitedMatches.matches)match.ref&&outputRefKeys.add(match.ref);snapshotRefs.commit(outputRefKeys);let registry2=getPageRefRegistry(session);for(let ref of outputRefKeys){let entry=registry2.resolve(ref);entry&&(refs[ref.slice(1)]={backendNodeId:entry.backendNodeId})}return{snapshot:formatted.snapshot,refs,elementCount:countSnapshotNodes(tree),outputNodeCount:formatted.outputNodeCount,mode,...rootSelector?{rootSelector}:{},...rootRef?{rootRef,ancestorDepth}:{},...query?{query,matches:limitedMatches.matches,matchCount:queryResult.matches.length,...limitedMatches.truncated?{matchesTruncated:!0}:{}}:{},...effectiveMode!==mode?{fallbackMode:"viewport"}:{},...formatted.truncated?{truncated:!0}:{}}}async function cdpPageFrames(session,_data){let result=await session.client.sendCommand("Page.getFrameTree",{});function flattenFrameTree(tree){if(!tree)return[];let{frame,childFrames=[]}=tree;return[{frameId:frame.id,parentFrameId:frame.parentId??null,url:frame.url,name:frame.name??""},...childFrames.flatMap(flattenFrameTree)]}let frames=flattenFrameTree(result.frameTree);return{frames,count:frames.length}}registerActions([{name:"page_snapshot",session:"page",handler:cdpPageSnapshot},{name:"page_frames",session:"page",handler:cdpPageFrames}]);var MEARL_SERVICE_COOKIE_DOMAINS=["tdbank.alibaba-inc.com","ats2.alibaba-inc.com","g.alibaba-inc.com","login.alibaba-inc.com","token-hub.alibaba-inc.com","alibaba-inc.com"],MEARL_SERVICE_COOKIE_HOSTS=new Set(MEARL_SERVICE_COOKIE_DOMAINS);function normalizeCookieDomain2(input){let value=input.trim();if(!value)throw new Error("Cookie domain must be a non-empty string");let hostname3;try{hostname3=new URL(value.includes("://")?value:`https://${value}`).hostname}catch{throw new Error(`Invalid cookie domain: ${input}`)}if(hostname3=hostname3.toLowerCase().replace(/^\.+/,"").replace(/\.+$/,""),!hostname3)throw new Error(`Invalid cookie domain: ${input}`);return hostname3}function normalizeCookieDomains(inputs){if(!Array.isArray(inputs))throw new Error("copyCookieDomains must be an array of domains");return[...new Set(inputs.map(value=>normalizeCookieDomain2(String(value))))]}function isMearlServiceCookie(cookie){let domain2=normalizeCookieDomain2(cookie.domain);return MEARL_SERVICE_COOKIE_HOSTS.has(domain2)?!0:domain2.endsWith(".tdbank.alibaba-inc.com")||domain2.endsWith(".ats2.alibaba-inc.com")}function resolveCookieCopyPlan(input){return input==="mearl-services"?{domains:[...MEARL_SERVICE_COOKIE_DOMAINS],select:cookies=>cookies.filter(isMearlServiceCookie)}:{domains:input===void 0?[]:normalizeCookieDomains(input),select:cookies=>cookies}}function cookieMatchesDomain(cookieDomain,requestedDomain){let cookieHost=cookieDomain.toLowerCase().replace(/^\.+/,"");return cookieHost===requestedDomain||cookieHost.endsWith(`.${requestedDomain}`)||requestedDomain.endsWith(`.${cookieHost}`)}function toTransferableCookie(cookie){let result={name:String(cookie.name),value:String(cookie.value),domain:String(cookie.domain),path:String(cookie.path||"/"),secure:!!cookie.secure,httpOnly:!!cookie.httpOnly};return["Strict","Lax","None"].includes(cookie.sameSite)&&(result.sameSite=cookie.sameSite),typeof cookie.expires=="number"&&cookie.expires>0&&(result.expires=cookie.expires),["Low","Medium","High"].includes(cookie.priority)&&(result.priority=cookie.priority),typeof cookie.sameParty=="boolean"&&(result.sameParty=cookie.sameParty),["Unset","NonSecure","Secure"].includes(cookie.sourceScheme)&&(result.sourceScheme=cookie.sourceScheme),typeof cookie.sourcePort=="number"&&(result.sourcePort=cookie.sourcePort),cookie.partitionKey?.topLevelSite&&(result.partitionKey={topLevelSite:String(cookie.partitionKey.topLevelSite),...typeof cookie.partitionKey.hasCrossSiteAncestor=="boolean"?{hasCrossSiteAncestor:cookie.partitionKey.hasCrossSiteAncestor}:{}}),result}async function cdpExportCookies(session,domains){let requestedDomains=normalizeCookieDomains(domains);return((await(await session.getBrowserClient()).sendCommand("Storage.getCookies",{})).cookies??[]).filter(cookie=>requestedDomains.some(domain2=>cookieMatchesDomain(String(cookie.domain),domain2))).map(toTransferableCookie)}async function cdpImportCookies(session,cookies){if(cookies.length===0)return 0;let browser=await session.getBrowserClient();return cdpImportCookiesWithClient(browser,cookies)}async function cdpImportCookiesWithClient(browser,cookies){return cookies.length===0?0:(await browser.sendCommand("Storage.setCookies",{cookies}),cookies.length)}import{closeSync as closeSync3,existsSync as existsSync3,mkdtempSync,mkdirSync as mkdirSync2,openSync as openSync3,readFileSync as readFileSync3,renameSync as renameSync3,rmSync as rmSync2,writeFileSync as writeFileSync2}from"node:fs";import{spawn as spawn3,spawnSync as spawnSync2}from"node:child_process";import{randomUUID as randomUUID4}from"node:crypto";import{tmpdir}from"node:os";import{join as join3}from"node:path";var MANAGED_BROWSERS_SUBDIR="managed-browsers",MANAGED_BROWSER_LOCKS_SUBDIR="managed-browser-locks",MANAGED_PROFILES_SUBDIR="managed-profiles",LAUNCH_TIMEOUT_MS=15e3;function validateName(value){let name=typeof value=="string"?value.trim():"";if(!name)throw new Error("name is required");if(name.length>64)throw new Error("name must be at most 64 characters");if(/[/\\\0\r\n]/.test(name))throw new Error("name contains unsupported characters");return name}function managedBrowserId(name){return`managed:${name.toLocaleLowerCase("en-US")}`}function hasTdbankSelector(data){return data.accountId!==void 0||data.havanaId!==void 0||typeof data.query=="string"&&data.query.trim().length>0}function validateTdbankSelector(data){if(data.havanaId!==void 0&&data.site===void 0)throw new Error("site is required when havanaId is provided");if([data.accountId!==void 0,data.havanaId!==void 0,typeof data.query=="string"&&data.query.trim().length>0].filter(Boolean).length>1)throw new Error("Use only one of accountId, havanaId + site, or query")}function chromeExecutableCandidates(platform=process.platform){let envPath=process.env.MEARL_CHROME_PATH,candidates=envPath?[envPath]:[];if(platform==="darwin")return candidates.concat(["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary","/Applications/Chromium.app/Contents/MacOS/Chromium"]);if(platform==="win32"){let local=process.env.LOCALAPPDATA??"",programFiles=process.env.PROGRAMFILES??"",programFilesX86=process.env["PROGRAMFILES(X86)"]??"";return candidates.concat([join3(local,"Google","Chrome","Application","chrome.exe"),join3(programFiles,"Google","Chrome","Application","chrome.exe"),join3(programFilesX86,"Google","Chrome","Application","chrome.exe")])}return candidates.concat(["/usr/bin/google-chrome","/usr/bin/google-chrome-stable","/usr/bin/chromium","/usr/bin/chromium-browser"])}function resolveChromeExecutable(explicitPath){if(explicitPath){if(!existsSync3(explicitPath))throw new Error(`Chrome executable not found: ${explicitPath}`);return explicitPath}let found=chromeExecutableCandidates().find(candidate=>candidate&&existsSync3(candidate));if(!found)throw new Error("Chrome executable not found. Set executablePath or MEARL_CHROME_PATH.");return found}function desktopChromeUserAgent(version2,platform=process.platform){if(!/^\d+(?:\.\d+){1,3}$/.test(version2))throw new Error(`Invalid Chrome version: ${version2}`);return`Mozilla/5.0 (${platform==="darwin"?"Macintosh; Intel Mac OS X 10_15_7":platform==="win32"?"Windows NT 10.0; Win64; x64":"X11; Linux x86_64"}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${version2} Safari/537.36`}function resolveChromeVersion(executablePath){let result=spawnSync2(executablePath,["--version"],{encoding:"utf8",windowsHide:!0}),version2=`${result.stdout??""} ${result.stderr??""}`.match(/\b(\d+(?:\.\d+){1,3})\b/)?.[1];if(!version2)throw new Error(`Could not determine Chrome version from: ${executablePath}`);return version2}function resolveUserAgentMode(value){if(value===void 0||value==="default")return"default";if(value==="desktop")return"desktop";throw new Error('userAgentMode must be "default" or "desktop"')}function buildManagedChromeArgs(options){return[`--user-data-dir=${options.userDataDir}`,"--remote-debugging-port=0","--no-first-run","--no-default-browser-check","--disable-background-networking",...options.headless?["--headless=new"]:[],...options.userAgent?[`--user-agent=${options.userAgent}`]:[],"about:blank"]}function browserSummary(record2,running){return{browserId:record2.browserId,name:record2.name,provider:"local",headless:record2.headless,persistent:record2.persistent,cdpPort:record2.cdpPort,createdAt:record2.createdAt,account:record2.account,copiedCookies:record2.copiedCookies,running}}function isManagedProcess(pid,commandMarker,platform=process.platform){if(!isAlive(pid))return!1;try{if(platform==="win32"){let escapedMarker=commandMarker.replace(/'/g,"''");return spawnSync2("powershell.exe",["-NoProfile","-NonInteractive","-Command",`$p = Get-CimInstance Win32_Process -Filter 'ProcessId = ${pid}'; if ($p.CommandLine -and $p.CommandLine.Contains('${escapedMarker}')) { exit 0 } else { exit 1 }`],{windowsHide:!0,stdio:"ignore"}).status===0}let result=spawnSync2("ps",["-p",String(pid),"-o","command="],{encoding:"utf8",stdio:["ignore","pipe","ignore"]});return result.status===0&&result.stdout.includes(commandMarker)}catch{return!1}}function listRecords(){let records=[];for(let file2 of listRecordFiles(keyedDir(MANAGED_BROWSERS_SUBDIR))){let record2=readRecord(file2);if(!record2){removeRecord(file2);continue}let running=isManagedProcess(record2.pid,record2.userDataDir);if(!running&&(signalProcess(record2.hostPid,"SIGTERM",`--browser-id ${record2.browserId}`),removeRecord(keyedConfigFile("browsers",record2.browserId)),!record2.persistent)){removeRecord(file2),rmSync2(record2.userDataDir,{recursive:!0,force:!0});continue}records.push({record:record2,running})}return records}function listManagedBrowsers(){return listRecords().map(({record:record2,running})=>browserSummary(record2,running))}function findManagedRecord(selector){let normalized=selector.trim().toLowerCase();return listRecords().find(({record:record2})=>record2.browserId.toLowerCase()===normalized||record2.name.toLowerCase()===normalized)?.record??null}function hasManagedBrowser(selector){return findManagedRecord(selector)!==null}async function waitForActivePort(userDataDir){let deadline=Date.now()+LAUNCH_TIMEOUT_MS;for(;Date.now()<deadline;){let info=readDevToolsActivePort(userDataDir);if(info)return info.port;await new Promise(resolve3=>setTimeout(resolve3,100))}throw new Error(`Chrome did not expose a CDP port within ${LAUNCH_TIMEOUT_MS}ms`)}async function waitForBrowserRegistration(browserId,expectedPid){let file2=keyedConfigFile("browsers",browserId),deadline=Date.now()+LAUNCH_TIMEOUT_MS;for(;Date.now()<deadline;){if(readRecord(file2)?.pid===expectedPid&&isAlive(expectedPid))return;await new Promise(resolve3=>setTimeout(resolve3,100))}throw new Error(`Managed browser ${browserId} did not register within ${LAUNCH_TIMEOUT_MS}ms`)}function signalProcess(pid,signal,commandMarker){if(isManagedProcess(pid,commandMarker)){if(process.platform==="win32"){spawnSync2("taskkill",["/PID",String(pid),"/T","/F"],{windowsHide:!0,stdio:"ignore"});return}try{process.kill(pid,signal)}catch{}}}async function stopProcess(pid,commandMarker){signalProcess(pid,"SIGTERM",commandMarker);let deadline=Date.now()+3e3;for(;Date.now()<deadline&&isManagedProcess(pid,commandMarker);)await new Promise(resolve3=>setTimeout(resolve3,50));isManagedProcess(pid,commandMarker)&&signalProcess(pid,"SIGKILL",commandMarker)}function profileDirectory(browserId,persistent){if(!persistent)return mkdtempSync(join3(tmpdir(),"mearl-browser-"));let dir=join3(DAEMON_HOME,MANAGED_PROFILES_SUBDIR,hashKey(browserId));return mkdirSync2(dir,{recursive:!0}),dir}async function removeStoppedInstance(browserId){let file2=keyedConfigFile(MANAGED_BROWSERS_SUBDIR,browserId),record2=readRecord(file2);!record2||isManagedProcess(record2.pid,record2.userDataDir)||(await stopProcess(record2.hostPid,`--browser-id ${record2.browserId}`),removeRecord(file2),removeRecord(keyedConfigFile("browsers",record2.browserId)),record2.persistent||rmSync2(record2.userDataDir,{recursive:!0,force:!0}))}function acquireLaunchLock(browserId){let lockDir=keyedDir(MANAGED_BROWSER_LOCKS_SUBDIR),lockFile=keyedConfigFile(MANAGED_BROWSER_LOCKS_SUBDIR,browserId);mkdirSync2(lockDir,{recursive:!0});let token=`${process.pid}:${randomUUID4()}`,tryAcquire=()=>{try{return writeFileSync2(lockFile,token,{flag:"wx"}),!0}catch(error48){if(error48.code!=="EEXIST")throw error48;return!1}};if(!tryAcquire()){let observedToken="";try{observedToken=readFileSync3(lockFile,"utf-8")}catch{}let ownerPid=Number(observedToken.split(":",1)[0]);if(Number.isInteger(ownerPid)&&!isAlive(ownerPid)){let staleFile=`${lockFile}.${process.pid}.${randomUUID4()}.stale`;try{if(readFileSync3(lockFile,"utf-8")!==observedToken)throw new Error("Launch lock owner changed");if(renameSync3(lockFile,staleFile),readFileSync3(staleFile,"utf-8")===observedToken)rmSync2(staleFile,{force:!0});else try{renameSync3(staleFile,lockFile)}catch{}}catch{}}if(!tryAcquire())throw new Error(`Managed browser launch already in progress: ${browserId}`)}return()=>{try{readFileSync3(lockFile,"utf-8")===token&&rmSync2(lockFile,{force:!0})}catch{}}}async function launchManagedBrowser(input,deps){if(input.reuse!==void 0&&input.reuse!=="never"&&input.reuse!=="prefer"&&input.reuse!=="require")throw new Error('reuse must be "never", "prefer", or "require"');if(input.reuse==="prefer"||input.reuse==="require")throw new Error("reuse is currently supported only by the AgentBay browser provider");if(input.imageId!==void 0)throw new Error("imageId is only supported by the AgentBay browser provider");let name=validateName(input.name),browserId=managedBrowserId(name);validateTdbankSelector(input);let cookieCopy=resolveCookieCopyPlan(input.copyCookieDomains),copyCookieDomains=cookieCopy.domains,headless=input.headless!==!1,persistent=input.persistent===!0,executablePath=resolveChromeExecutable(input.executablePath),userAgent=resolveUserAgentMode(input.userAgentMode)==="desktop"?desktopChromeUserAgent(resolveChromeVersion(executablePath)):void 0,userDataDir=profileDirectory(browserId,persistent),logDir=keyedDir(MANAGED_BROWSERS_SUBDIR);mkdirSync2(logDir,{recursive:!0});let logPath=join3(logDir,`${hashKey(browserId)}.log`),logFd=openSync3(logPath,"a"),chromePid=0,hostPid=0,session=null,recordWritten=!1,releaseLock=null;try{if(releaseLock=acquireLaunchLock(browserId),await removeStoppedInstance(browserId),findManagedRecord(browserId))throw new Error(`Managed browser already running: ${browserId}`);let[ticket,exportedCookies]=await Promise.all([hasTdbankSelector(input)?deps.prepareTdbankSso(input):Promise.resolve(void 0),copyCookieDomains.length>0?deps.exportCookies(copyCookieDomains):Promise.resolve([])]),cookies=cookieCopy.select(exportedCookies),chromeArgs=buildManagedChromeArgs({userDataDir,headless,userAgent});rmSync2(join3(userDataDir,"DevToolsActivePort"),{force:!0});let chrome=spawn3(executablePath,chromeArgs,{detached:!0,stdio:["ignore","ignore",logFd],windowsHide:headless});if(await new Promise((resolve3,reject)=>{chrome.once("error",reject),chrome.once("spawn",resolve3)}),chromePid=chrome.pid??0,!chromePid)throw new Error("Chrome launched without a process id");chrome.unref();let cdpPort=await waitForActivePort(userDataDir);session=new CdpSession({port:cdpPort,userDataDir});let copiedCookieCount=await cdpImportCookies(session,cookies),account;if(ticket){let login=await cdpConsumeTdbankSso(session,ticket.ssoUrl,ticket.account.loginId);account={accountId:ticket.account.accountId,loginId:ticket.account.loginId,nickname:login.nickname}}input.url&&await(await session.getBrowserClient()).sendCommand("Target.createTarget",{url:input.url,background:headless}),session.close(),session=null;let host=spawn3(process.execPath,[deps.nativeHostScript,"--daemon","--cdp-port",String(cdpPort),"--cdp-user-data-dir",userDataDir,"--browser-id",browserId,"--browser-name",name],{detached:!0,stdio:"ignore",windowsHide:!0});if(await new Promise((resolve3,reject)=>{host.once("error",reject),host.once("spawn",resolve3)}),hostPid=host.pid??0,!hostPid)throw new Error("Native host launched without a process id");host.unref();let record2={pid:chromePid,hostPid,browserId,name,headless,persistent,userDataDir,executablePath,cdpPort,createdAt:new Date().toISOString(),account,...copyCookieDomains.length>0?{copiedCookies:{domains:copyCookieDomains,count:copiedCookieCount}}:{}};return writeRecord(keyedConfigFile(MANAGED_BROWSERS_SUBDIR,browserId),record2),recordWritten=!0,await waitForBrowserRegistration(browserId,hostPid),deps.log(`managed browser launched: ${browserId}, chrome=${chromePid}, host=${hostPid}`),{...browserSummary(record2,!0),created:!0,reused:!1}}catch(error48){throw session?.close(),hostPid&&await stopProcess(hostPid,`--browser-id ${browserId}`),chromePid&&await stopProcess(chromePid,userDataDir),recordWritten&&removeRecord(keyedConfigFile(MANAGED_BROWSERS_SUBDIR,browserId)),persistent||rmSync2(userDataDir,{recursive:!0,force:!0}),error48}finally{releaseLock?.(),closeSync3(logFd)}}async function closeManagedBrowser(selector,options={}){let record2=findManagedRecord(selector);if(!record2)throw new Error(`Managed browser not found: ${selector}`);await stopProcess(record2.pid,record2.userDataDir);let closingOwnHost=record2.hostPid===process.pid;closingOwnHost||await stopProcess(record2.hostPid,`--browser-id ${record2.browserId}`),removeRecord(keyedConfigFile(MANAGED_BROWSERS_SUBDIR,record2.browserId)),removeRecord(keyedConfigFile("browsers",record2.browserId));let deleteProfile=options.deleteProfile===!0||!record2.persistent;return deleteProfile&&rmSync2(record2.userDataDir,{recursive:!0,force:!0}),closingOwnHost&&setTimeout(()=>process.kill(process.pid,"SIGTERM"),250).unref(),{browserId:record2.browserId,closed:!0,profileDeleted:deleteProfile}}import{existsSync as existsSync9,readFileSync as readFileSync7}from"node:fs";import{spawn as spawn5}from"node:child_process";import{homedir as homedir2}from"node:os";import{dirname as dirname6,join as join6,parse,resolve as resolve2}from"node:path";import{fileURLToPath as fileURLToPath2}from"node:url";function positiveIntegerMinutes(value,name,fallback){if(value===void 0||!value.trim())return fallback;let minutes=Number(value);if(!Number.isInteger(minutes)||minutes<=0)throw new Error(`${name} must be a positive integer in minutes`);return minutes}function resolveAgentBayLifecycleConfig(env=process.env){let idleReleaseTimeout=positiveIntegerMinutes(env.MEARL_AGENTBAY_IDLE_RELEASE_MINUTES,"MEARL_AGENTBAY_IDLE_RELEASE_MINUTES",30),maxRuntime=positiveIntegerMinutes(env.MEARL_AGENTBAY_MAX_RUNTIME_MINUTES,"MEARL_AGENTBAY_MAX_RUNTIME_MINUTES",120);if(idleReleaseTimeout<3)throw new Error("MEARL_AGENTBAY_IDLE_RELEASE_MINUTES must be at least 3");if(maxRuntime<idleReleaseTimeout)throw new Error("MEARL_AGENTBAY_MAX_RUNTIME_MINUTES must be greater than or equal to MEARL_AGENTBAY_IDLE_RELEASE_MINUTES");return{idleReleaseTimeout,maxRuntime}}var AgentBaySessionWatchdog=class{idleTimeoutMs;checkIntervalMs;now;keepAlive;close;log;activeRequests=0;lastActivityAt;timer=null;checking=!1;closing=!1;stopped=!1;constructor(options){if(!Number.isFinite(options.idleTimeoutMs)||options.idleTimeoutMs<=0)throw new Error("AgentBay idle timeout must be positive");if(this.idleTimeoutMs=options.idleTimeoutMs,this.checkIntervalMs=options.checkIntervalMs??6e4,!Number.isFinite(this.checkIntervalMs)||this.checkIntervalMs<=0)throw new Error("AgentBay lifecycle check interval must be positive");this.now=options.now??Date.now,this.keepAlive=options.keepAlive,this.close=options.close,this.log=options.log,this.lastActivityAt=this.now()}start(){this.timer||this.stopped||(this.timer=setInterval(()=>void this.checkNow(),this.checkIntervalMs),this.timer.unref())}stop(){this.stopped=!0,this.timer&&(clearInterval(this.timer),this.timer=null)}beginActivity(){return this.stopped||this.closing?!1:(this.activeRequests+=1,this.lastActivityAt=this.now(),!0)}endActivity(){this.activeRequests>0&&(this.activeRequests-=1),this.lastActivityAt=this.now()}async checkNow(){if(!(this.stopped||this.checking||this.closing)){this.checking=!0;try{let idleForMs=this.now()-this.lastActivityAt;if(this.activeRequests>0||idleForMs<this.idleTimeoutMs){try{await this.keepAlive()}catch(error48){this.log("AgentBay keepalive failed:",error48 instanceof Error?error48.message:String(error48))}return}this.closing=!0,this.log(`AgentBay browser reached the idle timeout after ${idleForMs}ms; closing`);try{await this.close()}catch(error48){this.closing=!1,this.log("AgentBay idle close failed:",error48 instanceof Error?error48.message:String(error48))}}finally{this.checking=!1}}}};var AGENTBAY_BROWSERS_SUBDIR="agentbay-browsers",DEFAULT_AGENTBAY_IMAGE_ID="imgc-0aae4rgl8kvagdv1j",sdkPromise=null;async function loadSdk(){return sdkPromise??=Promise.resolve().then(()=>(init_agentbay_sdk(),agentbay_sdk_exports)),sdkPromise}async function createClient(apiKey){let{AgentBay:AgentBay2}=await loadSdk();return new AgentBay2({apiKey})}function agentBayBrowserId(name){return`managed:agentbay:${name.toLocaleLowerCase("en-US")}`}function envValue(text,key){for(let line of text.split(/\r?\n/)){let match=/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)\s*$/.exec(line);if(!match||match[1]!==key)continue;let value=(match[2]??"").trim();return value.length>=2&&(value.startsWith('"')&&value.endsWith('"')||value.startsWith("'")&&value.endsWith("'"))?value=value.slice(1,-1):value=value.replace(/\s+#.*$/,"").trim(),value||void 0}}function envFilesUpward(start){let files=[],current=resolve2(start);for(;;){files.push(join6(current,".env"));let parent=dirname6(current);if(parent===current||current===parse(current).root)break;current=parent}return files}function resolveAgentBayApiKey(){let inherited=process.env.AGENTBAY_KEY?.trim()||process.env.AGENTBAY_API_KEY?.trim();if(inherited)return inherited;let moduleDir=dirname6(fileURLToPath2(import.meta.url)),candidates=[...process.env.MEARL_ENV_FILE?[resolve2(process.env.MEARL_ENV_FILE)]:[],...envFilesUpward(process.cwd()),...envFilesUpward(moduleDir),join6(homedir2(),".mearl",".env")];for(let file2 of new Set(candidates))if(existsSync9(file2))try{let text=readFileSync7(file2,"utf8"),value=envValue(text,"AGENTBAY_KEY")??envValue(text,"AGENTBAY_API_KEY");if(value)return value}catch{}throw new Error("AgentBay API key not found. Set AGENTBAY_KEY in the environment, project .env, or ~/.mearl/.env.")}function validateAgentBayInput(input){if(input.headless===!0)throw new Error("headless=true is not supported by the AgentBay browser provider");if(input.executablePath)throw new Error("executablePath is only supported by the local browser provider");if(input.accountId!==void 0||input.havanaId!==void 0||input.site!==void 0||typeof input.query=="string"&&input.query.trim())throw new Error("TDBank login parameters are only supported by the local browser provider")}function resolveReuseMode(value){if(value===void 0)return"never";if(value==="never"||value==="prefer"||value==="require")return value;throw new Error('reuse must be "never", "prefer", or "require"')}function validateReusableAgentBayConfiguration(input,record2){if(input.imageId!==void 0&&resolveAgentBayImageId(input.imageId)!==record2.imageId)throw new Error(`Cannot change imageId while reusing AgentBay browser: ${record2.browserId}`);if(input.persistent!==void 0&&input.persistent!==(record2.persistent===!0))throw new Error(`Cannot change persistent while reusing AgentBay browser: ${record2.browserId}`);if(input.userAgentMode!==void 0&&record2.userAgentMode!==void 0&&input.userAgentMode!==record2.userAgentMode)throw new Error(`Cannot change userAgentMode while reusing AgentBay browser: ${record2.browserId}`)}function resolveAgentBayImageId(value){if(value===void 0)return DEFAULT_AGENTBAY_IMAGE_ID;let imageId=typeof value=="string"?value.trim():"";if(!imageId||imageId.length>128||!/^[A-Za-z0-9][A-Za-z0-9._:-]*$/.test(imageId))throw new Error("imageId must be a valid AgentBay image alias or image ID");return imageId}function agentBayContextName(browserId){return`mearl-browser-${hashKey(browserId)}`}function normalizeDesktopUserAgent(value){let userAgent=typeof value=="string"?value.trim():"";if(!userAgent)throw new Error("Could not determine the control browser user agent");return userAgent.replace(/\bHeadlessChrome\//g,"Chrome/")}function normalizeAgentBayAccessUrl(value){let candidate=typeof value=="string"?value.trim():"";if(candidate)try{let url2=new URL(candidate);return url2.protocol==="https:"||url2.protocol==="http:"?url2.toString():void 0}catch{return}}function browserSummary2(record2,running){return{browserId:record2.browserId,name:record2.name,provider:"agentbay",headless:!1,persistent:record2.persistent===!0,agentbaySessionId:record2.sessionId,...record2.imageId?{agentbayImageId:record2.imageId}:{},...record2.contextId?{agentbayContextId:record2.contextId}:{},...record2.contextName?{agentbayContextName:record2.contextName}:{},createdAt:record2.createdAt,...record2.copiedCookies?{copiedCookies:record2.copiedCookies}:{},running}}function listRecords2(){let records=[];for(let file2 of listRecordFiles(keyedDir(AGENTBAY_BROWSERS_SUBDIR))){let stored=readRecord(file2);if(!stored){removeRecord(file2);continue}let{accessUrl:legacyAccessUrl,...record2}=stored;legacyAccessUrl!==void 0&&writeRecord(file2,record2);let running=isManagedProcess(record2.pid,`--browser-id ${record2.browserId}`);running||removeRecord(keyedConfigFile("browsers",record2.browserId)),records.push({record:record2,running})}return records}function findRecordWithStatus(selector){let normalized=selector.trim().toLowerCase();return listRecords2().find(({record:record2})=>record2.browserId.toLowerCase()===normalized||record2.name.toLowerCase()===normalized)??null}function findRecord(selector){return findRecordWithStatus(selector)?.record??null}function hasAgentBayBrowser(selector){return findRecord(selector)!==null}function listAgentBayBrowsers(){return listRecords2().map(({record:record2,running})=>browserSummary2(record2,running))}async function requireSession(sessionId,apiKey){let agentBay=await createClient(apiKey);return requireSessionFromClient(agentBay,sessionId)}async function requireSessionFromClient(agentBay,sessionId){let result=await agentBay.get(sessionId);if(!result.success||!result.session)throw new Error(result.errorMessage||`AgentBay session not found: ${sessionId}`);return result.session}async function getAgentBaySession(sessionId,dependencies={}){let apiKey=(dependencies.resolveApiKey??resolveAgentBayApiKey)(),agentBay=dependencies.createAgentBayClient?await dependencies.createAgentBayClient(apiKey):await createClient(apiKey);return requireSessionFromClient(agentBay,sessionId)}async function getAgentBayAccessUrl(sessionId,dependencies={}){let apiKey=(dependencies.resolveApiKey??resolveAgentBayApiKey)(),agentBay=dependencies.createAgentBayClient?await dependencies.createAgentBayClient(apiKey):await createClient(apiKey),session=await requireSessionFromClient(agentBay,sessionId);if(!session.info)throw new Error("The installed AgentBay SDK does not support live session information");let result=await session.info();if(result.success===!1)throw new Error(result.errorMessage||`AgentBay session info failed: ${sessionId}`);let data=result.data&&typeof result.data=="object"?result.data:null,accessUrl=normalizeAgentBayAccessUrl(data&&"resourceUrl"in data?data.resourceUrl:void 0);if(!accessUrl)throw new Error(`AgentBay session did not return a browser access URL: ${sessionId}`);return accessUrl}async function resolvePersistentContext(agentBay,browserId){if(!agentBay.context)throw new Error("The installed AgentBay SDK does not support persistent browser contexts");let name=agentBayContextName(browserId),result=await agentBay.context.get(name,!0);if(!result.success||!result.context?.id)throw new Error(result.errorMessage||`Failed to create AgentBay browser context: ${name}`);return{id:result.context.id,name:result.context.name||name}}async function resolveAgentBayEndpoint(sessionId){let apiKey=resolveAgentBayApiKey(),{AgentBay:AgentBay2,GetCdpLinkRequest:GetCdpLinkRequest2}=await loadSdk(),response=await new AgentBay2({apiKey}).client.getCdpLink(new GetCdpLinkRequest2({authorization:`Bearer ${apiKey}`,sessionId})),endpoint=response.body?.success?response.body.data?.url:void 0;if(!endpoint)throw new Error(response.body?.message||`Failed to get AgentBay CDP link: ${sessionId}`);let url2=new URL(endpoint);if(url2.protocol!=="ws:"&&url2.protocol!=="wss:")throw new Error(`AgentBay returned an unsupported CDP endpoint: ${url2.protocol}`);return url2.toString()}async function keepAgentBaySessionAlive(sessionId){let result=await(await requireSession(sessionId,resolveAgentBayApiKey())).keepAlive();if(result.success===!1)throw new Error(result.errorMessage||"AgentBay keepalive failed")}async function configureAgentBayBrowserSession(session,input,cookies,connectCdp=url2=>CdpClient.connect(url2)){let endpoint=await session.browser.getEndpointUrl(),cdp=await connectCdp(endpoint);try{await cdp.sendCommand("Browser.getVersion",{},1e4);let copiedCookieCount=await cdpImportCookiesWithClient(cdp,cookies);return input.url&&await cdp.sendCommand("Target.createTarget",{url:input.url,background:!1}),copiedCookieCount}finally{cdp.close()}}async function initializeAgentBayBrowserSession(session,input,cookies,options={}){if(!await session.browser.initializeAsync(options.userAgent?{userAgent:options.userAgent}:{}))throw new Error("AgentBay browser initialization failed");return configureAgentBayBrowserSession(session,input,cookies,options.connectCdp)}async function reuseAgentBayBrowserSession(session,input,cookies,options={}){return configureAgentBayBrowserSession(session,input,cookies,options.connectCdp)}async function launchAgentBayBrowser(input,deps){let name=validateName(input.name),browserId=agentBayBrowserId(name);validateAgentBayInput(input);let reuseMode=resolveReuseMode(input.reuse),imageId=resolveAgentBayImageId(input.imageId),persistent=input.persistent===!0,userAgentMode=resolveUserAgentMode(input.userAgentMode),cookieCopy=resolveCookieCopyPlan(input.copyCookieDomains),copyCookieDomains=cookieCopy.domains,apiKey=(deps.resolveApiKey??resolveAgentBayApiKey)(),lifecycle=resolveAgentBayLifecycleConfig(),releaseLock=acquireLaunchLock(browserId),persistBrowserRecord=deps.persistBrowserRecord??(record2=>writeRecord(keyedConfigFile(AGENTBAY_BROWSERS_SUBDIR,record2.browserId),record2)),findBrowserRecord=deps.findBrowserRecord??findRecordWithStatus,session=null,context,hostPid=0,recordWritten=!1;try{let existing=findBrowserRecord(browserId);if(existing){if(reuseMode==="never")throw new Error(`AgentBay browser already exists: ${browserId}`);if(!existing.running)throw new Error(`AgentBay browser is not running and cannot be reused: ${browserId}`);validateReusableAgentBayConfiguration(input,existing.record);let exportedCookies2=copyCookieDomains.length>0?await deps.exportCookies(copyCookieDomains):[],cookies2=cookieCopy.select(exportedCookies2),agentBay2=await(deps.createAgentBayClient??createClient)(apiKey),existingSession=await requireSessionFromClient(agentBay2,existing.record.sessionId),copiedCookieCount2=await reuseAgentBayBrowserSession(existingSession,input,cookies2,{connectCdp:deps.connectCdp}),record3={...existing.record,...copyCookieDomains.length>0?{copiedCookies:{domains:copyCookieDomains,count:copiedCookieCount2}}:{}};return copyCookieDomains.length>0&&persistBrowserRecord(record3),deps.log(`AgentBay browser reused: ${browserId}, host=${record3.pid}`),{...browserSummary2(record3,!0),created:!1,reused:!0}}if(reuseMode==="require")throw new Error(`AgentBay browser is not running and reuse=require: ${browserId}`);let[exportedCookies,userAgent]=await Promise.all([copyCookieDomains.length>0?deps.exportCookies(copyCookieDomains):Promise.resolve([]),userAgentMode==="desktop"?deps.getBrowserUserAgent().then(normalizeDesktopUserAgent):Promise.resolve(void 0)]),cookies=cookieCopy.select(exportedCookies),agentBay=await(deps.createAgentBayClient??createClient)(apiKey);context=persistent?await resolvePersistentContext(agentBay,browserId):void 0;let{LifecyclePolicy:LifecyclePolicy2}=await loadSdk(),created=await agentBay.create({imageId,framework:"mearl",lifecyclePolicy:new LifecyclePolicy2(lifecycle),...context?{browserContext:{contextId:context.id,autoUpload:!0,syncMode:"standard"}}:{}});if(!created.success||!created.session)throw new Error(created.errorMessage||"AgentBay session creation failed");session=created.session;let copiedCookieCount=await initializeAgentBayBrowserSession(session,input,cookies,{userAgent,connectCdp:deps.connectCdp}),host=spawn5(process.execPath,[deps.nativeHostScript,"--daemon","--agentbay-session-id",session.sessionId,"--browser-id",browserId,"--browser-name",name,"--agentbay-idle-release-minutes",String(lifecycle.idleReleaseTimeout)],{detached:!0,stdio:"ignore",windowsHide:!0});if(await new Promise((resolveSpawn,rejectSpawn)=>{host.once("error",rejectSpawn),host.once("spawn",resolveSpawn)}),hostPid=host.pid??0,!hostPid)throw new Error("AgentBay native host launched without a process id");host.unref();let record2={pid:hostPid,browserId,name,sessionId:session.sessionId,imageId,userAgentMode,persistent,...context?{contextId:context.id,contextName:context.name}:{},createdAt:new Date().toISOString(),...copyCookieDomains.length>0?{copiedCookies:{domains:copyCookieDomains,count:copiedCookieCount}}:{}};return persistBrowserRecord(record2),recordWritten=!0,await waitForBrowserRegistration(browserId,hostPid),deps.log(`AgentBay browser launched: ${browserId}, host=${hostPid}`),{...browserSummary2(record2,!0),created:!0,reused:!1}}catch(error48){if(hostPid&&await stopProcess(hostPid,`--browser-id ${browserId}`),recordWritten&&(removeRecord(keyedConfigFile(AGENTBAY_BROWSERS_SUBDIR,browserId)),removeRecord(keyedConfigFile("browsers",browserId))),session){let cleanupError;try{let deleted=await session.delete(!1);deleted.success||(cleanupError=new Error(deleted.errorMessage||"AgentBay session deletion failed"))}catch(deleteError){cleanupError=deleteError}if(cleanupError){let recoveryRecord={pid:hostPid,browserId,name,sessionId:session.sessionId,imageId,userAgentMode,persistent,...context?{contextId:context.id,contextName:context.name}:{},createdAt:new Date().toISOString()},recoverySaved=!1,recoveryError;try{persistBrowserRecord(recoveryRecord),recoverySaved=!0}catch(writeError){recoveryError=writeError}throw deps.log(`AgentBay launch cleanup failed for ${session.sessionId}:`,cleanupError instanceof Error?cleanupError.message:String(cleanupError)),recoveryError&&deps.log(`AgentBay recovery metadata could not be saved for ${session.sessionId}:`,recoveryError instanceof Error?recoveryError.message:String(recoveryError)),new AggregateError(recoveryError?[error48,cleanupError,recoveryError]:[error48,cleanupError],`${error48 instanceof Error?error48.message:String(error48)}; `+(recoverySaved?"AgentBay session cleanup failed and recovery metadata was retained for browser_close":`AgentBay session cleanup failed; session ${session.sessionId} may require manual deletion`),{cause:error48})}}throw error48}finally{releaseLock()}}function isMissingSessionError(error48){let message=error48 instanceof Error?error48.message:String(error48);return/not[ -]?found|does not exist|already deleted|invalid session/i.test(message)}async function releaseAgentBayBrowserResources(record2,agentBay,options={}){let deleteContext=record2.persistent===!0&&options.deleteProfile===!0,syncContext=record2.persistent===!0&&!deleteContext,contextSynced=!!record2.contextSyncedAt,session;try{session=await requireSessionFromClient(agentBay,record2.sessionId)}catch(error48){if(!isMissingSessionError(error48))throw error48}if(session){if(syncContext&&!contextSynced){if(!session.callMcpTool)throw new Error("The installed AgentBay SDK cannot stop the browser before context sync");let stopped=await session.callMcpTool("stopChrome",{},!1);if(stopped.success===!1)throw new Error(stopped.errorMessage||"AgentBay browser shutdown failed");if(!session.context)throw new Error("The installed AgentBay SDK cannot synchronize browser context state");let synced=await session.context.sync();if(!synced.success)throw new Error(synced.errorMessage||"AgentBay browser context sync failed");contextSynced=!0,record2.contextSyncedAt=new Date().toISOString(),options.persistRecord?.(record2)}try{let result=await session.delete(!1);if(!result.success)throw new Error(result.errorMessage||"AgentBay session deletion failed")}catch(error48){if(!isMissingSessionError(error48))throw error48}}if(deleteContext){if(!record2.contextId||!record2.contextName||!agentBay.context)throw new Error("AgentBay browser context metadata is unavailable for profile deletion");let result=await agentBay.context.delete({id:record2.contextId,name:record2.contextName});if(!result.success)throw new Error(result.errorMessage||"AgentBay context deletion failed")}return{sessionDeleted:!0,...syncContext?{contextSynced}:{},...deleteContext?{contextDeleted:!0}:{}}}async function closeAgentBayBrowser(selector,options={}){let record2=findRecord(selector);if(!record2)throw new Error(`AgentBay browser not found: ${selector}`);let agentBay=await createClient(resolveAgentBayApiKey()),releaseLock=acquireLaunchLock(record2.browserId);try{if(record2=findRecord(record2.browserId),!record2)throw new Error(`AgentBay browser not found: ${selector}`);let released=await releaseAgentBayBrowserResources(record2,agentBay,{...options,persistRecord:updatedRecord=>writeRecord(keyedConfigFile(AGENTBAY_BROWSERS_SUBDIR,updatedRecord.browserId),updatedRecord)}),closingOwnHost=record2.pid===process.pid;return closingOwnHost||await stopProcess(record2.pid,`--browser-id ${record2.browserId}`),removeRecord(keyedConfigFile(AGENTBAY_BROWSERS_SUBDIR,record2.browserId)),removeRecord(keyedConfigFile("browsers",record2.browserId)),closingOwnHost&&setTimeout(()=>process.kill(process.pid,"SIGTERM"),250).unref(),{browserId:record2.browserId,provider:"agentbay",closed:!0,...released,...record2.persistent===!0?{profileDeleted:options.deleteProfile===!0}:{profileDeleted:!0}}}finally{releaseLock()}}import{randomUUID as randomUUID6}from"node:crypto";import{basename as basename3,posix}from"node:path";var AGENTBAY_FILE_UPLOAD_WAIT_SECONDS=120;function pageUploadTargets(action,data){return action==="page_upload"?[{data}]:action!=="run_actions"||!Array.isArray(data?.actions)?[]:data.actions.flatMap((step,index)=>step?.action==="page_upload"?[{data:step.data,step:index}]:[])}function validateFilePaths(target){let filePaths=target.data?.filePaths;if(!Array.isArray(filePaths)||filePaths.length===0||filePaths.some(filePath=>typeof filePath!="string"||filePath.length===0)){let prefix=target.step===void 0?"":`Step ${target.step}: `;throw new Error(`${prefix}Invalid filePaths: must be a non-empty array of file path strings`)}return filePaths}function uploadError(result){return result.errorMessage??result.error_message??result.error??"unknown error"}async function stageAgentBayPageUploads(sessionId,action,data,dependencies={}){let targets=pageUploadTargets(action,data);if(targets.length===0)return data;let targetFilePaths=targets.map(target=>validateFilePaths(target)),fileSystem=(await(dependencies.getSession??getAgentBaySession)(sessionId)).fileSystem;if(!fileSystem)throw new Error("The installed AgentBay SDK does not support session file transfer");let contextPath=await fileSystem.getFileTransferContextPath();if(!contextPath)throw new Error(`AgentBay file transfer context is unavailable for session ${sessionId}`);let createTransferId=dependencies.createTransferId??randomUUID6,stagedPaths=await Promise.all(targetFilePaths.map(filePaths=>Promise.all(filePaths.map(async localPath=>{let remoteDirectory=posix.join(contextPath,createTransferId()),directoryResult=await fileSystem.createDirectory(remoteDirectory);if(directoryResult?.success===!1)throw new Error(`Failed to prepare AgentBay upload for ${basename3(localPath)}: ${uploadError(directoryResult)}`);let remotePath=posix.join(remoteDirectory,basename3(localPath)),result=await fileSystem.uploadFile(localPath,remotePath,{wait:!0,waitTimeout:AGENTBAY_FILE_UPLOAD_WAIT_SECONDS});if(result?.success!==!0)throw new Error(`Failed to upload ${basename3(localPath)} to AgentBay: ${uploadError(result)}`);return remotePath}))));if(action==="page_upload")return{...data,filePaths:stagedPaths[0]};let runActions=data,targetIndex=0;return{...runActions,actions:runActions.actions.map(step=>{if(step.action!=="page_upload")return step;let filePaths=stagedPaths[targetIndex++];return{...step,data:{...step.data,filePaths}}})}}var BROWSERS_SUBDIR="browsers",STALE_RECORD_TTL_MS=5*6e4,FOCUS_WRITE_THROTTLE_MS=1e3,identity=null,logFn2=()=>{};function initBrowserRegistry(deps){logFn2=deps.log}function recordFileFor2(browserId){return keyedConfigFile(BROWSERS_SUBDIR,browserId)}function ownsRecord(browserId){let existing=readRecord(recordFileFor2(browserId));return!existing||existing.pid===process.pid||!isAlive(existing.pid)}function persist(patch){if(!identity)return;let file2=recordFileFor2(identity.browserId);if(!ownsRecord(identity.browserId))return;let previous=readRecord(file2),record2={pid:process.pid,browserId:identity.browserId,socketPath:identity.socketPath,browserName:identity.browserName,nativeHostVersion:identity.nativeHostVersion,transport:identity.transport,startedAt:identity.startedAt,lastFocusedAt:previous?.lastFocusedAt,extensionVersion:previous?.extensionVersion,...patch,updatedAt:Date.now()};try{writeRecord(file2,record2)}catch(error48){logFn2("browser-registry: failed to write record:",String(error48))}}function registerBrowser(info){let startedAt=identity?.startedAt??new Date().toISOString();identity={browserId:info.browserId,socketPath:info.socketPath,browserName:info.browserName,nativeHostVersion:info.nativeHostVersion,transport:info.transport,startedAt};let previous=readRecord(recordFileFor2(info.browserId));persist({lastFocusedAt:previous?.lastFocusedAt??info.lastFocusedAt??Date.now(),extensionVersion:info.extensionVersion}),logFn2(`browser-registry: registered ${info.browserName} (${info.browserId})`)}var lastFocusWriteAt=0,focusFlushTimer=null;function writeFocusNow(){lastFocusWriteAt=Date.now(),persist({lastFocusedAt:lastFocusWriteAt})}function touchFocus(){if(!identity)return;let elapsed=Date.now()-lastFocusWriteAt;if(elapsed>=FOCUS_WRITE_THROTTLE_MS){writeFocusNow();return}focusFlushTimer||(focusFlushTimer=setTimeout(()=>{focusFlushTimer=null,writeFocusNow()},FOCUS_WRITE_THROTTLE_MS-elapsed),focusFlushTimer.unref())}function unregisterBrowser(){if(focusFlushTimer&&(clearTimeout(focusFlushTimer),focusFlushTimer=null),!identity)return;let file2=recordFileFor2(identity.browserId),existing=readRecord(file2);existing&&existing.pid!==process.pid||removeRecord(file2)}function pruneDeadBrowsers(){let now=Date.now();for(let file2 of listRecordFiles(keyedDir(BROWSERS_SUBDIR))){let rec=readRecord(file2);if(!rec){removeRecord(file2);continue}isAlive(rec.pid)||now-(rec.updatedAt??0)>STALE_RECORD_TTL_MS&&removeRecord(file2)}}function listRegisteredBrowsers(){let records=[];for(let file2 of listRecordFiles(keyedDir(BROWSERS_SUBDIR))){let record2=readRecord(file2);record2&&isAlive(record2.pid)&&records.push(record2)}return records.sort((a,b)=>(b.lastFocusedAt??0)-(a.lastFocusedAt??0)||(b.updatedAt??0)-(a.updatedAt??0))}async function ensureDiscoverableCdpBrowser(discovery){return discovery.isPublished()?!0:await discovery.isAvailable()?(discovery.publish(),discovery.monitor(),!0):!1}function connectionFields(record2){return{extensionVersion:record2.extensionVersion,nativeHostVersion:record2.nativeHostVersion,transport:record2.transport}}function mergeBrowserInventory(connected,managed){let managedById=new Map(managed.map(browser=>[browser.browserId,browser])),browsers=connected.map(record2=>{let managedBrowser=managedById.get(record2.browserId);return managedBrowser?(managedById.delete(record2.browserId),{browserId:record2.browserId,name:managedBrowser.name,type:"managed",status:"connected",...connectionFields(record2),headless:managedBrowser.headless,persistent:managedBrowser.persistent,provider:managedBrowser.provider,..."cdpPort"in managedBrowser?{cdpPort:managedBrowser.cdpPort}:{},..."agentbaySessionId"in managedBrowser?{agentbaySessionId:managedBrowser.agentbaySessionId}:{},..."agentbayImageId"in managedBrowser&&managedBrowser.agentbayImageId?{agentbayImageId:managedBrowser.agentbayImageId}:{},..."agentbayContextId"in managedBrowser&&managedBrowser.agentbayContextId?{agentbayContextId:managedBrowser.agentbayContextId}:{},..."agentbayContextName"in managedBrowser&&managedBrowser.agentbayContextName?{agentbayContextName:managedBrowser.agentbayContextName}:{},createdAt:managedBrowser.createdAt,..."account"in managedBrowser?{account:managedBrowser.account}:{},..."copiedCookies"in managedBrowser?{copiedCookies:managedBrowser.copiedCookies}:{}}):{browserId:record2.browserId,name:record2.browserName,type:"regular",status:"connected",...connectionFields(record2)}}),disconnected=[...managedById.values()].sort((a,b)=>b.createdAt.localeCompare(a.createdAt)).map(browser=>({browserId:browser.browserId,name:browser.name,type:"managed",status:browser.running?"running_disconnected":"stopped",headless:browser.headless,persistent:browser.persistent,provider:browser.provider,..."cdpPort"in browser?{cdpPort:browser.cdpPort}:{},..."agentbaySessionId"in browser?{agentbaySessionId:browser.agentbaySessionId}:{},..."agentbayImageId"in browser&&browser.agentbayImageId?{agentbayImageId:browser.agentbayImageId}:{},..."agentbayContextId"in browser&&browser.agentbayContextId?{agentbayContextId:browser.agentbayContextId}:{},..."agentbayContextName"in browser&&browser.agentbayContextName?{agentbayContextName:browser.agentbayContextName}:{},createdAt:browser.createdAt,..."account"in browser?{account:browser.account}:{},..."copiedCookies"in browser?{copiedCookies:browser.copiedCookies}:{}}));return browsers.push(...disconnected),{count:browsers.length,connectedCount:connected.length,browsers}}function listBrowserInventory(){let managed=[...listManagedBrowsers(),...listAgentBayBrowsers()];return mergeBrowserInventory(listRegisteredBrowsers(),managed)}import fs5 from"node:fs";import path6 from"node:path";import os2 from"node:os";import{randomUUID as randomUUID7}from"node:crypto";var NATIVE_HOST_VERSION="2.9.6";var MEASUREMENT_ID="G-W84LJDZ6PH",API_SECRET="X233siI5RrGYLhlD0kBKEQ",ENDPOINT=`https://www.google-analytics.com/mp/collect?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`,CLIENT_ID_PATTERN=/^\d+\.\d+$/,BUILD_CHANNEL=NATIVE_HOST_VERSION==="unknown"?"development":"production",CONFIG_DIR=path6.join(os2.homedir(),".mearl"),CONFIG_FILE=path6.join(CONFIG_DIR,"config.json");function readConfig(){try{return JSON.parse(fs5.readFileSync(CONFIG_FILE,"utf-8"))}catch{return{}}}function writeConfig(config2){try{fs5.mkdirSync(CONFIG_DIR,{recursive:!0}),fs5.writeFileSync(CONFIG_FILE,JSON.stringify(config2,null,2))}catch{}}var clientId=null;function createClientId(seed=randomUUID7()){let first=2166136261,second=2246822519;for(let index=0;index<seed.length;index++){let code=seed.charCodeAt(index);first=Math.imul(first^code,16777619)>>>0,second=Math.imul(second^code,3266489917)>>>0}return`${first||1}.${second||1}`}function getClientId(){if(clientId)return clientId;let config2=readConfig();return config2.clientId&&CLIENT_ID_PATTERN.test(config2.clientId)?(clientId=config2.clientId,clientId):(clientId=createClientId(config2.clientId),writeConfig({...config2,clientId}),clientId)}function setAnalyticsClientId(value){return typeof value!="string"||!CLIENT_ID_PATTERN.test(value)?!1:(clientId=value,!0)}function classifyAnalyticsError(error48){let message=error48 instanceof Error?error48.message:String(error48);return/timed?\s*out|timeout/i.test(message)?"timeout":/permission|not authorized|access denied|forbidden/i.test(message)?"permission_denied":/not found|no matching|does not exist/i.test(message)?"not_found":/not connected|disconnected|unavailable|connection (?:failed|closed)/i.test(message)?"unavailable":/invalid|required|must be|unsupported/i.test(message)?"invalid_request":"execution_error"}function trackAction(action,params){let payload={client_id:getClientId(),events:[{name:"agent_action",params:{action,...params,mearl_version:NATIVE_HOST_VERSION,runtime:"native_host",build_channel:BUILD_CHANNEL}}]};fetch(ENDPOINT,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(payload),keepalive:!0}).catch(()=>{})}import{open}from"node:fs/promises";import path8 from"node:path";var TRUNCATED_MARKER=`
|
|
1252
|
+
}`,arguments:[{value:ancestorDepth}],returnByValue:!1});if(ancestorObjectId=ancestor.result?.objectId,!ancestorObjectId||ancestor.result?.subtype==="null")throw new Error("page_snapshot: cannot resolve an ancestor for rootRef");let ancestorBackendNodeId=(await sendCdpDeviceShellPageCommand(session,"DOM.describeNode",{objectId:ancestorObjectId})).node?.backendNodeId;if(ancestorBackendNodeId===void 0)throw new Error("page_snapshot: cannot resolve an ancestor for rootRef");return ancestorBackendNodeId}finally{ancestorObjectId&&await sendCdpDeviceShellPageCommand(session,"Runtime.releaseObject",{objectId:ancestorObjectId}).catch(()=>{}),await sendCdpDeviceShellPageCommand(session,"Runtime.releaseObject",{objectId}).catch(()=>{})}}async function getViewportBackendNodeIds(session){let[metrics,captured]=await Promise.all([sendCdpDeviceShellPageCommand(session,"Page.getLayoutMetrics",{}),sendCdpDeviceShellPageCommand(session,"DOMSnapshot.captureSnapshot",{computedStyles:[],includeDOMRects:!0,includePaintOrder:!1})]),viewport=resolveDOMSnapshotViewportBounds(metrics);if(!viewport)throw new Error("page_snapshot: viewport metrics are unavailable");let{left,top,width,height}=viewport,right=left+width,bottom=top+height,visible=new Set;for(let document2 of captured.documents??[]){let backendNodeIds=document2.nodes?.backendNodeId??[],nodeIndexes=document2.layout?.nodeIndex??[],bounds=document2.layout?.bounds??[];for(let index=0;index<nodeIndexes.length;index+=1){let box=bounds[index],backendNodeId=backendNodeIds[nodeIndexes[index]];if(!box||backendNodeId===void 0)continue;let[x,y,boxWidth,boxHeight]=box;boxWidth<=0||boxHeight<=0||x<right&&x+boxWidth>left&&y<bottom&&y+boxHeight>top&&visible.add(backendNodeId)}}return visible}async function cdpPageSnapshot(session,data){let mode=data?.mode??"full",rootSelector=data?.rootSelector,rootRef=data?.rootRef,ancestorDepth=data?.ancestorDepth??0,query=resolvePageSnapshotQuery(data?.query);if(!["full","interactive","viewport"].includes(mode))throw new Error("page_snapshot: mode must be one of full, interactive, viewport");if(rootSelector!==void 0&&(typeof rootSelector!="string"||!rootSelector.trim()))throw new Error("page_snapshot: rootSelector must be a non-empty CSS selector");if(rootRef!==void 0&&(typeof rootRef!="string"||!/^@e\d+$/.test(rootRef)))throw new Error('page_snapshot: rootRef must be a snapshot ref like "@e3"');if(rootSelector!==void 0&&rootRef!==void 0)throw new Error("page_snapshot: rootSelector and rootRef are mutually exclusive");if(!Number.isInteger(ancestorDepth)||ancestorDepth<0||ancestorDepth>20)throw new Error("page_snapshot: ancestorDepth must be an integer between 0 and 20");if(ancestorDepth>0&&rootRef===void 0)throw new Error("page_snapshot: ancestorDepth requires rootRef");let rootBackendNodeId;if(rootSelector)rootBackendNodeId=await resolveRootBackendNodeId(session,rootSelector);else if(rootRef){let entry=resolvePageRef(session,rootRef);if(!entry)throw new Error(`Ref ${rootRef} not found. Run page_snapshot first to get fresh refs.`);rootBackendNodeId=await resolveAncestorBackendNodeId(session,entry.backendNodeId,ancestorDepth)}let snapshotRefs=beginPageSnapshotRefs(session),[result,visibleBackendNodeIds]=await Promise.all([sendCdpDeviceShellPageCommand(session,rootBackendNodeId===void 0?"Accessibility.getFullAXTree":"Accessibility.queryAXTree",rootBackendNodeId===void 0?{depth:data?.depth}:{backendNodeId:rootBackendNodeId}),mode==="viewport"||mode==="interactive"?getViewportBackendNodeIds(session):Promise.resolve(void 0)]),nodes=result.nodes??[];await reconcileAXCheckedStates(nodes,backendNodeId=>readDOMCheckedState2(session,backendNodeId));let nodeMap=new Map;for(let node of nodes)nodeMap.set(node.nodeId,node);let rootNode=nodes[0];if(!rootNode)return snapshotRefs.commit(new Set),{snapshot:"(empty page)",refs:{},elementCount:0,outputNodeCount:1,mode,...rootSelector?{rootSelector}:{},...rootRef?{rootRef,ancestorDepth}:{},...query?{query,matches:[],matchCount:0}:{}};let rawTree=buildSnapshotTree(nodeMap,rootNode.nodeId,snapshotRefs),viewportFilteredTree=mode==="interactive"?filterSnapshotTree(rawTree,"viewport",visibleBackendNodeIds):rawTree,effectiveMode=mode;mode==="interactive"&&!hasInteractiveSnapshotNode(viewportFilteredTree)&&(effectiveMode="viewport");let modeFilteredTree=mode==="interactive"?effectiveMode==="interactive"?filterSnapshotTree(viewportFilteredTree,"interactive"):viewportFilteredTree:filterSnapshotTree(rawTree,effectiveMode,visibleBackendNodeIds),queryResult=query?filterSnapshotTreeByQuery(modeFilteredTree,query):{tree:modeFilteredTree,matches:[]},limitedMatches=query?limitPageSnapshotQueryMatches(queryResult.matches):{matches:[],truncated:!1},tree=queryResult.tree,lines=[];tree&&formatSnapshotNode(tree,0,lines);let formatted=formatSnapshotWithLimits(lines.length>0?lines:[query?"(no matches)":"(empty page)"],{maxChars:data?.maxChars,maxNodes:data?.maxNodes}),refs={},outputRefKeys=new Set(Array.from(formatted.snapshot.matchAll(/(?:^|\n)\s*(@e\d+)\s/g),match=>match[1]));for(let match of limitedMatches.matches)match.ref&&outputRefKeys.add(match.ref);snapshotRefs.commit(outputRefKeys);let registry2=getPageRefRegistry(session);for(let ref of outputRefKeys){let entry=registry2.resolve(ref);entry&&(refs[ref.slice(1)]={backendNodeId:entry.backendNodeId})}return{snapshot:formatted.snapshot,refs,elementCount:countSnapshotNodes(tree),outputNodeCount:formatted.outputNodeCount,mode,...rootSelector?{rootSelector}:{},...rootRef?{rootRef,ancestorDepth}:{},...query?{query,matches:limitedMatches.matches,matchCount:queryResult.matches.length,...limitedMatches.truncated?{matchesTruncated:!0}:{}}:{},...effectiveMode!==mode?{fallbackMode:"viewport"}:{},...formatted.truncated?{truncated:!0}:{}}}async function cdpPageFrames(session,_data){let result=await session.client.sendCommand("Page.getFrameTree",{});function flattenFrameTree(tree){if(!tree)return[];let{frame,childFrames=[]}=tree;return[{frameId:frame.id,parentFrameId:frame.parentId??null,url:frame.url,name:frame.name??""},...childFrames.flatMap(flattenFrameTree)]}let frames=flattenFrameTree(result.frameTree);return{frames,count:frames.length}}registerActions([{name:"page_snapshot",session:"page",handler:cdpPageSnapshot},{name:"page_frames",session:"page",handler:cdpPageFrames}]);var MEARL_SERVICE_COOKIE_DOMAINS=["tdbank.alibaba-inc.com","ats2.alibaba-inc.com","g.alibaba-inc.com","login.alibaba-inc.com","token-hub.alibaba-inc.com","alibaba-inc.com"],MEARL_SERVICE_COOKIE_HOSTS=new Set(MEARL_SERVICE_COOKIE_DOMAINS);function normalizeCookieDomain2(input){let value=input.trim();if(!value)throw new Error("Cookie domain must be a non-empty string");let hostname3;try{hostname3=new URL(value.includes("://")?value:`https://${value}`).hostname}catch{throw new Error(`Invalid cookie domain: ${input}`)}if(hostname3=hostname3.toLowerCase().replace(/^\.+/,"").replace(/\.+$/,""),!hostname3)throw new Error(`Invalid cookie domain: ${input}`);return hostname3}function normalizeCookieDomains(inputs){if(!Array.isArray(inputs))throw new Error("copyCookieDomains must be an array of domains");return[...new Set(inputs.map(value=>normalizeCookieDomain2(String(value))))]}function isMearlServiceCookie(cookie){let domain2=normalizeCookieDomain2(cookie.domain);return MEARL_SERVICE_COOKIE_HOSTS.has(domain2)?!0:domain2.endsWith(".tdbank.alibaba-inc.com")||domain2.endsWith(".ats2.alibaba-inc.com")}function resolveCookieCopyPlan(input){return input==="mearl-services"?{domains:[...MEARL_SERVICE_COOKIE_DOMAINS],select:cookies=>cookies.filter(isMearlServiceCookie)}:{domains:input===void 0?[]:normalizeCookieDomains(input),select:cookies=>cookies}}function cookieMatchesDomain(cookieDomain,requestedDomain){let cookieHost=cookieDomain.toLowerCase().replace(/^\.+/,"");return cookieHost===requestedDomain||cookieHost.endsWith(`.${requestedDomain}`)||requestedDomain.endsWith(`.${cookieHost}`)}function toTransferableCookie(cookie){let result={name:String(cookie.name),value:String(cookie.value),domain:String(cookie.domain),path:String(cookie.path||"/"),secure:!!cookie.secure,httpOnly:!!cookie.httpOnly};return["Strict","Lax","None"].includes(cookie.sameSite)&&(result.sameSite=cookie.sameSite),typeof cookie.expires=="number"&&cookie.expires>0&&(result.expires=cookie.expires),["Low","Medium","High"].includes(cookie.priority)&&(result.priority=cookie.priority),typeof cookie.sameParty=="boolean"&&(result.sameParty=cookie.sameParty),["Unset","NonSecure","Secure"].includes(cookie.sourceScheme)&&(result.sourceScheme=cookie.sourceScheme),typeof cookie.sourcePort=="number"&&(result.sourcePort=cookie.sourcePort),cookie.partitionKey?.topLevelSite&&(result.partitionKey={topLevelSite:String(cookie.partitionKey.topLevelSite),...typeof cookie.partitionKey.hasCrossSiteAncestor=="boolean"?{hasCrossSiteAncestor:cookie.partitionKey.hasCrossSiteAncestor}:{}}),result}async function cdpExportCookies(session,domains){let requestedDomains=normalizeCookieDomains(domains);return((await(await session.getBrowserClient()).sendCommand("Storage.getCookies",{})).cookies??[]).filter(cookie=>requestedDomains.some(domain2=>cookieMatchesDomain(String(cookie.domain),domain2))).map(toTransferableCookie)}async function cdpImportCookies(session,cookies){if(cookies.length===0)return 0;let browser=await session.getBrowserClient();return cdpImportCookiesWithClient(browser,cookies)}async function cdpImportCookiesWithClient(browser,cookies){return cookies.length===0?0:(await browser.sendCommand("Storage.setCookies",{cookies}),cookies.length)}import{closeSync as closeSync3,existsSync as existsSync3,mkdtempSync,mkdirSync as mkdirSync2,openSync as openSync3,readFileSync as readFileSync3,renameSync as renameSync3,rmSync as rmSync2,writeFileSync as writeFileSync2}from"node:fs";import{spawn as spawn3,spawnSync as spawnSync2}from"node:child_process";import{randomUUID as randomUUID4}from"node:crypto";import{tmpdir}from"node:os";import{join as join3}from"node:path";var MANAGED_BROWSERS_SUBDIR="managed-browsers",MANAGED_BROWSER_LOCKS_SUBDIR="managed-browser-locks",MANAGED_PROFILES_SUBDIR="managed-profiles",LAUNCH_TIMEOUT_MS=15e3;function validateName(value){let name=typeof value=="string"?value.trim():"";if(!name)throw new Error("name is required");if(name.length>64)throw new Error("name must be at most 64 characters");if(/[/\\\0\r\n]/.test(name))throw new Error("name contains unsupported characters");return name}function managedBrowserId(name){return`managed:${name.toLocaleLowerCase("en-US")}`}function hasTdbankSelector(data){return data.accountId!==void 0||data.havanaId!==void 0||typeof data.query=="string"&&data.query.trim().length>0}function validateTdbankSelector(data){if(data.havanaId!==void 0&&data.site===void 0)throw new Error("site is required when havanaId is provided");if([data.accountId!==void 0,data.havanaId!==void 0,typeof data.query=="string"&&data.query.trim().length>0].filter(Boolean).length>1)throw new Error("Use only one of accountId, havanaId + site, or query")}function chromeExecutableCandidates(platform=process.platform){let envPath=process.env.MEARL_CHROME_PATH,candidates=envPath?[envPath]:[];if(platform==="darwin")return candidates.concat(["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary","/Applications/Chromium.app/Contents/MacOS/Chromium"]);if(platform==="win32"){let local=process.env.LOCALAPPDATA??"",programFiles=process.env.PROGRAMFILES??"",programFilesX86=process.env["PROGRAMFILES(X86)"]??"";return candidates.concat([join3(local,"Google","Chrome","Application","chrome.exe"),join3(programFiles,"Google","Chrome","Application","chrome.exe"),join3(programFilesX86,"Google","Chrome","Application","chrome.exe")])}return candidates.concat(["/usr/bin/google-chrome","/usr/bin/google-chrome-stable","/usr/bin/chromium","/usr/bin/chromium-browser"])}function resolveChromeExecutable(explicitPath){if(explicitPath){if(!existsSync3(explicitPath))throw new Error(`Chrome executable not found: ${explicitPath}`);return explicitPath}let found=chromeExecutableCandidates().find(candidate=>candidate&&existsSync3(candidate));if(!found)throw new Error("Chrome executable not found. Set executablePath or MEARL_CHROME_PATH.");return found}function desktopChromeUserAgent(version2,platform=process.platform){if(!/^\d+(?:\.\d+){1,3}$/.test(version2))throw new Error(`Invalid Chrome version: ${version2}`);return`Mozilla/5.0 (${platform==="darwin"?"Macintosh; Intel Mac OS X 10_15_7":platform==="win32"?"Windows NT 10.0; Win64; x64":"X11; Linux x86_64"}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${version2} Safari/537.36`}function resolveChromeVersion(executablePath){let result=spawnSync2(executablePath,["--version"],{encoding:"utf8",windowsHide:!0}),version2=`${result.stdout??""} ${result.stderr??""}`.match(/\b(\d+(?:\.\d+){1,3})\b/)?.[1];if(!version2)throw new Error(`Could not determine Chrome version from: ${executablePath}`);return version2}function resolveUserAgentMode(value){if(value===void 0||value==="default")return"default";if(value==="desktop")return"desktop";throw new Error('userAgentMode must be "default" or "desktop"')}function buildManagedChromeArgs(options){return[`--user-data-dir=${options.userDataDir}`,"--remote-debugging-port=0","--no-first-run","--no-default-browser-check","--disable-background-networking",...options.headless?["--headless=new"]:[],...options.userAgent?[`--user-agent=${options.userAgent}`]:[],"about:blank"]}function browserSummary(record2,running){return{browserId:record2.browserId,name:record2.name,provider:"local",headless:record2.headless,persistent:record2.persistent,cdpPort:record2.cdpPort,createdAt:record2.createdAt,account:record2.account,copiedCookies:record2.copiedCookies,running}}function isManagedProcess(pid,commandMarker,platform=process.platform){if(!isAlive(pid))return!1;try{if(platform==="win32"){let escapedMarker=commandMarker.replace(/'/g,"''");return spawnSync2("powershell.exe",["-NoProfile","-NonInteractive","-Command",`$p = Get-CimInstance Win32_Process -Filter 'ProcessId = ${pid}'; if ($p.CommandLine -and $p.CommandLine.Contains('${escapedMarker}')) { exit 0 } else { exit 1 }`],{windowsHide:!0,stdio:"ignore"}).status===0}let result=spawnSync2("ps",["-p",String(pid),"-o","command="],{encoding:"utf8",stdio:["ignore","pipe","ignore"]});return result.status===0&&result.stdout.includes(commandMarker)}catch{return!1}}function listRecords(){let records=[];for(let file2 of listRecordFiles(keyedDir(MANAGED_BROWSERS_SUBDIR))){let record2=readRecord(file2);if(!record2){removeRecord(file2);continue}let running=isManagedProcess(record2.pid,record2.userDataDir);if(!running&&(signalProcess(record2.hostPid,"SIGTERM",`--browser-id ${record2.browserId}`),removeRecord(keyedConfigFile("browsers",record2.browserId)),!record2.persistent)){removeRecord(file2),rmSync2(record2.userDataDir,{recursive:!0,force:!0});continue}records.push({record:record2,running})}return records}function listManagedBrowsers(){return listRecords().map(({record:record2,running})=>browserSummary(record2,running))}function findManagedRecord(selector){let normalized=selector.trim().toLowerCase();return listRecords().find(({record:record2})=>record2.browserId.toLowerCase()===normalized||record2.name.toLowerCase()===normalized)?.record??null}function hasManagedBrowser(selector){return findManagedRecord(selector)!==null}async function waitForActivePort(userDataDir){let deadline=Date.now()+LAUNCH_TIMEOUT_MS;for(;Date.now()<deadline;){let info=readDevToolsActivePort(userDataDir);if(info)return info.port;await new Promise(resolve3=>setTimeout(resolve3,100))}throw new Error(`Chrome did not expose a CDP port within ${LAUNCH_TIMEOUT_MS}ms`)}async function waitForBrowserRegistration(browserId,expectedPid){let file2=keyedConfigFile("browsers",browserId),deadline=Date.now()+LAUNCH_TIMEOUT_MS;for(;Date.now()<deadline;){if(readRecord(file2)?.pid===expectedPid&&isAlive(expectedPid))return;await new Promise(resolve3=>setTimeout(resolve3,100))}throw new Error(`Managed browser ${browserId} did not register within ${LAUNCH_TIMEOUT_MS}ms`)}function signalProcess(pid,signal,commandMarker){if(isManagedProcess(pid,commandMarker)){if(process.platform==="win32"){spawnSync2("taskkill",["/PID",String(pid),"/T","/F"],{windowsHide:!0,stdio:"ignore"});return}try{process.kill(pid,signal)}catch{}}}async function stopProcess(pid,commandMarker){signalProcess(pid,"SIGTERM",commandMarker);let deadline=Date.now()+3e3;for(;Date.now()<deadline&&isManagedProcess(pid,commandMarker);)await new Promise(resolve3=>setTimeout(resolve3,50));isManagedProcess(pid,commandMarker)&&signalProcess(pid,"SIGKILL",commandMarker)}function profileDirectory(browserId,persistent){if(!persistent)return mkdtempSync(join3(tmpdir(),"mearl-browser-"));let dir=join3(DAEMON_HOME,MANAGED_PROFILES_SUBDIR,hashKey(browserId));return mkdirSync2(dir,{recursive:!0}),dir}async function removeStoppedInstance(browserId){let file2=keyedConfigFile(MANAGED_BROWSERS_SUBDIR,browserId),record2=readRecord(file2);!record2||isManagedProcess(record2.pid,record2.userDataDir)||(await stopProcess(record2.hostPid,`--browser-id ${record2.browserId}`),removeRecord(file2),removeRecord(keyedConfigFile("browsers",record2.browserId)),record2.persistent||rmSync2(record2.userDataDir,{recursive:!0,force:!0}))}function acquireLaunchLock(browserId){let lockDir=keyedDir(MANAGED_BROWSER_LOCKS_SUBDIR),lockFile=keyedConfigFile(MANAGED_BROWSER_LOCKS_SUBDIR,browserId);mkdirSync2(lockDir,{recursive:!0});let token=`${process.pid}:${randomUUID4()}`,tryAcquire=()=>{try{return writeFileSync2(lockFile,token,{flag:"wx"}),!0}catch(error48){if(error48.code!=="EEXIST")throw error48;return!1}};if(!tryAcquire()){let observedToken="";try{observedToken=readFileSync3(lockFile,"utf-8")}catch{}let ownerPid=Number(observedToken.split(":",1)[0]);if(Number.isInteger(ownerPid)&&!isAlive(ownerPid)){let staleFile=`${lockFile}.${process.pid}.${randomUUID4()}.stale`;try{if(readFileSync3(lockFile,"utf-8")!==observedToken)throw new Error("Launch lock owner changed");if(renameSync3(lockFile,staleFile),readFileSync3(staleFile,"utf-8")===observedToken)rmSync2(staleFile,{force:!0});else try{renameSync3(staleFile,lockFile)}catch{}}catch{}}if(!tryAcquire())throw new Error(`Managed browser launch already in progress: ${browserId}`)}return()=>{try{readFileSync3(lockFile,"utf-8")===token&&rmSync2(lockFile,{force:!0})}catch{}}}async function launchManagedBrowser(input,deps){if(input.reuse!==void 0&&input.reuse!=="never"&&input.reuse!=="prefer"&&input.reuse!=="require")throw new Error('reuse must be "never", "prefer", or "require"');if(input.reuse==="prefer"||input.reuse==="require")throw new Error("reuse is currently supported only by the AgentBay browser provider");if(input.imageId!==void 0)throw new Error("imageId is only supported by the AgentBay browser provider");let name=validateName(input.name),browserId=managedBrowserId(name);validateTdbankSelector(input);let cookieCopy=resolveCookieCopyPlan(input.copyCookieDomains),copyCookieDomains=cookieCopy.domains,headless=input.headless!==!1,persistent=input.persistent===!0,executablePath=resolveChromeExecutable(input.executablePath),userAgent=resolveUserAgentMode(input.userAgentMode)==="desktop"?desktopChromeUserAgent(resolveChromeVersion(executablePath)):void 0,userDataDir=profileDirectory(browserId,persistent),logDir=keyedDir(MANAGED_BROWSERS_SUBDIR);mkdirSync2(logDir,{recursive:!0});let logPath=join3(logDir,`${hashKey(browserId)}.log`),logFd=openSync3(logPath,"a"),chromePid=0,hostPid=0,session=null,recordWritten=!1,releaseLock=null;try{if(releaseLock=acquireLaunchLock(browserId),await removeStoppedInstance(browserId),findManagedRecord(browserId))throw new Error(`Managed browser already running: ${browserId}`);let[ticket,exportedCookies]=await Promise.all([hasTdbankSelector(input)?deps.prepareTdbankSso(input):Promise.resolve(void 0),copyCookieDomains.length>0?deps.exportCookies(copyCookieDomains):Promise.resolve([])]),cookies=cookieCopy.select(exportedCookies),chromeArgs=buildManagedChromeArgs({userDataDir,headless,userAgent});rmSync2(join3(userDataDir,"DevToolsActivePort"),{force:!0});let chrome=spawn3(executablePath,chromeArgs,{detached:!0,stdio:["ignore","ignore",logFd],windowsHide:headless});if(await new Promise((resolve3,reject)=>{chrome.once("error",reject),chrome.once("spawn",resolve3)}),chromePid=chrome.pid??0,!chromePid)throw new Error("Chrome launched without a process id");chrome.unref();let cdpPort=await waitForActivePort(userDataDir);session=new CdpSession({port:cdpPort,userDataDir});let copiedCookieCount=await cdpImportCookies(session,cookies),account;if(ticket){let login=await cdpConsumeTdbankSso(session,ticket.ssoUrl,ticket.account.loginId);account={accountId:ticket.account.accountId,loginId:ticket.account.loginId,nickname:login.nickname}}input.url&&await(await session.getBrowserClient()).sendCommand("Target.createTarget",{url:input.url,background:headless}),session.close(),session=null;let host=spawn3(process.execPath,[deps.nativeHostScript,"--daemon","--cdp-port",String(cdpPort),"--cdp-user-data-dir",userDataDir,"--browser-id",browserId,"--browser-name",name,...headless?["--browser-headless"]:[]],{detached:!0,stdio:"ignore",windowsHide:!0});if(await new Promise((resolve3,reject)=>{host.once("error",reject),host.once("spawn",resolve3)}),hostPid=host.pid??0,!hostPid)throw new Error("Native host launched without a process id");host.unref();let record2={pid:chromePid,hostPid,browserId,name,headless,persistent,userDataDir,executablePath,cdpPort,createdAt:new Date().toISOString(),account,...copyCookieDomains.length>0?{copiedCookies:{domains:copyCookieDomains,count:copiedCookieCount}}:{}};return writeRecord(keyedConfigFile(MANAGED_BROWSERS_SUBDIR,browserId),record2),recordWritten=!0,await waitForBrowserRegistration(browserId,hostPid),deps.log(`managed browser launched: ${browserId}, chrome=${chromePid}, host=${hostPid}`),{...browserSummary(record2,!0),created:!0,reused:!1}}catch(error48){throw session?.close(),hostPid&&await stopProcess(hostPid,`--browser-id ${browserId}`),chromePid&&await stopProcess(chromePid,userDataDir),recordWritten&&removeRecord(keyedConfigFile(MANAGED_BROWSERS_SUBDIR,browserId)),persistent||rmSync2(userDataDir,{recursive:!0,force:!0}),error48}finally{releaseLock?.(),closeSync3(logFd)}}async function closeManagedBrowser(selector,options={}){let record2=findManagedRecord(selector);if(!record2)throw new Error(`Managed browser not found: ${selector}`);await stopProcess(record2.pid,record2.userDataDir);let closingOwnHost=record2.hostPid===process.pid;closingOwnHost||await stopProcess(record2.hostPid,`--browser-id ${record2.browserId}`),removeRecord(keyedConfigFile(MANAGED_BROWSERS_SUBDIR,record2.browserId)),removeRecord(keyedConfigFile("browsers",record2.browserId));let deleteProfile=options.deleteProfile===!0||!record2.persistent;return deleteProfile&&rmSync2(record2.userDataDir,{recursive:!0,force:!0}),closingOwnHost&&setTimeout(()=>process.kill(process.pid,"SIGTERM"),250).unref(),{browserId:record2.browserId,closed:!0,profileDeleted:deleteProfile}}import{existsSync as existsSync9,readFileSync as readFileSync7}from"node:fs";import{spawn as spawn5}from"node:child_process";import{homedir as homedir2}from"node:os";import{dirname as dirname6,join as join6,parse,resolve as resolve2}from"node:path";import{fileURLToPath as fileURLToPath2}from"node:url";function positiveIntegerMinutes(value,name,fallback){if(value===void 0||!value.trim())return fallback;let minutes=Number(value);if(!Number.isInteger(minutes)||minutes<=0)throw new Error(`${name} must be a positive integer in minutes`);return minutes}function resolveAgentBayLifecycleConfig(env=process.env){let idleReleaseTimeout=positiveIntegerMinutes(env.MEARL_AGENTBAY_IDLE_RELEASE_MINUTES,"MEARL_AGENTBAY_IDLE_RELEASE_MINUTES",30),maxRuntime=positiveIntegerMinutes(env.MEARL_AGENTBAY_MAX_RUNTIME_MINUTES,"MEARL_AGENTBAY_MAX_RUNTIME_MINUTES",120);if(idleReleaseTimeout<3)throw new Error("MEARL_AGENTBAY_IDLE_RELEASE_MINUTES must be at least 3");if(maxRuntime<idleReleaseTimeout)throw new Error("MEARL_AGENTBAY_MAX_RUNTIME_MINUTES must be greater than or equal to MEARL_AGENTBAY_IDLE_RELEASE_MINUTES");return{idleReleaseTimeout,maxRuntime}}var AgentBaySessionWatchdog=class{idleTimeoutMs;checkIntervalMs;now;keepAlive;close;log;activeRequests=0;lastActivityAt;timer=null;checking=!1;closing=!1;stopped=!1;constructor(options){if(!Number.isFinite(options.idleTimeoutMs)||options.idleTimeoutMs<=0)throw new Error("AgentBay idle timeout must be positive");if(this.idleTimeoutMs=options.idleTimeoutMs,this.checkIntervalMs=options.checkIntervalMs??6e4,!Number.isFinite(this.checkIntervalMs)||this.checkIntervalMs<=0)throw new Error("AgentBay lifecycle check interval must be positive");this.now=options.now??Date.now,this.keepAlive=options.keepAlive,this.close=options.close,this.log=options.log,this.lastActivityAt=this.now()}start(){this.timer||this.stopped||(this.timer=setInterval(()=>void this.checkNow(),this.checkIntervalMs),this.timer.unref())}stop(){this.stopped=!0,this.timer&&(clearInterval(this.timer),this.timer=null)}beginActivity(){return this.stopped||this.closing?!1:(this.activeRequests+=1,this.lastActivityAt=this.now(),!0)}endActivity(){this.activeRequests>0&&(this.activeRequests-=1),this.lastActivityAt=this.now()}async checkNow(){if(!(this.stopped||this.checking||this.closing)){this.checking=!0;try{let idleForMs=this.now()-this.lastActivityAt;if(this.activeRequests>0||idleForMs<this.idleTimeoutMs){try{await this.keepAlive()}catch(error48){this.log("AgentBay keepalive failed:",error48 instanceof Error?error48.message:String(error48))}return}this.closing=!0,this.log(`AgentBay browser reached the idle timeout after ${idleForMs}ms; closing`);try{await this.close()}catch(error48){this.closing=!1,this.log("AgentBay idle close failed:",error48 instanceof Error?error48.message:String(error48))}}finally{this.checking=!1}}}};var AGENTBAY_BROWSERS_SUBDIR="agentbay-browsers",DEFAULT_AGENTBAY_IMAGE_ID="imgc-0aae4rgl8kvagdv1j",sdkPromise=null;async function loadSdk(){return sdkPromise??=Promise.resolve().then(()=>(init_agentbay_sdk(),agentbay_sdk_exports)),sdkPromise}async function createClient(apiKey){let{AgentBay:AgentBay2}=await loadSdk();return new AgentBay2({apiKey})}function agentBayBrowserId(name){return`managed:agentbay:${name.toLocaleLowerCase("en-US")}`}function envValue(text,key){for(let line of text.split(/\r?\n/)){let match=/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)\s*$/.exec(line);if(!match||match[1]!==key)continue;let value=(match[2]??"").trim();return value.length>=2&&(value.startsWith('"')&&value.endsWith('"')||value.startsWith("'")&&value.endsWith("'"))?value=value.slice(1,-1):value=value.replace(/\s+#.*$/,"").trim(),value||void 0}}function envFilesUpward(start){let files=[],current=resolve2(start);for(;;){files.push(join6(current,".env"));let parent=dirname6(current);if(parent===current||current===parse(current).root)break;current=parent}return files}function resolveAgentBayApiKey(){let inherited=process.env.AGENTBAY_KEY?.trim()||process.env.AGENTBAY_API_KEY?.trim();if(inherited)return inherited;let moduleDir=dirname6(fileURLToPath2(import.meta.url)),candidates=[...process.env.MEARL_ENV_FILE?[resolve2(process.env.MEARL_ENV_FILE)]:[],...envFilesUpward(process.cwd()),...envFilesUpward(moduleDir),join6(homedir2(),".mearl",".env")];for(let file2 of new Set(candidates))if(existsSync9(file2))try{let text=readFileSync7(file2,"utf8"),value=envValue(text,"AGENTBAY_KEY")??envValue(text,"AGENTBAY_API_KEY");if(value)return value}catch{}throw new Error("AgentBay API key not found. Set AGENTBAY_KEY in the environment, project .env, or ~/.mearl/.env.")}function validateAgentBayInput(input){if(input.headless===!0)throw new Error("headless=true is not supported by the AgentBay browser provider");if(input.executablePath)throw new Error("executablePath is only supported by the local browser provider");if(input.accountId!==void 0||input.havanaId!==void 0||input.site!==void 0||typeof input.query=="string"&&input.query.trim())throw new Error("TDBank login parameters are only supported by the local browser provider")}function resolveReuseMode(value){if(value===void 0)return"never";if(value==="never"||value==="prefer"||value==="require")return value;throw new Error('reuse must be "never", "prefer", or "require"')}function validateReusableAgentBayConfiguration(input,record2){if(input.imageId!==void 0&&resolveAgentBayImageId(input.imageId)!==record2.imageId)throw new Error(`Cannot change imageId while reusing AgentBay browser: ${record2.browserId}`);if(input.persistent!==void 0&&input.persistent!==(record2.persistent===!0))throw new Error(`Cannot change persistent while reusing AgentBay browser: ${record2.browserId}`);if(input.userAgentMode!==void 0&&record2.userAgentMode!==void 0&&input.userAgentMode!==record2.userAgentMode)throw new Error(`Cannot change userAgentMode while reusing AgentBay browser: ${record2.browserId}`)}function resolveAgentBayImageId(value){if(value===void 0)return DEFAULT_AGENTBAY_IMAGE_ID;let imageId=typeof value=="string"?value.trim():"";if(!imageId||imageId.length>128||!/^[A-Za-z0-9][A-Za-z0-9._:-]*$/.test(imageId))throw new Error("imageId must be a valid AgentBay image alias or image ID");return imageId}function agentBayContextName(browserId){return`mearl-browser-${hashKey(browserId)}`}function normalizeDesktopUserAgent(value){let userAgent=typeof value=="string"?value.trim():"";if(!userAgent)throw new Error("Could not determine the control browser user agent");return userAgent.replace(/\bHeadlessChrome\//g,"Chrome/")}function normalizeAgentBayAccessUrl(value){let candidate=typeof value=="string"?value.trim():"";if(candidate)try{let url2=new URL(candidate);return url2.protocol==="https:"||url2.protocol==="http:"?url2.toString():void 0}catch{return}}function browserSummary2(record2,running){return{browserId:record2.browserId,name:record2.name,provider:"agentbay",headless:!1,persistent:record2.persistent===!0,agentbaySessionId:record2.sessionId,...record2.imageId?{agentbayImageId:record2.imageId}:{},...record2.contextId?{agentbayContextId:record2.contextId}:{},...record2.contextName?{agentbayContextName:record2.contextName}:{},createdAt:record2.createdAt,...record2.copiedCookies?{copiedCookies:record2.copiedCookies}:{},running}}function listRecords2(){let records=[];for(let file2 of listRecordFiles(keyedDir(AGENTBAY_BROWSERS_SUBDIR))){let stored=readRecord(file2);if(!stored){removeRecord(file2);continue}let{accessUrl:legacyAccessUrl,...record2}=stored;legacyAccessUrl!==void 0&&writeRecord(file2,record2);let running=isManagedProcess(record2.pid,`--browser-id ${record2.browserId}`);running||removeRecord(keyedConfigFile("browsers",record2.browserId)),records.push({record:record2,running})}return records}function findRecordWithStatus(selector){let normalized=selector.trim().toLowerCase();return listRecords2().find(({record:record2})=>record2.browserId.toLowerCase()===normalized||record2.name.toLowerCase()===normalized)??null}function findRecord(selector){return findRecordWithStatus(selector)?.record??null}function hasAgentBayBrowser(selector){return findRecord(selector)!==null}function listAgentBayBrowsers(){return listRecords2().map(({record:record2,running})=>browserSummary2(record2,running))}async function requireSession(sessionId,apiKey){let agentBay=await createClient(apiKey);return requireSessionFromClient(agentBay,sessionId)}async function requireSessionFromClient(agentBay,sessionId){let result=await agentBay.get(sessionId);if(!result.success||!result.session)throw new Error(result.errorMessage||`AgentBay session not found: ${sessionId}`);return result.session}async function getAgentBaySession(sessionId,dependencies={}){let apiKey=(dependencies.resolveApiKey??resolveAgentBayApiKey)(),agentBay=dependencies.createAgentBayClient?await dependencies.createAgentBayClient(apiKey):await createClient(apiKey);return requireSessionFromClient(agentBay,sessionId)}async function getAgentBayAccessUrl(sessionId,dependencies={}){let apiKey=(dependencies.resolveApiKey??resolveAgentBayApiKey)(),agentBay=dependencies.createAgentBayClient?await dependencies.createAgentBayClient(apiKey):await createClient(apiKey),session=await requireSessionFromClient(agentBay,sessionId);if(!session.info)throw new Error("The installed AgentBay SDK does not support live session information");let result=await session.info();if(result.success===!1)throw new Error(result.errorMessage||`AgentBay session info failed: ${sessionId}`);let data=result.data&&typeof result.data=="object"?result.data:null,accessUrl=normalizeAgentBayAccessUrl(data&&"resourceUrl"in data?data.resourceUrl:void 0);if(!accessUrl)throw new Error(`AgentBay session did not return a browser access URL: ${sessionId}`);return accessUrl}async function resolvePersistentContext(agentBay,browserId){if(!agentBay.context)throw new Error("The installed AgentBay SDK does not support persistent browser contexts");let name=agentBayContextName(browserId),result=await agentBay.context.get(name,!0);if(!result.success||!result.context?.id)throw new Error(result.errorMessage||`Failed to create AgentBay browser context: ${name}`);return{id:result.context.id,name:result.context.name||name}}async function resolveAgentBayEndpoint(sessionId){let apiKey=resolveAgentBayApiKey(),{AgentBay:AgentBay2,GetCdpLinkRequest:GetCdpLinkRequest2}=await loadSdk(),response=await new AgentBay2({apiKey}).client.getCdpLink(new GetCdpLinkRequest2({authorization:`Bearer ${apiKey}`,sessionId})),endpoint=response.body?.success?response.body.data?.url:void 0;if(!endpoint)throw new Error(response.body?.message||`Failed to get AgentBay CDP link: ${sessionId}`);let url2=new URL(endpoint);if(url2.protocol!=="ws:"&&url2.protocol!=="wss:")throw new Error(`AgentBay returned an unsupported CDP endpoint: ${url2.protocol}`);return url2.toString()}async function keepAgentBaySessionAlive(sessionId){let result=await(await requireSession(sessionId,resolveAgentBayApiKey())).keepAlive();if(result.success===!1)throw new Error(result.errorMessage||"AgentBay keepalive failed")}async function configureAgentBayBrowserSession(session,input,cookies,connectCdp=url2=>CdpClient.connect(url2)){let endpoint=await session.browser.getEndpointUrl(),cdp=await connectCdp(endpoint);try{await cdp.sendCommand("Browser.getVersion",{},1e4);let copiedCookieCount=await cdpImportCookiesWithClient(cdp,cookies);return input.url&&await cdp.sendCommand("Target.createTarget",{url:input.url,background:!1}),copiedCookieCount}finally{cdp.close()}}async function initializeAgentBayBrowserSession(session,input,cookies,options={}){if(!await session.browser.initializeAsync(options.userAgent?{userAgent:options.userAgent}:{}))throw new Error("AgentBay browser initialization failed");return configureAgentBayBrowserSession(session,input,cookies,options.connectCdp)}async function reuseAgentBayBrowserSession(session,input,cookies,options={}){return configureAgentBayBrowserSession(session,input,cookies,options.connectCdp)}async function launchAgentBayBrowser(input,deps){let name=validateName(input.name),browserId=agentBayBrowserId(name);validateAgentBayInput(input);let reuseMode=resolveReuseMode(input.reuse),imageId=resolveAgentBayImageId(input.imageId),persistent=input.persistent===!0,userAgentMode=resolveUserAgentMode(input.userAgentMode),cookieCopy=resolveCookieCopyPlan(input.copyCookieDomains),copyCookieDomains=cookieCopy.domains,apiKey=(deps.resolveApiKey??resolveAgentBayApiKey)(),lifecycle=resolveAgentBayLifecycleConfig(),releaseLock=acquireLaunchLock(browserId),persistBrowserRecord=deps.persistBrowserRecord??(record2=>writeRecord(keyedConfigFile(AGENTBAY_BROWSERS_SUBDIR,record2.browserId),record2)),findBrowserRecord=deps.findBrowserRecord??findRecordWithStatus,session=null,context,hostPid=0,recordWritten=!1;try{let existing=findBrowserRecord(browserId);if(existing){if(reuseMode==="never")throw new Error(`AgentBay browser already exists: ${browserId}`);if(!existing.running)throw new Error(`AgentBay browser is not running and cannot be reused: ${browserId}`);validateReusableAgentBayConfiguration(input,existing.record);let exportedCookies2=copyCookieDomains.length>0?await deps.exportCookies(copyCookieDomains):[],cookies2=cookieCopy.select(exportedCookies2),agentBay2=await(deps.createAgentBayClient??createClient)(apiKey),existingSession=await requireSessionFromClient(agentBay2,existing.record.sessionId),copiedCookieCount2=await reuseAgentBayBrowserSession(existingSession,input,cookies2,{connectCdp:deps.connectCdp}),record3={...existing.record,...copyCookieDomains.length>0?{copiedCookies:{domains:copyCookieDomains,count:copiedCookieCount2}}:{}};return copyCookieDomains.length>0&&persistBrowserRecord(record3),deps.log(`AgentBay browser reused: ${browserId}, host=${record3.pid}`),{...browserSummary2(record3,!0),created:!1,reused:!0}}if(reuseMode==="require")throw new Error(`AgentBay browser is not running and reuse=require: ${browserId}`);let[exportedCookies,userAgent]=await Promise.all([copyCookieDomains.length>0?deps.exportCookies(copyCookieDomains):Promise.resolve([]),userAgentMode==="desktop"?deps.getBrowserUserAgent().then(normalizeDesktopUserAgent):Promise.resolve(void 0)]),cookies=cookieCopy.select(exportedCookies),agentBay=await(deps.createAgentBayClient??createClient)(apiKey);context=persistent?await resolvePersistentContext(agentBay,browserId):void 0;let{LifecyclePolicy:LifecyclePolicy2}=await loadSdk(),created=await agentBay.create({imageId,framework:"mearl",lifecyclePolicy:new LifecyclePolicy2(lifecycle),...context?{browserContext:{contextId:context.id,autoUpload:!0,syncMode:"standard"}}:{}});if(!created.success||!created.session)throw new Error(created.errorMessage||"AgentBay session creation failed");session=created.session;let copiedCookieCount=await initializeAgentBayBrowserSession(session,input,cookies,{userAgent,connectCdp:deps.connectCdp}),host=spawn5(process.execPath,[deps.nativeHostScript,"--daemon","--agentbay-session-id",session.sessionId,"--browser-id",browserId,"--browser-name",name,"--agentbay-idle-release-minutes",String(lifecycle.idleReleaseTimeout)],{detached:!0,stdio:"ignore",windowsHide:!0});if(await new Promise((resolveSpawn,rejectSpawn)=>{host.once("error",rejectSpawn),host.once("spawn",resolveSpawn)}),hostPid=host.pid??0,!hostPid)throw new Error("AgentBay native host launched without a process id");host.unref();let record2={pid:hostPid,browserId,name,sessionId:session.sessionId,imageId,userAgentMode,persistent,...context?{contextId:context.id,contextName:context.name}:{},createdAt:new Date().toISOString(),...copyCookieDomains.length>0?{copiedCookies:{domains:copyCookieDomains,count:copiedCookieCount}}:{}};return persistBrowserRecord(record2),recordWritten=!0,await waitForBrowserRegistration(browserId,hostPid),deps.log(`AgentBay browser launched: ${browserId}, host=${hostPid}`),{...browserSummary2(record2,!0),created:!0,reused:!1}}catch(error48){if(hostPid&&await stopProcess(hostPid,`--browser-id ${browserId}`),recordWritten&&(removeRecord(keyedConfigFile(AGENTBAY_BROWSERS_SUBDIR,browserId)),removeRecord(keyedConfigFile("browsers",browserId))),session){let cleanupError;try{let deleted=await session.delete(!1);deleted.success||(cleanupError=new Error(deleted.errorMessage||"AgentBay session deletion failed"))}catch(deleteError){cleanupError=deleteError}if(cleanupError){let recoveryRecord={pid:hostPid,browserId,name,sessionId:session.sessionId,imageId,userAgentMode,persistent,...context?{contextId:context.id,contextName:context.name}:{},createdAt:new Date().toISOString()},recoverySaved=!1,recoveryError;try{persistBrowserRecord(recoveryRecord),recoverySaved=!0}catch(writeError){recoveryError=writeError}throw deps.log(`AgentBay launch cleanup failed for ${session.sessionId}:`,cleanupError instanceof Error?cleanupError.message:String(cleanupError)),recoveryError&&deps.log(`AgentBay recovery metadata could not be saved for ${session.sessionId}:`,recoveryError instanceof Error?recoveryError.message:String(recoveryError)),new AggregateError(recoveryError?[error48,cleanupError,recoveryError]:[error48,cleanupError],`${error48 instanceof Error?error48.message:String(error48)}; `+(recoverySaved?"AgentBay session cleanup failed and recovery metadata was retained for browser_close":`AgentBay session cleanup failed; session ${session.sessionId} may require manual deletion`),{cause:error48})}}throw error48}finally{releaseLock()}}function isMissingSessionError(error48){let message=error48 instanceof Error?error48.message:String(error48);return/not[ -]?found|does not exist|already deleted|invalid session/i.test(message)}async function releaseAgentBayBrowserResources(record2,agentBay,options={}){let deleteContext=record2.persistent===!0&&options.deleteProfile===!0,syncContext=record2.persistent===!0&&!deleteContext,contextSynced=!!record2.contextSyncedAt,session;try{session=await requireSessionFromClient(agentBay,record2.sessionId)}catch(error48){if(!isMissingSessionError(error48))throw error48}if(session){if(syncContext&&!contextSynced){if(!session.callMcpTool)throw new Error("The installed AgentBay SDK cannot stop the browser before context sync");let stopped=await session.callMcpTool("stopChrome",{},!1);if(stopped.success===!1)throw new Error(stopped.errorMessage||"AgentBay browser shutdown failed");if(!session.context)throw new Error("The installed AgentBay SDK cannot synchronize browser context state");let synced=await session.context.sync();if(!synced.success)throw new Error(synced.errorMessage||"AgentBay browser context sync failed");contextSynced=!0,record2.contextSyncedAt=new Date().toISOString(),options.persistRecord?.(record2)}try{let result=await session.delete(!1);if(!result.success)throw new Error(result.errorMessage||"AgentBay session deletion failed")}catch(error48){if(!isMissingSessionError(error48))throw error48}}if(deleteContext){if(!record2.contextId||!record2.contextName||!agentBay.context)throw new Error("AgentBay browser context metadata is unavailable for profile deletion");let result=await agentBay.context.delete({id:record2.contextId,name:record2.contextName});if(!result.success)throw new Error(result.errorMessage||"AgentBay context deletion failed")}return{sessionDeleted:!0,...syncContext?{contextSynced}:{},...deleteContext?{contextDeleted:!0}:{}}}async function closeAgentBayBrowser(selector,options={}){let record2=findRecord(selector);if(!record2)throw new Error(`AgentBay browser not found: ${selector}`);let agentBay=await createClient(resolveAgentBayApiKey()),releaseLock=acquireLaunchLock(record2.browserId);try{if(record2=findRecord(record2.browserId),!record2)throw new Error(`AgentBay browser not found: ${selector}`);let released=await releaseAgentBayBrowserResources(record2,agentBay,{...options,persistRecord:updatedRecord=>writeRecord(keyedConfigFile(AGENTBAY_BROWSERS_SUBDIR,updatedRecord.browserId),updatedRecord)}),closingOwnHost=record2.pid===process.pid;return closingOwnHost||await stopProcess(record2.pid,`--browser-id ${record2.browserId}`),removeRecord(keyedConfigFile(AGENTBAY_BROWSERS_SUBDIR,record2.browserId)),removeRecord(keyedConfigFile("browsers",record2.browserId)),closingOwnHost&&setTimeout(()=>process.kill(process.pid,"SIGTERM"),250).unref(),{browserId:record2.browserId,provider:"agentbay",closed:!0,...released,...record2.persistent===!0?{profileDeleted:options.deleteProfile===!0}:{profileDeleted:!0}}}finally{releaseLock()}}import{randomUUID as randomUUID6}from"node:crypto";import{basename as basename3,posix}from"node:path";var AGENTBAY_FILE_UPLOAD_WAIT_SECONDS=120;function pageUploadTargets(action,data){return action==="page_upload"?[{data}]:action!=="run_actions"||!Array.isArray(data?.actions)?[]:data.actions.flatMap((step,index)=>step?.action==="page_upload"?[{data:step.data,step:index}]:[])}function validateFilePaths(target){let filePaths=target.data?.filePaths;if(!Array.isArray(filePaths)||filePaths.length===0||filePaths.some(filePath=>typeof filePath!="string"||filePath.length===0)){let prefix=target.step===void 0?"":`Step ${target.step}: `;throw new Error(`${prefix}Invalid filePaths: must be a non-empty array of file path strings`)}return filePaths}function uploadError(result){return result.errorMessage??result.error_message??result.error??"unknown error"}async function stageAgentBayPageUploads(sessionId,action,data,dependencies={}){let targets=pageUploadTargets(action,data);if(targets.length===0)return data;let targetFilePaths=targets.map(target=>validateFilePaths(target)),fileSystem=(await(dependencies.getSession??getAgentBaySession)(sessionId)).fileSystem;if(!fileSystem)throw new Error("The installed AgentBay SDK does not support session file transfer");let contextPath=await fileSystem.getFileTransferContextPath();if(!contextPath)throw new Error(`AgentBay file transfer context is unavailable for session ${sessionId}`);let createTransferId=dependencies.createTransferId??randomUUID6,stagedPaths=await Promise.all(targetFilePaths.map(filePaths=>Promise.all(filePaths.map(async localPath=>{let remoteDirectory=posix.join(contextPath,createTransferId()),directoryResult=await fileSystem.createDirectory(remoteDirectory);if(directoryResult?.success===!1)throw new Error(`Failed to prepare AgentBay upload for ${basename3(localPath)}: ${uploadError(directoryResult)}`);let remotePath=posix.join(remoteDirectory,basename3(localPath)),result=await fileSystem.uploadFile(localPath,remotePath,{wait:!0,waitTimeout:AGENTBAY_FILE_UPLOAD_WAIT_SECONDS});if(result?.success!==!0)throw new Error(`Failed to upload ${basename3(localPath)} to AgentBay: ${uploadError(result)}`);return remotePath}))));if(action==="page_upload")return{...data,filePaths:stagedPaths[0]};let runActions=data,targetIndex=0;return{...runActions,actions:runActions.actions.map(step=>{if(step.action!=="page_upload")return step;let filePaths=stagedPaths[targetIndex++];return{...step,data:{...step.data,filePaths}}})}}var BROWSERS_SUBDIR="browsers",STALE_RECORD_TTL_MS=5*6e4,FOCUS_WRITE_THROTTLE_MS=1e3,identity=null,logFn2=()=>{};function initBrowserRegistry(deps){logFn2=deps.log}function recordFileFor2(browserId){return keyedConfigFile(BROWSERS_SUBDIR,browserId)}function ownsRecord(browserId){let existing=readRecord(recordFileFor2(browserId));return!existing||existing.pid===process.pid||!isAlive(existing.pid)}function persist(patch){if(!identity)return;let file2=recordFileFor2(identity.browserId);if(!ownsRecord(identity.browserId))return;let previous=readRecord(file2),record2={pid:process.pid,browserId:identity.browserId,socketPath:identity.socketPath,browserName:identity.browserName,nativeHostVersion:identity.nativeHostVersion,transport:identity.transport,startedAt:identity.startedAt,lastFocusedAt:previous?.lastFocusedAt,extensionVersion:previous?.extensionVersion,...patch,updatedAt:Date.now()};try{writeRecord(file2,record2)}catch(error48){logFn2("browser-registry: failed to write record:",String(error48))}}function registerBrowser(info){let startedAt=identity?.startedAt??new Date().toISOString();identity={browserId:info.browserId,socketPath:info.socketPath,browserName:info.browserName,nativeHostVersion:info.nativeHostVersion,transport:info.transport,startedAt};let previous=readRecord(recordFileFor2(info.browserId));persist({lastFocusedAt:previous?.lastFocusedAt??info.lastFocusedAt??Date.now(),extensionVersion:info.extensionVersion}),logFn2(`browser-registry: registered ${info.browserName} (${info.browserId})`)}var lastFocusWriteAt=0,focusFlushTimer=null;function writeFocusNow(){lastFocusWriteAt=Date.now(),persist({lastFocusedAt:lastFocusWriteAt})}function touchFocus(){if(!identity)return;let elapsed=Date.now()-lastFocusWriteAt;if(elapsed>=FOCUS_WRITE_THROTTLE_MS){writeFocusNow();return}focusFlushTimer||(focusFlushTimer=setTimeout(()=>{focusFlushTimer=null,writeFocusNow()},FOCUS_WRITE_THROTTLE_MS-elapsed),focusFlushTimer.unref())}function unregisterBrowser(){if(focusFlushTimer&&(clearTimeout(focusFlushTimer),focusFlushTimer=null),!identity)return;let file2=recordFileFor2(identity.browserId),existing=readRecord(file2);existing&&existing.pid!==process.pid||removeRecord(file2)}function pruneDeadBrowsers(){let now=Date.now();for(let file2 of listRecordFiles(keyedDir(BROWSERS_SUBDIR))){let rec=readRecord(file2);if(!rec){removeRecord(file2);continue}isAlive(rec.pid)||now-(rec.updatedAt??0)>STALE_RECORD_TTL_MS&&removeRecord(file2)}}function listRegisteredBrowsers(){let records=[];for(let file2 of listRecordFiles(keyedDir(BROWSERS_SUBDIR))){let record2=readRecord(file2);record2&&isAlive(record2.pid)&&records.push(record2)}return records.sort((a,b)=>(b.lastFocusedAt??0)-(a.lastFocusedAt??0)||(b.updatedAt??0)-(a.updatedAt??0))}async function ensureDiscoverableCdpBrowser(discovery){return discovery.isPublished()?!0:await discovery.isAvailable()?(discovery.publish(),discovery.monitor(),!0):!1}function connectionFields(record2){return{extensionVersion:record2.extensionVersion,nativeHostVersion:record2.nativeHostVersion,transport:record2.transport}}function mergeBrowserInventory(connected,managed){let managedById=new Map(managed.map(browser=>[browser.browserId,browser])),browsers=connected.map(record2=>{let managedBrowser=managedById.get(record2.browserId);return managedBrowser?(managedById.delete(record2.browserId),{browserId:record2.browserId,name:managedBrowser.name,type:"managed",status:"connected",...connectionFields(record2),headless:managedBrowser.headless,persistent:managedBrowser.persistent,provider:managedBrowser.provider,..."cdpPort"in managedBrowser?{cdpPort:managedBrowser.cdpPort}:{},..."agentbaySessionId"in managedBrowser?{agentbaySessionId:managedBrowser.agentbaySessionId}:{},..."agentbayImageId"in managedBrowser&&managedBrowser.agentbayImageId?{agentbayImageId:managedBrowser.agentbayImageId}:{},..."agentbayContextId"in managedBrowser&&managedBrowser.agentbayContextId?{agentbayContextId:managedBrowser.agentbayContextId}:{},..."agentbayContextName"in managedBrowser&&managedBrowser.agentbayContextName?{agentbayContextName:managedBrowser.agentbayContextName}:{},createdAt:managedBrowser.createdAt,..."account"in managedBrowser?{account:managedBrowser.account}:{},..."copiedCookies"in managedBrowser?{copiedCookies:managedBrowser.copiedCookies}:{}}):{browserId:record2.browserId,name:record2.browserName,type:"regular",status:"connected",...connectionFields(record2)}}),disconnected=[...managedById.values()].sort((a,b)=>b.createdAt.localeCompare(a.createdAt)).map(browser=>({browserId:browser.browserId,name:browser.name,type:"managed",status:browser.running?"running_disconnected":"stopped",headless:browser.headless,persistent:browser.persistent,provider:browser.provider,..."cdpPort"in browser?{cdpPort:browser.cdpPort}:{},..."agentbaySessionId"in browser?{agentbaySessionId:browser.agentbaySessionId}:{},..."agentbayImageId"in browser&&browser.agentbayImageId?{agentbayImageId:browser.agentbayImageId}:{},..."agentbayContextId"in browser&&browser.agentbayContextId?{agentbayContextId:browser.agentbayContextId}:{},..."agentbayContextName"in browser&&browser.agentbayContextName?{agentbayContextName:browser.agentbayContextName}:{},createdAt:browser.createdAt,..."account"in browser?{account:browser.account}:{},..."copiedCookies"in browser?{copiedCookies:browser.copiedCookies}:{}}));return browsers.push(...disconnected),{count:browsers.length,connectedCount:connected.length,browsers}}function listBrowserInventory(){let managed=[...listManagedBrowsers(),...listAgentBayBrowsers()];return mergeBrowserInventory(listRegisteredBrowsers(),managed)}import fs5 from"node:fs";import path6 from"node:path";import os2 from"node:os";import{randomUUID as randomUUID7}from"node:crypto";var NATIVE_HOST_VERSION="2.10.0";var MEASUREMENT_ID="G-W84LJDZ6PH",API_SECRET="X233siI5RrGYLhlD0kBKEQ",ENDPOINT=`https://www.google-analytics.com/mp/collect?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`,CLIENT_ID_PATTERN=/^\d+\.\d+$/,BUILD_CHANNEL=NATIVE_HOST_VERSION==="unknown"?"development":"production",CONFIG_DIR=path6.join(os2.homedir(),".mearl"),CONFIG_FILE=path6.join(CONFIG_DIR,"config.json");function readConfig(){try{return JSON.parse(fs5.readFileSync(CONFIG_FILE,"utf-8"))}catch{return{}}}function writeConfig(config2){try{fs5.mkdirSync(CONFIG_DIR,{recursive:!0}),fs5.writeFileSync(CONFIG_FILE,JSON.stringify(config2,null,2))}catch{}}var clientId=null;function createClientId(seed=randomUUID7()){let first=2166136261,second=2246822519;for(let index=0;index<seed.length;index++){let code=seed.charCodeAt(index);first=Math.imul(first^code,16777619)>>>0,second=Math.imul(second^code,3266489917)>>>0}return`${first||1}.${second||1}`}function getClientId(){if(clientId)return clientId;let config2=readConfig();return config2.clientId&&CLIENT_ID_PATTERN.test(config2.clientId)?(clientId=config2.clientId,clientId):(clientId=createClientId(config2.clientId),writeConfig({...config2,clientId}),clientId)}function setAnalyticsClientId(value){return typeof value!="string"||!CLIENT_ID_PATTERN.test(value)?!1:(clientId=value,!0)}function classifyAnalyticsError(error48){let message=error48 instanceof Error?error48.message:String(error48);return/timed?\s*out|timeout/i.test(message)?"timeout":/permission|not authorized|access denied|forbidden/i.test(message)?"permission_denied":/not found|no matching|does not exist/i.test(message)?"not_found":/not connected|disconnected|unavailable|connection (?:failed|closed)/i.test(message)?"unavailable":/invalid|required|must be|unsupported/i.test(message)?"invalid_request":"execution_error"}function trackAction(action,params){let payload={client_id:getClientId(),events:[{name:"agent_action",params:{action,...params,mearl_version:NATIVE_HOST_VERSION,runtime:"native_host",build_channel:BUILD_CHANNEL}}]};fetch(ENDPOINT,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(payload),keepalive:!0}).catch(()=>{})}import{open}from"node:fs/promises";import path8 from"node:path";var TRUNCATED_MARKER=`
|
|
959
1253
|
âĻ [middle truncated for Native Messaging] âĻ
|
|
960
1254
|
`;function truncateUtf82(value,maxBytes){if(Buffer.byteLength(value,"utf8")<=maxBytes)return value;let markerBytes=Buffer.byteLength(TRUNCATED_MARKER,"utf8");if(maxBytes<=markerBytes)return"";let source=Buffer.from(value,"utf8"),contentBytes=maxBytes-markerBytes,headBytes=Math.ceil(contentBytes/2),tailBytes=Math.floor(contentBytes/2);do{let truncated=`${source.subarray(0,headBytes).toString("utf8")}${TRUNCATED_MARKER}${source.subarray(source.length-tailBytes).toString("utf8")}`;if(Buffer.byteLength(truncated,"utf8")<=maxBytes)return truncated;headBytes>=tailBytes?headBytes-=1:tailBytes-=1}while(headBytes>0&&tailBytes>0);return""}function sanitizeValue(value,budget,depth){if(value===null||typeof value=="boolean"||typeof value=="number")return value;if(typeof value=="string"){let available=Math.max(0,budget.remaining),next2=truncateUtf82(value,available),bytes=Buffer.byteLength(next2,"utf8");return budget.remaining=Math.max(0,budget.remaining-bytes),next2!==value&&(budget.truncated=!0),next2}if(typeof value>"u")return null;if(typeof value!="object")return String(value);if(depth>=12||budget.remaining<=0)return budget.truncated=!0,{__transportTruncated:!0};if(budget.seen.has(value))return budget.truncated=!0,"[Circular]";if(budget.seen.add(value),Array.isArray(value)){let next2=value.slice(0,160).map(entry=>sanitizeValue(entry,budget,depth+1));return value.length>160&&(budget.truncated=!0,next2.push({__transportTruncated:!0,originalLength:value.length})),next2}let entries=Object.entries(value),next={};for(let[index,[key,entry]]of entries.entries()){if(index>=160||budget.remaining<=0){budget.truncated=!0;break}budget.remaining=Math.max(0,budget.remaining-Buffer.byteLength(key,"utf8")),next[key]=sanitizeValue(entry,budget,depth+1)}return budget.truncated&&(next.__transportTruncated=!0),next}function sanitizeAgentChatEvent(event){let budget={remaining:409600,truncated:!1,seen:new WeakSet},next={...event,params:sanitizeValue(event.params,budget,0)},bytes=Buffer.byteLength(JSON.stringify(next),"utf8");return bytes<=524288?next:{...event,params:{__transportTruncated:!0,originalBytes:bytes,message:"Agent event exceeded the Native Messaging transport limit."}}}import fs6 from"node:fs";import path7 from"node:path";import{execFile}from"node:child_process";function selectedPath(stdout){return stdout.replace(/[\r\n]+$/,"")||null}var runDirectoryPickerCommand=(command,args)=>new Promise((resolve3,reject)=>{execFile(command,args,{encoding:"utf8",windowsHide:!0},(error48,stdout)=>{if(!error48){resolve3(selectedPath(stdout));return}if(error48.code===1){resolve3(null);return}reject(error48)})});function isMissingCommand(error48){return error48 instanceof Error&&error48.code==="ENOENT"}async function pickWorkspaceDirectory(platform=process.platform,run=runDirectoryPickerCommand){let directory;if(platform==="darwin")directory=await run("osascript",["-e",'POSIX path of (choose folder with prompt "Select a workspace for Agent Chat")']);else if(platform==="win32"){let script=["Add-Type -AssemblyName System.Windows.Forms;","$dialog = New-Object System.Windows.Forms.FolderBrowserDialog;","$dialog.Description = 'Select a workspace for Agent Chat';","if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {","[Console]::OutputEncoding = [System.Text.Encoding]::UTF8;","Write-Output $dialog.SelectedPath;","}"].join(" ");directory=await run("powershell.exe",["-NoProfile","-STA","-Command",script])}else if(platform==="linux")try{directory=await run("zenity",["--file-selection","--directory","--title=Select a workspace for Agent Chat"])}catch(error48){if(!isMissingCommand(error48))throw error48;try{directory=await run("kdialog",["--getexistingdirectory",".","--title","Select a workspace for Agent Chat"])}catch(fallbackError){throw isMissingCommand(fallbackError)?new Error("Install zenity or kdialog to select an Agent Chat workspace",{cause:fallbackError}):fallbackError}}else throw new Error(`Directory selection is not supported on ${platform}`);return directory?resolveWorkspaceDirectory(directory):null}function resolveWorkspaceDirectory(directory){if(typeof directory!="string"||!directory)throw new Error("Workspace directory is required");if(!path7.isAbsolute(directory))throw new Error("Workspace directory must be an absolute path");let resolved;try{resolved=fs6.realpathSync.native(directory)}catch(error48){throw new Error(`Workspace directory does not exist: ${directory}`,{cause:error48})}if(!fs6.statSync(resolved).isDirectory())throw new Error(`Workspace path is not a directory: ${directory}`);return resolved}var MAX_REPLAY_EVENTS=1e3,MAX_REPLAY_BYTES=2048*1024,MAX_REPLAY_PAGE_BYTES=524288,MAX_SKILL_FILE_BYTES=1024*1024,SUPPORTED_IMAGE_MIME_TYPES=new Set(AGENT_CHAT_SUPPORTED_IMAGE_MIME_TYPES),REPLAY_SNAPSHOT_METHODS=new Set(["thread/settings/updated"]);function createAgentDeveloperInstructions({cwd,tabId,initialPageUrl,initialPageTitle}){return[...cwd?[createAgentDirectoryContextInstructions(cwd)]:[],...tabId!==void 0?[createBrowserAgentDeveloperInstructions(tabId,{...initialPageUrl?{url:initialPageUrl}:{},...initialPageTitle?{title:initialPageTitle}:{}})]:[]].join(`
|
|
961
1255
|
|
|
@@ -1011,7 +1305,7 @@ ${output.stderr}`,"project")))}return{cli,updates:(await Promise.all(commands)).
|
|
|
1011
1305
|
`;for(;;)try{let handle=fs12.openSync(lockPath,"wx",384);try{fs12.writeFileSync(handle,owner,"utf8")}finally{fs12.closeSync(handle)}break}catch(error48){if(!(error48 instanceof Error)||!("code"in error48)||error48.code!=="EEXIST")throw error48;let existing=readLockState(lockPath),staleAfter=existing?.owner?NATIVE_HOST_UPDATE_TIMEOUT_MS:INVALID_UPDATE_LOCK_GRACE_MS,referenceTime=existing?.owner?.startedAt??existing?.modifiedAt,expired=referenceTime!==void 0&&Date.now()-referenceTime>staleAfter,ownerAlive=existing?.owner?isAlive(existing.owner.pid):!1;if(expired&&!ownerAlive)try{fs12.unlinkSync(lockPath);continue}catch{}if(Date.now()-startedAt>NATIVE_HOST_UPDATE_TIMEOUT_MS+1e4)throw new NativeHostUpdateFailure("lock-timeout","Another Mearl Native Host update did not finish in time");await wait(UPDATE_LOCK_POLL_MS)}try{return await operation()}finally{try{fs12.readFileSync(lockPath,"utf8")===owner&&fs12.unlinkSync(lockPath)}catch{}}}function classifyUpdateFailure(output){return/\b(?:E404|ETARGET)\b|no matching version found|404\s+not found|package.+not found/i.test(output)?"package-unavailable":/\b(?:EAI_AGAIN|ECONNREFUSED|ECONNRESET|ENETUNREACH|ENOTFOUND|ERR_SOCKET_TIMEOUT)\b|fetch failed|network request/i.test(output)?"network":"setup-failed"}function nativeHostUpdateCommand(targetVersion){if(!isMearlReleaseVersion(targetVersion))throw new Error("The Native Host update target must be a valid Mearl release");let releaseLine=mearlReleaseLineForVersion(targetVersion);return{args:["--yes",`@mearl/setup@${releaseLine}`,"update","--local","--yes","--target-line",releaseLine,"--skip-skill"]}}function currentNativeHostPackageRoot(entryPath){let current=path14.dirname(entryPath);for(let depth=0;depth<12;depth+=1){try{if(JSON.parse(fs12.readFileSync(path14.join(current,"package.json"),"utf8")).name==="@mearl/native-host")return current}catch{}let parent=path14.dirname(current);if(parent===current)break;current=parent}return null}function currentPackageManagerInstallation(environment,nodePath,platform){let packageRoot=currentNativeHostPackageRoot(fileURLToPath3(import.meta.url));return packageRoot?resolvePackageManagerInstallation(packageRoot,"@mearl/native-host",{env:environment,platform,processExecPath:nodePath}):null}async function installedLocalPackagesMatch(targetReleaseLine,environment,runner){let installedVersions=[];for(let executableName of["mearl-native-host","mearl"]){let executable=findExecutable(executableName,{env:environment});if(!executable)return!1;try{let result=await runner(executable,["--version"],{capture:!0,env:environment,timeoutMs:5e3}),installedVersion=result.stdout.trim();if(result.code!==0||!isMearlReleaseVersionInLine(installedVersion,targetReleaseLine))return!1;installedVersions.push(installedVersion)}catch{return!1}}return new Set(installedVersions).size===1}async function runNativeHostUpdate(targetVersion,options={}){let command=nativeHostUpdateCommand(targetVersion),targetReleaseLine=mearlReleaseLineForVersion(targetVersion),environment=options.environment??process.env,platform=options.platform??process.platform,nodePath=options.nodePath??process.execPath,currentInstallation=currentPackageManagerInstallation(environment,nodePath,platform),managerCommand=options.packageManagerCommand===void 0?currentInstallation?.command??null:options.packageManagerCommand,packageBinDirectory=options.packageBinDirectory===void 0?currentInstallation?.binDirectory??null:options.packageBinDirectory,childEnvironment=prependNodePath(environment,nodePath);managerCommand&&(childEnvironment=prependCommandPath(managerCommand,childEnvironment)),packageBinDirectory&&(childEnvironment=prependPathDirectory(packageBinDirectory,childEnvironment));let packageRunner=options.packageRunner??findExecutable("npx",{env:childEnvironment,extraDirectories:[path14.dirname(nodePath)],platform});if(!packageRunner)throw new NativeHostUpdateFailure("package-unavailable","The package runner is unavailable");let runner=options.runner??runCommand,areTargetsInstalled=options.areTargetsInstalled??((version2,env)=>installedLocalPackagesMatch(version2,env,runner));await(options.withUpdateLock??((version2,operation)=>withNativeHostUpdateLock(options.updateLockPath??UPDATE_LOCK_PATH,version2,operation)))(targetVersion,async()=>{let result;try{result=await runner(packageRunner,command.args,{capture:!0,env:childEnvironment,timeoutMs:options.timeoutMs??NATIVE_HOST_UPDATE_TIMEOUT_MS})}catch(error48){let message=error48 instanceof Error?error48.message:String(error48),classified=classifyUpdateFailure(message);throw new NativeHostUpdateFailure(/timed out/i.test(message)?"timeout":classified==="setup-failed"?"unknown":classified,"The Native Host update process did not complete")}if(result.code!==0)throw new NativeHostUpdateFailure(classifyUpdateFailure(`${result.stderr.slice(0,8192)}
|
|
1012
1306
|
${result.stdout.slice(0,8192)}`),"The Mearl setup release line did not complete successfully");if(!await areTargetsInstalled(targetReleaseLine,childEnvironment))throw new NativeHostUpdateFailure("verification-failed","The installed Native Host and client do not match the Extension release line")})}var NativeHostUpdateCoordinator=class{constructor(options){this.options=options}#automaticAttempted=!1;#operation=null;evaluate(extensionVersion2,checkForUpdates){if(checkForUpdates!==!0||this.#automaticAttempted||this.#operation)return;if(!isMearlReleaseVersion(extensionVersion2)||!isMearlReleaseVersion(this.options.hostVersion)){this.options.log("Skipped Native Host update check because a release version was invalid");return}let targetVersion=extensionVersion2;if(compareMearlReleaseLines(this.options.hostVersion,targetVersion)>=0)return;this.#automaticAttempted=!0;let operation=this.options.runUpdate(targetVersion).then(()=>this.options.requestRestart()).catch(error48=>{let category=error48 instanceof NativeHostUpdateFailure?error48.updateError:"unknown";this.options.log(`Native Host automatic update failed (${category})`)}).finally(()=>{this.#operation===operation&&(this.#operation=null)});this.#operation=operation}};import fs17 from"node:fs";import path18 from"node:path";import{randomUUID as randomUUID9}from"node:crypto";import fs16 from"node:fs";import os8 from"node:os";import path17 from"node:path";import{createHash as createHash2,randomUUID as randomUUID8}from"node:crypto";import WebSocket2 from"ws";var PAGE_ACT_ACTIONS2=["page_click","page_drag","page_type","page_hover","page_scroll","page_press","page_upload","page_eval"];var OBSERVED_PAGE_ACTIONS=new Set(PAGE_ACT_ACTIONS2);import net from"node:net";import fs15 from"node:fs";import os7 from"node:os";import path16 from"node:path";import{createRequire as createRequire8}from"node:module";import fs13 from"node:fs";import fs14 from"node:fs";import os6 from"node:os";import path15 from"node:path";var BROWSERS_DIR=path15.join(os6.homedir(),".mearl","browsers");var require9=createRequire8(import.meta.url),CLIENT_VERSION=require9("../package.json").version,MAX_SOCKET_BUFFER_SIZE=64*1024*1024,SOCKET_PATH=process.platform==="win32"?"\\\\.\\pipe\\mearl-agent":path16.join(os7.tmpdir(),"mearl-agent.sock");import{existsSync as existsSync10,readFileSync as readFileSync8}from"node:fs";import{homedir as homedir3}from"node:os";import{join as join7}from"node:path";var MEARL_CONFIG_DIR=join7(homedir3(),".mearl");var import_extract_zip=__toESM(require_extract_zip(),1);import WebSocket3 from"ws";var MEARL_EXTENSION_DOWNLOAD_PAGE="https://mearl.alibaba-inc.com/",MEARL_EXTENSION_REMOTE_CONFIG_URL=`${MEARL_EXTENSION_DOWNLOAD_PAGE}config.json`;var MEARL_EXTENSION_ID="aoehhjnofngknnjefamjbplchbolghkm",MEARL_EXTENSION_SETUP_MARKER=".mearl-setup.json";var MAX_ARCHIVE_BYTES=64*1024*1024,SHA256_PATTERN=/^[a-f\d]{64}$/i;function extensionArchiveUrl(version2){if(!isMearlReleaseVersion(version2))throw new Error(`Invalid Mearl browser extension version: ${version2}`);return new URL(`mearl-chrome-v${version2}.zip`,MEARL_EXTENSION_DOWNLOAD_PAGE).toString()}function validateExtensionRelease(release){if(!isMearlReleaseVersion(release.version))throw new Error("Remote extension config has an invalid latestVersion");let expectedArchiveUrl=extensionArchiveUrl(release.version),archiveUrl;try{archiveUrl=new URL(release.archiveUrl).toString()}catch{throw new Error("Remote extension config has an invalid downloadUrl")}if(archiveUrl!==expectedArchiveUrl)throw new Error("Remote extension downloadUrl does not match latestVersion");if(release.sha256!==void 0&&!SHA256_PATTERN.test(release.sha256))throw new Error("Remote extension config has an invalid downloadSha256");return{archiveUrl,...release.sha256?{sha256:release.sha256.toLowerCase()}:{},version:release.version}}async function fetchBrowserExtensionRelease(fetchImpl=fetch){let response=await fetchImpl(MEARL_EXTENSION_REMOTE_CONFIG_URL,{cache:"no-store"});if(!response.ok)throw new Error(`Extension config returned HTTP ${response.status}`);let config2=await response.json();return validateExtensionRelease({archiveUrl:typeof config2.downloadUrl=="string"?config2.downloadUrl:"",...typeof config2.downloadSha256=="string"?{sha256:config2.downloadSha256}:{},version:typeof config2.latestVersion=="string"?config2.latestVersion:""})}function sameExtensionPath(left,right){let normalizedLeft=path17.normalize(path17.resolve(left)),normalizedRight=path17.normalize(path17.resolve(right));return process.platform==="win32"?normalizedLeft.toLowerCase()===normalizedRight.toLowerCase():normalizedLeft===normalizedRight}function setupMarkerPath(directory){return path17.join(directory,MEARL_EXTENSION_SETUP_MARKER)}function hasSetupMarker(targetDirectory){try{let marker=JSON.parse(fs16.readFileSync(setupMarkerPath(targetDirectory),"utf8"));return marker.schemaVersion===1&&marker.extensionId===MEARL_EXTENSION_ID&&typeof marker.path=="string"&&sameExtensionPath(marker.path,targetDirectory)}catch{return!1}}async function writeSetupMarker(directory,targetDirectory){let marker={extensionId:MEARL_EXTENSION_ID,path:path17.resolve(targetDirectory),schemaVersion:1};await fs16.promises.writeFile(setupMarkerPath(directory),`${JSON.stringify(marker,null,2)}
|
|
1013
1307
|
`,{mode:384})}async function replaceDirectory(stagingDirectory,targetDirectory){let backupDirectory=`${targetDirectory}.backup-${randomUUID8()}`,targetExists=fs16.existsSync(targetDirectory);try{targetExists&&await fs16.promises.rename(targetDirectory,backupDirectory),await fs16.promises.rename(stagingDirectory,targetDirectory)}catch(error48){throw!fs16.existsSync(targetDirectory)&&fs16.existsSync(backupDirectory)&&await fs16.promises.rename(backupDirectory,targetDirectory),error48}targetExists&&await fs16.promises.rm(backupDirectory,{force:!0,recursive:!0})}function readExtensionManifest(directory){let manifestPath=path17.join(directory,"manifest.json"),parsed;try{parsed=JSON.parse(fs16.readFileSync(manifestPath,"utf8"))}catch(error48){throw new Error(`Downloaded extension has no valid manifest.json: ${error48 instanceof Error?error48.message:error48}`,{cause:error48})}if(parsed.manifest_version!==3||typeof parsed.name!="string"||typeof parsed.key!="string"||parsed.key.length===0)throw new Error("Downloaded archive is not a valid Manifest V3 extension");if(!isMearlReleaseVersion(parsed.version))throw new Error("Downloaded extension manifest has an invalid version");return parsed}async function downloadAndReplaceExtension(releaseInput,targetDirectory,fetchImpl,extractArchive){let release=validateExtensionRelease(releaseInput),parentDirectory=path17.dirname(targetDirectory),stagingDirectory=`${targetDirectory}.staging-${randomUUID8()}`,archivePath=path17.join(parentDirectory,`.mearl-extension-${randomUUID8()}.zip`);await fs16.promises.mkdir(parentDirectory,{recursive:!0});try{let response=await fetchImpl(release.archiveUrl,{redirect:"follow"});if(!response.ok)throw new Error(`Extension archive returned HTTP ${response.status}: ${release.archiveUrl}`);if(Number(response.headers.get("content-length")??0)>MAX_ARCHIVE_BYTES)throw new Error(`Extension archive exceeds ${MAX_ARCHIVE_BYTES} bytes`);let archive=Buffer.from(await response.arrayBuffer());if(archive.length===0||archive.length>MAX_ARCHIVE_BYTES)throw new Error("Extension archive is empty or too large");if(release.sha256&&createHash2("sha256").update(archive).digest("hex")!==release.sha256)throw new Error("Extension archive SHA256 does not match remote config");await fs16.promises.writeFile(archivePath,archive,{mode:384}),await fs16.promises.mkdir(stagingDirectory,{recursive:!0}),await extractArchive(archivePath,stagingDirectory);let manifest=readExtensionManifest(stagingDirectory);if(manifest.version!==release.version)throw new Error(`Extension archive version ${String(manifest.version)} does not match ${release.version}`);return await writeSetupMarker(stagingDirectory,targetDirectory),await replaceDirectory(stagingDirectory,targetDirectory),release}finally{await fs16.promises.rm(archivePath,{force:!0}),await fs16.promises.rm(stagingDirectory,{force:!0,recursive:!0})}}async function updateSetupManagedBrowserExtensionFiles(options,dependencies={}){let targetDirectory=path17.resolve(options.targetDirectory);if(!hasSetupMarker(targetDirectory))throw new Error("The running extension is not managed by Mearl setup");let fetchImpl=dependencies.fetch??fetch,extractArchive=dependencies.extractArchive??((archivePath,destination)=>(0,import_extract_zip.default)(archivePath,{dir:destination}));return{...await downloadAndReplaceExtension(options.release,targetDirectory,fetchImpl,extractArchive),path:targetDirectory}}var EXTENSION_UPDATE_LOCK_PATH=path18.join(DAEMON_HOME,"extension-update.lock"),EXTENSION_UPDATE_LOCK_STALE_MS=10*6e4,INVALID_UPDATE_LOCK_GRACE_MS2=1e4;function readUpdateLock(lockPath){try{let stat2=fs17.lstatSync(lockPath);if(!stat2.isFile()||stat2.isSymbolicLink()||stat2.size>4096)return{modifiedAt:stat2.mtimeMs,owner:null};try{let value=JSON.parse(fs17.readFileSync(lockPath,"utf8")),owner=typeof value.id=="string"&&Number.isInteger(value.pid)&&(value.pid??0)>0&&typeof value.startedAt=="number"?value:null;return{modifiedAt:stat2.mtimeMs,owner}}catch{return{modifiedAt:stat2.mtimeMs,owner:null}}}catch{return null}}async function withExtensionUpdateLock(operation,dependencies){let lockPath=dependencies.lockPath??EXTENSION_UPDATE_LOCK_PATH,now=dependencies.now??Date.now,isProcessAlive=dependencies.isProcessAlive??isAlive;fs17.mkdirSync(path18.dirname(lockPath),{recursive:!0,mode:448});let owner={id:randomUUID9(),pid:process.pid,startedAt:now()},serializedOwner=`${JSON.stringify(owner)}
|
|
1014
|
-
`;for(let attempt=0;attempt<2;attempt+=1)try{fs17.writeFileSync(lockPath,serializedOwner,{encoding:"utf8",flag:"wx",mode:384});break}catch(error48){if(!(error48 instanceof Error)||!("code"in error48)||error48.code!=="EEXIST")throw error48;let state=readUpdateLock(lockPath);if(!(state===null||(state.owner?now()-state.owner.startedAt>EXTENSION_UPDATE_LOCK_STALE_MS&&!isProcessAlive(state.owner.pid):now()-state.modifiedAt>INVALID_UPDATE_LOCK_GRACE_MS2))||attempt>0)throw new Error("Another extension update is already running",{cause:error48});try{fs17.unlinkSync(lockPath)}catch(unlinkError){throw new Error("Another extension update is already running",{cause:unlinkError})}}try{return await operation()}finally{try{fs17.readFileSync(lockPath,"utf8")===serializedOwner&&fs17.unlinkSync(lockPath)}catch{}}}async function updateSetupManagedExtension(request,dependencies={}){if(!isMearlReleaseVersion(request.currentVersion))throw new Error("The running extension reported an invalid version");if(!request.setupManagedPath||!path18.isAbsolute(request.setupManagedPath))throw new Error("A setup-managed extension path is required");let release=await(dependencies.fetchRelease??fetchBrowserExtensionRelease)(),changelogUrl=`https://mearl.alibaba-inc.com/changelog.html#v${release.version}`;return compareMearlReleaseVersions(release.version,request.currentVersion)<=0?{changelogUrl,updated:!1,version:request.currentVersion}:withExtensionUpdateLock(async()=>(await(dependencies.updateFiles??updateSetupManagedBrowserExtensionFiles)({release,targetDirectory:request.setupManagedPath}),{changelogUrl,updated:!0,version:release.version}),dependencies)}init_runtimeArgs();var cliArgs=process.argv.slice(2),cliArg=cliArgs[0];if(cliArg==="--init"||cliArg==="--uninstall"||cliArg==="init"||cliArg==="uninstall"){let{runCli:runCli2}=await Promise.resolve().then(()=>(init_install(),install_exports));process.exit(await runCli2(cliArgs))}function printCliHelp(){console.error(`mearl-native-host v${NATIVE_HOST_VERSION}
|
|
1308
|
+
`;for(let attempt=0;attempt<2;attempt+=1)try{fs17.writeFileSync(lockPath,serializedOwner,{encoding:"utf8",flag:"wx",mode:384});break}catch(error48){if(!(error48 instanceof Error)||!("code"in error48)||error48.code!=="EEXIST")throw error48;let state=readUpdateLock(lockPath);if(!(state===null||(state.owner?now()-state.owner.startedAt>EXTENSION_UPDATE_LOCK_STALE_MS&&!isProcessAlive(state.owner.pid):now()-state.modifiedAt>INVALID_UPDATE_LOCK_GRACE_MS2))||attempt>0)throw new Error("Another extension update is already running",{cause:error48});try{fs17.unlinkSync(lockPath)}catch(unlinkError){throw new Error("Another extension update is already running",{cause:unlinkError})}}try{return await operation()}finally{try{fs17.readFileSync(lockPath,"utf8")===serializedOwner&&fs17.unlinkSync(lockPath)}catch{}}}async function updateSetupManagedExtension(request,dependencies={}){if(!isMearlReleaseVersion(request.currentVersion))throw new Error("The running extension reported an invalid version");if(!request.setupManagedPath||!path18.isAbsolute(request.setupManagedPath))throw new Error("A setup-managed extension path is required");let release=await(dependencies.fetchRelease??fetchBrowserExtensionRelease)(),changelogUrl=`https://mearl.alibaba-inc.com/changelog.html#v${release.version}`;return compareMearlReleaseVersions(release.version,request.currentVersion)<=0?{changelogUrl,updated:!1,version:request.currentVersion}:withExtensionUpdateLock(async()=>(await(dependencies.updateFiles??updateSetupManagedBrowserExtensionFiles)({release,targetDirectory:request.setupManagedPath}),{changelogUrl,updated:!0,version:release.version}),dependencies)}init_runtimeArgs();var OPEN_SANDBOX_PORT_PLACEHOLDER="{port}",AONE_PORT_MAPPING_URL="http://127.0.0.1:58596/api/port-mapping";function normalizeBrowserAccessUrl(value){if(typeof value!="string"||!value.trim())return null;let input=/^[a-z][a-z\d+.-]*:\/\//i.test(value.trim())?value.trim():`https://${value.trim()}`;try{let parsed=new URL(input);return parsed.protocol==="ws:"&&(parsed.protocol="http:"),parsed.protocol==="wss:"&&(parsed.protocol="https:"),!["http:","https:"].includes(parsed.protocol)||!parsed.hostname?null:parsed.toString()}catch{return null}}function resolveSandboxBrowserAccessCapability(env=process.env){return env.OPENSANDBOX_ID?.trim()?{kind:"sandbox-novnc",environment:"opensandbox",port:6080}:env.AONE_SANDBOX_ID?.trim()?{kind:"sandbox-novnc",environment:"aone",port:6080}:null}function resolveOpenSandboxBrowserAccessUrl(port,env=process.env){if(!env.OPENSANDBOX_ID?.trim())return null;let template=env.AONE_SANDBOX_ENDPOINT_TEMPLATE?.trim();return template?.includes(OPEN_SANDBOX_PORT_PLACEHOLDER)?normalizeBrowserAccessUrl(template.replaceAll(OPEN_SANDBOX_PORT_PLACEHOLDER,String(port))):null}async function resolveAoneBrowserAccessUrl(port,dependencies){let response=await(dependencies.fetch??globalThis.fetch)(`${AONE_PORT_MAPPING_URL}?port=${port}`,{signal:AbortSignal.timeout(5e3)});if(!response.ok)throw new Error(`AONE Sandbox port mapping failed with HTTP ${response.status}`);let payload=await response.json(),url2=payload.success?normalizeBrowserAccessUrl(payload.url):null;if(!url2)throw new Error(`AONE Sandbox did not return a browser access URL for port ${port}`);return url2}async function resolveSandboxBrowserAccess(dependencies={}){let env=dependencies.env??process.env,capability=resolveSandboxBrowserAccessCapability(env);if(!capability)throw new Error("The selected browser is not running in a supported sandbox");if(capability.environment==="opensandbox"){let url3=resolveOpenSandboxBrowserAccessUrl(capability.port,env);if(url3)return{...capability,url:url3};if(!env.AONE_SANDBOX_ID?.trim())throw new Error("OpenSandbox browser access is unavailable because AONE_SANDBOX_ENDPOINT_TEMPLATE is missing or invalid")}let url2=await resolveAoneBrowserAccessUrl(capability.port,dependencies);return{...capability,environment:"aone",url:url2}}var cliArgs=process.argv.slice(2),cliArg=cliArgs[0];if(cliArg==="--init"||cliArg==="--uninstall"||cliArg==="init"||cliArg==="uninstall"){let{runCli:runCli2}=await Promise.resolve().then(()=>(init_install(),install_exports));process.exit(await runCli2(cliArgs))}function printCliHelp(){console.error(`mearl-native-host v${NATIVE_HOST_VERSION}
|
|
1015
1309
|
|
|
1016
1310
|
Usage:
|
|
1017
1311
|
mearl-native-host [runtime-options]
|
|
@@ -1034,6 +1328,7 @@ Runtime options:
|
|
|
1034
1328
|
Close an idle AgentBay browser (minimum 3 minutes)
|
|
1035
1329
|
--browser-id <id> Registry id for this CDP browser
|
|
1036
1330
|
--browser-name <name> Human-readable registry name
|
|
1331
|
+
--browser-headless Mark this CDP browser as having no graphical display
|
|
1037
1332
|
--version, -v Show version
|
|
1038
1333
|
--help, -h Show this help message
|
|
1039
1334
|
|
|
@@ -1052,7 +1347,7 @@ Examples:
|
|
|
1052
1347
|
mearl-native-host uninstall --mode skills
|
|
1053
1348
|
mearl-native-host init --extension-id abcdefghijklmnopqrstuvwxyzabcdef
|
|
1054
1349
|
mearl-native-host --daemon
|
|
1055
|
-
mearl-native-host --version`)}!cliArg&&process.stdin.isTTY&&(printCliHelp(),process.exit(0));var runtimeArgs={browserId:"cdp",browserName:"CDP",cdpPort:9222,daemon:!1,discoverCdp:!1,help:!1,skipBrowserRegistration:!1,version:!1};if(cliArgs.length>0)try{let{parseNativeHostRuntimeArgs:parseNativeHostRuntimeArgs2}=await Promise.resolve().then(()=>(init_runtimeArgs(),runtimeArgs_exports));runtimeArgs=await parseNativeHostRuntimeArgs2(cliArgs,3)}catch(error48){console.error(`Error: ${error48 instanceof Error?error48.message:String(error48)}`),printCliHelp(),process.exit(2)}runtimeArgs.version&&(console.log(NATIVE_HOST_VERSION),process.exit(0));runtimeArgs.help&&(printCliHelp(),process.exit(0));var isDaemonMode=runtimeArgs.daemon,discoverCdp=runtimeArgs.discoverCdp,skipBrowserRegistration=runtimeArgs.skipBrowserRegistration,CDP_PORT=runtimeArgs.cdpPort,CDP_USER_DATA_DIR=runtimeArgs.cdpUserDataDir,AGENTBAY_SESSION_ID=runtimeArgs.agentBaySessionId,AGENTBAY_IDLE_RELEASE_MINUTES=runtimeArgs.agentBayIdleReleaseMinutes,CDP_BROWSER_ID=runtimeArgs.browserId,CDP_BROWSER_NAME=runtimeArgs.browserName;function socketPathFor(suffix){return process.platform==="win32"?`\\\\.\\pipe\\mearl-agent${suffix}`:path21.join(os10.tmpdir(),`mearl-agent${suffix}.sock`)}var LEGACY_SOCKET_PATH=socketPathFor(""),INSTANCE_SOCKET_PATH=socketPathFor(`-${process.pid}`),LOG_FILE=path21.join(os10.tmpdir(),"mearl-native-host.log"),DEFAULT_TIMEOUT_MS=15e3,INVENTORY_IDLE_EXIT_MS=1e3,DISCOVERY_REQUEST_IDLE_EXIT_MS=5e3,MAX_SOCKET_BUFFER_SIZE2=64*1024*1024,extensionVersion=null,versionWarningEmitted=!1,cdpPermissionNoticeLogged=!1,EXTENSION_INSTALL_URL="https://chromewebstore.google.com/detail/mearl/aoehhjnofngknnjefamjbplchbolghkm";function majorMinor(version2){let parts=version2.split(".");return parts.length>=2?`${parts[0]}.${parts[1]}`:version2}function extractChromeVersion(input){let match=/Chrome\/([\d.]+)/.exec(input);return match?match[1].split(".").slice(0,3).join("."):null}async function fetchCdpBrowserVersion(){if(AGENTBAY_SESSION_ID)try{return(await(await getCdpSession().getBrowserClient()).sendCommand("Browser.getVersion",{},5e3)).product??null}catch{return null}let port=readDevToolsActivePort(CDP_USER_DATA_DIR)?.port??CDP_PORT;return new Promise(resolve3=>{let req=http4.get(`http://localhost:${port}/json/version`,res=>{let data="";res.on("data",chunk=>data+=chunk),res.on("end",()=>{try{let info=JSON.parse(data);resolve3(info.Browser??null)}catch{resolve3(null)}})});req.on("error",()=>resolve3(null)),req.setTimeout(2e3,()=>{req.destroy(),resolve3(null)})})}async function getCurrentBrowserUserAgent(){if(extensionVersion!==null)try{let result=await sendRequestToExtension("get_browser_info",{},3e3);if(result.userAgent?.trim())return result.userAgent}catch{}try{let result=await(await getCdpSession().getBrowserClient()).sendCommand("Browser.getVersion",{},5e3);if(result.userAgent?.trim())return result.userAgent}catch{}throw new Error("Could not determine the control browser user agent for userAgentMode=desktop")}async function collectVersions(includeInstallationInfo=!1){let info={nativeHost:NATIVE_HOST_VERSION,extension:extensionVersion,browser:null};if(extensionVersion!==null)try{let browserInfo=await sendRequestToExtension("get_browser_info",{},3e3);browserInfo?.userAgent&&(info.browser=extractChromeVersion(browserInfo.userAgent)),browserInfo?.extensionVersion&&(info.extension=browserInfo.extensionVersion),includeInstallationInfo&&(browserInfo?.extensionId&&(info.extensionId=browserInfo.extensionId),(typeof browserInfo?.setupManagedPath=="string"||browserInfo?.setupManagedPath===null)&&(info.setupManagedPath=browserInfo.setupManagedPath))}catch{}if(!info.browser){let cdpBrowser=await fetchCdpBrowserVersion();cdpBrowser&&(info.browser=extractChromeVersion(cdpBrowser))}return info}function buildVersionWarning(clientVersion){let versions=[clientVersion?{name:"client",version:clientVersion}:null,{name:"native-host",version:NATIVE_HOST_VERSION},extensionVersion?{name:"extension",version:extensionVersion}:null].filter(Boolean);return new Set(versions.map(v=>majorMinor(v.version))).size<=1?null:["â ī¸ Mearl version mismatch detected:",versions.map(v=>` - ${v.name}: ${v.version}`).join(`
|
|
1350
|
+
mearl-native-host --version`)}!cliArg&&process.stdin.isTTY&&(printCliHelp(),process.exit(0));var runtimeArgs={browserId:"cdp",browserHeadless:!1,browserName:"CDP",cdpPort:9222,daemon:!1,discoverCdp:!1,help:!1,skipBrowserRegistration:!1,version:!1};if(cliArgs.length>0)try{let{parseNativeHostRuntimeArgs:parseNativeHostRuntimeArgs2}=await Promise.resolve().then(()=>(init_runtimeArgs(),runtimeArgs_exports));runtimeArgs=await parseNativeHostRuntimeArgs2(cliArgs,3)}catch(error48){console.error(`Error: ${error48 instanceof Error?error48.message:String(error48)}`),printCliHelp(),process.exit(2)}runtimeArgs.version&&(console.log(NATIVE_HOST_VERSION),process.exit(0));runtimeArgs.help&&(printCliHelp(),process.exit(0));var isDaemonMode=runtimeArgs.daemon,discoverCdp=runtimeArgs.discoverCdp,skipBrowserRegistration=runtimeArgs.skipBrowserRegistration,CDP_PORT=runtimeArgs.cdpPort,CDP_USER_DATA_DIR=runtimeArgs.cdpUserDataDir,AGENTBAY_SESSION_ID=runtimeArgs.agentBaySessionId,AGENTBAY_IDLE_RELEASE_MINUTES=runtimeArgs.agentBayIdleReleaseMinutes,BROWSER_HEADLESS=runtimeArgs.browserHeadless,CDP_BROWSER_ID=runtimeArgs.browserId,CDP_BROWSER_NAME=runtimeArgs.browserName;function socketPathFor(suffix){return process.platform==="win32"?`\\\\.\\pipe\\mearl-agent${suffix}`:path21.join(os10.tmpdir(),`mearl-agent${suffix}.sock`)}var LEGACY_SOCKET_PATH=socketPathFor(""),INSTANCE_SOCKET_PATH=socketPathFor(`-${process.pid}`),LOG_FILE=path21.join(os10.tmpdir(),"mearl-native-host.log"),DEFAULT_TIMEOUT_MS=15e3,INVENTORY_IDLE_EXIT_MS=1e3,DISCOVERY_REQUEST_IDLE_EXIT_MS=5e3,MAX_SOCKET_BUFFER_SIZE2=64*1024*1024,extensionVersion=null,versionWarningEmitted=!1,cdpPermissionNoticeLogged=!1,EXTENSION_INSTALL_URL="https://chromewebstore.google.com/detail/mearl/aoehhjnofngknnjefamjbplchbolghkm";function majorMinor(version2){let parts=version2.split(".");return parts.length>=2?`${parts[0]}.${parts[1]}`:version2}function extractChromeVersion(input){let match=/Chrome\/([\d.]+)/.exec(input);return match?match[1].split(".").slice(0,3).join("."):null}async function fetchCdpBrowserVersion(){if(AGENTBAY_SESSION_ID)try{return(await(await getCdpSession().getBrowserClient()).sendCommand("Browser.getVersion",{},5e3)).product??null}catch{return null}let port=readDevToolsActivePort(CDP_USER_DATA_DIR)?.port??CDP_PORT;return new Promise(resolve3=>{let req=http4.get(`http://localhost:${port}/json/version`,res=>{let data="";res.on("data",chunk=>data+=chunk),res.on("end",()=>{try{let info=JSON.parse(data);resolve3(info.Browser??null)}catch{resolve3(null)}})});req.on("error",()=>resolve3(null)),req.setTimeout(2e3,()=>{req.destroy(),resolve3(null)})})}async function getCurrentBrowserUserAgent(){if(extensionVersion!==null)try{let result=await sendRequestToExtension("get_browser_info",{},3e3);if(result.userAgent?.trim())return result.userAgent}catch{}try{let result=await(await getCdpSession().getBrowserClient()).sendCommand("Browser.getVersion",{},5e3);if(result.userAgent?.trim())return result.userAgent}catch{}throw new Error("Could not determine the control browser user agent for userAgentMode=desktop")}function currentBrowserSupportsSandboxAccess(){return!BROWSER_HEADLESS}function resolveBrowserAccessCapability(){return AGENTBAY_SESSION_ID?{kind:"agentbay"}:currentBrowserSupportsSandboxAccess()?resolveSandboxBrowserAccessCapability():null}async function resolveBrowserAccess(){let capability=resolveBrowserAccessCapability();if(!capability)throw new Error("The selected browser does not expose a browser access URL");if(capability.kind==="agentbay"){if(!AGENTBAY_SESSION_ID)throw new Error("The selected browser is not an AgentBay browser");return{kind:"agentbay",url:await getAgentBayAccessUrl(AGENTBAY_SESSION_ID)}}return resolveSandboxBrowserAccess()}async function collectVersions(includeInstallationInfo=!1){let browserAccess=resolveBrowserAccessCapability(),info={nativeHost:NATIVE_HOST_VERSION,extension:extensionVersion,browser:null,...browserAccess?{browserAccess}:{}};if(extensionVersion!==null)try{let browserInfo=await sendRequestToExtension("get_browser_info",{},3e3);browserInfo?.userAgent&&(info.browser=extractChromeVersion(browserInfo.userAgent)),browserInfo?.extensionVersion&&(info.extension=browserInfo.extensionVersion),includeInstallationInfo&&(browserInfo?.extensionId&&(info.extensionId=browserInfo.extensionId),(typeof browserInfo?.setupManagedPath=="string"||browserInfo?.setupManagedPath===null)&&(info.setupManagedPath=browserInfo.setupManagedPath))}catch{}if(!info.browser){let cdpBrowser=await fetchCdpBrowserVersion();cdpBrowser&&(info.browser=extractChromeVersion(cdpBrowser))}return info}function buildVersionWarning(clientVersion){let versions=[clientVersion?{name:"client",version:clientVersion}:null,{name:"native-host",version:NATIVE_HOST_VERSION},extensionVersion?{name:"extension",version:extensionVersion}:null].filter(Boolean);return new Set(versions.map(v=>majorMinor(v.version))).size<=1?null:["â ī¸ Mearl version mismatch detected:",versions.map(v=>` - ${v.name}: ${v.version}`).join(`
|
|
1056
1351
|
`),"","This may cause unexpected behavior. To update:"," npx @mearl/setup update --local",` Browser extension: ${EXTENSION_INSTALL_URL}`].join(`
|
|
1057
1352
|
`)}var pendingRequests=new Map,nativeMessageBuffer=Buffer.alloc(0),socketServer=null,legacyServer=null,inventoryExitTimer=null,cdpRegistrationTimer=null,cdpBrowserPublished=!1,agentBaySessionWatchdog=null;function cancelInventoryExit(){inventoryExitTimer&&(clearTimeout(inventoryExitTimer),inventoryExitTimer=null)}function scheduleInventoryExit(delayMs=INVENTORY_IDLE_EXIT_MS){cancelInventoryExit(),inventoryExitTimer=setTimeout(()=>cleanupAndExit(0),delayMs),inventoryExitTimer.unref()}var cdpSession=null;function getCdpSession(){return cdpSession||(cdpSession=AGENTBAY_SESSION_ID?new CdpSession({endpointResolver:()=>resolveAgentBayEndpoint(AGENTBAY_SESSION_ID)}):new CdpSession({port:CDP_PORT,userDataDir:CDP_USER_DATA_DIR})),cdpSession}function log2(...args){let msg=`[${new Date().toISOString()}] [NativeHost] ${args.join(" ")}
|
|
1058
1353
|
`;try{fs20.appendFileSync(LOG_FILE,msg)}catch{}}function sendToExtension(message){let json2=JSON.stringify(message),length=Buffer.byteLength(json2,"utf-8"),header=Buffer.alloc(4);header.writeUInt32LE(length,0),process.stdout.write(header),process.stdout.write(json2)}var nativeHostUpdateCoordinator=new NativeHostUpdateCoordinator({hostVersion:NATIVE_HOST_VERSION,log:log2,runUpdate:targetVersion=>runNativeHostUpdate(targetVersion),requestRestart:()=>{restartAfterUpdate()}}),agentChatManager=null,agentSkillManager=new AgentSkillManager;function getAgentChatManager(){return agentChatManager||(agentChatManager=new AgentChatManager([new CodexAgentProvider(log2,NATIVE_HOST_VERSION,INSTANCE_SOCKET_PATH),new QoderAgentProvider(log2,NATIVE_HOST_VERSION)],event=>{sendToExtension({type:"agent_chat_event",data:event})})),agentChatManager}var agentServiceHandlers={agent_chat_pick_directory:async()=>({path:await pickWorkspaceDirectory()}),agent_chat_status:()=>getAgentChatManager().getStatus(),agent_chat_prepare:async data=>(await getAgentChatManager().prepare(data),{ok:!0}),agent_chat_list_sessions:data=>getAgentChatManager().listSessions(data),agent_chat_start:data=>getAgentChatManager().startSession(data),agent_chat_send:data=>getAgentChatManager().sendMessage(data),agent_chat_interrupt:async data=>(await getAgentChatManager().interrupt(data),{ok:!0}),agent_chat_close:async data=>(await getAgentChatManager().closeSession(data),{ok:!0}),agent_chat_events:data=>getAgentChatManager().getEvents(data),agent_chat_refresh:data=>getAgentChatManager().refreshSession(data),agent_chat_open_app:async data=>(await getAgentChatManager().openSession(data),{ok:!0}),agent_chat_respond:data=>(getAgentChatManager().respondToRequest(data),{ok:!0}),agent_skills_installed:async data=>{let[cli,skills]=await Promise.all([agentSkillManager.getStatus(),getAgentChatManager().listSkills(data)]);return{cli,skills}},agent_skills_read:data=>getAgentChatManager().readSkill(data),agent_skills_install:data=>agentSkillManager.install(data),agent_skills_check_updates:data=>agentSkillManager.checkUpdates(data),agent_skills_update:data=>agentSkillManager.update(data),agent_skills_uninstall:data=>agentSkillManager.uninstall(data)};function dispatchAgentServiceAction(action,request){let handler=agentServiceHandlers[action];return Promise.resolve(handler(request))}async function handleExtensionControlMessage(message){let{id,action,data={}}=message;if(isAgentServiceAction(action)){let result=await dispatchAgentServiceAction(action,data);sendToExtension({id,success:!0,data:result});return}if(action==="start_cloud_connector"){let serverUrl=data?.serverUrl;if(!serverUrl||typeof serverUrl!="string"){sendToExtension({id,success:!1,error:"serverUrl is required"});return}let result=await startCloudConnector(serverUrl);sendToExtension({id,success:result.success,data:result,error:result.error});return}if(action==="stop_cloud_connector"){let serverUrl=data?.serverUrl;if(!serverUrl||typeof serverUrl!="string"){sendToExtension({id,success:!1,error:"serverUrl is required"});return}let result=stopCloudConnector(serverUrl);sendToExtension({id,success:result.success,data:result,error:result.error});return}if(action==="list_cloud_connectors"){sendToExtension({id,success:!0,data:listCloudConnectors()});return}if(action==="update_setup_extension"){let result=await updateSetupManagedExtension({currentVersion:data?.currentVersion,setupManagedPath:data?.setupManagedPath});sendToExtension({id,success:!0,data:result});return}sendToExtension({id,success:!1,error:`Unknown extension action: ${action}`})}function handleExtensionMessage(message){if(message&&message.type==="ping"){message.version&&(extensionVersion=message.version,log2(`Extension version: ${extensionVersion}, Native Host version: ${NATIVE_HOST_VERSION}`)),setAnalyticsClientId(message.analyticsClientId),registerBrowser({browserId:typeof message.browserId=="string"?message.browserId:"default",socketPath:INSTANCE_SOCKET_PATH,browserName:typeof message.browserName=="string"?message.browserName:"Browser",nativeHostVersion:NATIVE_HOST_VERSION,transport:"extension",extensionVersion:extensionVersion??void 0}),sendToExtension({type:"pong",timestamp:Date.now(),version:NATIVE_HOST_VERSION}),nativeHostUpdateCoordinator.evaluate(message.version,message.checkForUpdates);return}if(message&&message.type==="browser_focus"){touchFocus();return}if(!message||typeof message!="object"||!message.id)return;let pending=pendingRequests.get(message.id);if(!pending){message.action&&handleExtensionControlMessage(message).catch(error48=>{sendToExtension({id:message.id,success:!1,error:error48 instanceof Error?error48.message:String(error48)})});return}clearTimeout(pending.timer),pendingRequests.delete(message.id),message.success?pending.resolve(message.data):pending.reject(new Error(message.error||"Unknown error from extension"))}function processNativeMessages(){for(;nativeMessageBuffer.length>=4;){let length=nativeMessageBuffer.readUInt32LE(0);if(nativeMessageBuffer.length<4+length)return;let jsonBytes=nativeMessageBuffer.subarray(4,4+length);nativeMessageBuffer=nativeMessageBuffer.subarray(4+length);try{let message=JSON.parse(jsonBytes.toString("utf-8"));handleExtensionMessage(message)}catch(error48){log2("Failed to parse extension message:",String(error48))}}}function setupNativeMessageInput(){process.stdin.on("readable",()=>{let chunk;for(;(chunk=process.stdin.read())!==null;)nativeMessageBuffer=Buffer.concat([nativeMessageBuffer,chunk]),processNativeMessages()}),process.stdin.on("end",()=>{log2("Extension disconnected (stdin end)"),cleanupAndExit(0)}),process.stdin.on("error",error48=>{log2("stdin error:",String(error48)),cleanupAndExit(1)})}function sendRequestToExtension(action,data,timeoutMs,trustedInternal=!1,controlSource="local"){let id=`${Date.now()}_${Math.random().toString(36).slice(2,10)}`;return new Promise((resolve3,reject)=>{let timer=setTimeout(()=>{pendingRequests.delete(id),reject(new Error(`Request timeout after ${timeoutMs}ms`))},timeoutMs);pendingRequests.set(id,{resolve:resolve3,reject,timer}),sendToExtension(createExtensionRequestMessage(id,action,data,trustedInternal,controlSource))})}function toTimeoutMs(action,data){if(action==="send_request"||action==="__send_request_with_files")return Number(data&&data.timeout?data.timeout:3e4)+5e3;if(action==="send_mtop_request")return Number(data&&data.timeout?data.timeout:1e4)+5e3;if(action==="page_wait")return Number(data?.time??data?.timeout??1e4)+5e3;if(action==="tab_open")return 4e4;if(action==="run_actions"){let timeoutMs=(Array.isArray(data?.actions)?data.actions:[{}]).reduce((total,step)=>{let stepAction=String(step?.action??"");return!stepAction||stepAction==="run_actions"?total+DEFAULT_TIMEOUT_MS:total+toTimeoutMs(stepAction,step?.data??{})},0);return Math.max(DEFAULT_TIMEOUT_MS,timeoutMs)}if(shouldObservePageAction(action,data)){let observationMs=Math.min(Math.max(Number(data?.observe?.timeoutMs??3e3),500),3e4),navigationGraceMs=Math.min(Math.max(Number(data?.observe?.navigationGraceMs??1e3),0),5e3),navigationTimeoutMs=Math.min(Math.max(Number(data?.observe?.navigationTimeoutMs??15e3),1e3),3e4);return Math.max(DEFAULT_TIMEOUT_MS,observationMs+navigationGraceMs+4e3+navigationTimeoutMs+5e3)}return DEFAULT_TIMEOUT_MS}async function handleSocketRequest(socket,line){let request;try{request=JSON.parse(line)}catch{socket.write(JSON.stringify({id:"",success:!1,error:`Invalid JSON request: ${line}`})+`
|
|
@@ -1062,7 +1357,7 @@ Examples:
|
|
|
1062
1357
|
`);return}let result=stopCloudConnector(serverUrl);socket.write(JSON.stringify({id,success:result.success,data:result})+`
|
|
1063
1358
|
`);return}if(action==="list_cloud_connectors"){let result=listCloudConnectors();socket.write(JSON.stringify({id,success:!0,data:result})+`
|
|
1064
1359
|
`);return}if(action==="get_versions"){let versions=await collectVersions(controlSource==="local");socket.write(JSON.stringify({id,success:!0,data:versions})+`
|
|
1065
|
-
`);return}if(action==="
|
|
1360
|
+
`);return}if(action==="get_browser_access_url"){try{let browserAccess=await resolveBrowserAccess();socket.write(JSON.stringify({id,success:!0,data:{browserAccess}})+`
|
|
1066
1361
|
`)}catch(error48){socket.write(JSON.stringify({id,success:!1,error:error48 instanceof Error?error48.message:String(error48)})+`
|
|
1067
1362
|
`)}return}if(isInternalExtensionAction(action)){socket.write(JSON.stringify({id,success:!1,error:"Internal action is not available to clients"})+`
|
|
1068
1363
|
`);return}if(action==="browser_list"){discoverCdp&&cancelInventoryExit();let discovered=isDaemonMode&&!skipBrowserRegistration?await ensureDiscoverableCdpBrowser({isPublished:()=>cdpBrowserPublished,isAvailable:()=>getCdpSession().isAvailable(),publish:publishDaemonBrowser,monitor:monitorConnectedDaemonBrowser}):!1,response=JSON.stringify({id,success:!0,data:listBrowserInventory()})+`
|