hypha-debugger 0.1.6 → 0.1.7
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.
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
\*******************************************************************/(e,t,n)=>{n.r(t),n.d(t,{TEXT_DECODER_THRESHOLD:()=>m,TEXT_ENCODER_THRESHOLD:()=>h,utf8Count:()=>a,utf8DecodeJs:()=>p,utf8DecodeTD:()=>g,utf8EncodeJs:()=>l,utf8EncodeTE:()=>u});var r,o,i,s=n(/*! ./int.mjs */"./node_modules/@msgpack/msgpack/dist.es5+esm/utils/int.mjs"),c=("undefined"==typeof process||"never"!==(null===(r=null===process||void 0===process?void 0:process.env)||void 0===r?void 0:r.TEXT_ENCODING))&&"undefined"!=typeof TextEncoder&&"undefined"!=typeof TextDecoder;function a(e){for(var t=e.length,n=0,r=0;r<t;){var o=e.charCodeAt(r++);if(4294967168&o)if(4294965248&o){if(o>=55296&&o<=56319&&r<t){var i=e.charCodeAt(r);56320==(64512&i)&&(++r,o=((1023&o)<<10)+(1023&i)+65536)}n+=4294901760&o?4:3}else n+=2;else n++}return n}function l(e,t,n){for(var r=e.length,o=n,i=0;i<r;){var s=e.charCodeAt(i++);if(4294967168&s){if(4294965248&s){if(s>=55296&&s<=56319&&i<r){var c=e.charCodeAt(i);56320==(64512&c)&&(++i,s=((1023&s)<<10)+(1023&c)+65536)}4294901760&s?(t[o++]=s>>18&7|240,t[o++]=s>>12&63|128,t[o++]=s>>6&63|128):(t[o++]=s>>12&15|224,t[o++]=s>>6&63|128)}else t[o++]=s>>6&31|192;t[o++]=63&s|128}else t[o++]=s}}var d=c?new TextEncoder:void 0,h=c?"undefined"!=typeof process&&"force"!==(null===(o=null===process||void 0===process?void 0:process.env)||void 0===o?void 0:o.TEXT_ENCODING)?200:0:s.UINT32_MAX;var u=(null==d?void 0:d.encodeInto)?function(e,t,n){d.encodeInto(e,t.subarray(n))}:function(e,t,n){t.set(d.encode(e),n)},_=4096;function p(e,t,n){for(var r=t,o=r+n,i=[],s="";r<o;){var c=e[r++];if(128&c)if(192==(224&c)){var a=63&e[r++];i.push((31&c)<<6|a)}else if(224==(240&c)){a=63&e[r++];var l=63&e[r++];i.push((31&c)<<12|a<<6|l)}else if(240==(248&c)){var d=(7&c)<<18|(a=63&e[r++])<<12|(l=63&e[r++])<<6|63&e[r++];d>65535&&(d-=65536,i.push(d>>>10&1023|55296),d=56320|1023&d),i.push(d)}else i.push(c);else i.push(c);i.length>=_&&(s+=String.fromCharCode.apply(String,i),i.length=0)}return i.length>0&&(s+=String.fromCharCode.apply(String,i)),s}var f=c?new TextDecoder:null,m=c?"undefined"!=typeof process&&"force"!==(null===(i=null===process||void 0===process?void 0:process.env)||void 0===i?void 0:i.TEXT_DECODER)?200:0:s.UINT32_MAX;function g(e,t,n){var r=e.subarray(t,t+n);return f.decode(r)}}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={exports:{}};return __webpack_modules__[e](n,n.exports,__webpack_require__),n.exports}__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};
|
|
56
56
|
/*!*********************************!*\
|
|
57
57
|
!*** ./src/websocket-client.js ***!
|
|
58
|
-
\*********************************/__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{API_VERSION:()=>_rpc_js__WEBPACK_IMPORTED_MODULE_0__.API_VERSION,HTTPStreamingRPCConnection:()=>_http_client_js__WEBPACK_IMPORTED_MODULE_4__.HTTPStreamingRPCConnection,LocalWebSocket:()=>LocalWebSocket,RPC:()=>_rpc_js__WEBPACK_IMPORTED_MODULE_0__.RPC,connectToServer:()=>connectToServer,connectToServerHTTP:()=>_http_client_js__WEBPACK_IMPORTED_MODULE_4__.connectToServerHTTP,getRTCService:()=>_webrtc_client_js__WEBPACK_IMPORTED_MODULE_3__.getRTCService,getRemoteService:()=>getRemoteService,getRemoteServiceHTTP:()=>_http_client_js__WEBPACK_IMPORTED_MODULE_4__.getRemoteServiceHTTP,hyphaWebsocketClient:()=>hyphaWebsocketClient,loadRequirements:()=>_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.loadRequirements,login:()=>login,logout:()=>logout,normalizeServerUrlHTTP:()=>_http_client_js__WEBPACK_IMPORTED_MODULE_4__.normalizeServerUrl,registerRTCService:()=>_webrtc_client_js__WEBPACK_IMPORTED_MODULE_3__.registerRTCService,schemaFunction:()=>_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction,setupLocalClient:()=>setupLocalClient});var _rpc_js__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./rpc.js */"./src/rpc.js"),_utils_index_js__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./utils/index.js */"./src/utils/index.js"),_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./utils/schema.js */"./src/utils/schema.js"),_webrtc_client_js__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! ./webrtc-client.js */"./src/webrtc-client.js"),_http_client_js__WEBPACK_IMPORTED_MODULE_4__=__webpack_require__(/*! ./http-client.js */"./src/http-client.js");const MAX_RETRY=1e6;class WebsocketRPCConnection{constructor(e,t,n,r,o=null,i=60,s=null,c=7200,a=null){(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(e&&t,"server_url and client_id are required"),this._server_url=e,this._client_id=t,this._workspace=n,this._token=r,this._reconnection_token=o,this._websocket=null,this._handle_message=null,this._handle_connected=null,this._handle_disconnected=null,this._timeout=i,this._WebSocketClass=s||WebSocket,this._closed=!1,this._legacy_auth=null,this.connection_info=null,this._enable_reconnect=!1,this._token_refresh_interval=c,this.manager_id=null,this._refresh_token_task=null,this._reconnect_timeouts=new Set,this._additional_headers=a,this._reconnecting=!1,this._disconnectedNotified=!1}_cleanup(){this._refresh_token_delay&&(clearTimeout(this._refresh_token_delay),this._refresh_token_delay=null),this._refresh_token_task&&(clearInterval(this._refresh_token_task),this._refresh_token_task=null);for(const e of this._reconnect_timeouts)clearTimeout(e);this._reconnect_timeouts.clear()}on_message(e){(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(e,"handler is required"),this._handle_message=e}on_connected(e){this._handle_connected=e}on_disconnected(e){this._handle_disconnected=e}async _attempt_connection(e,t=!0){return new Promise((n,r)=>{this._legacy_auth=!1;const o=new this._WebSocketClass(e);o.binaryType="arraybuffer",o.onopen=()=>{console.info("WebSocket connection established"),n(o)},o.onerror=e=>{console.error("WebSocket connection error:",e),r(new Error(`WebSocket connection error: ${e}`))},o.onclose=o=>{1003===o.code&&t?(console.info("Received 1003 error, attempting connection with query parameters."),this._legacy_auth=!0,this._attempt_connection_with_query_params(e).then(n).catch(r)):this._notifyDisconnected(o.reason)}})}async _attempt_connection_with_query_params(e){const t=[];this._client_id&&t.push(`client_id=${encodeURIComponent(this._client_id)}`),this._workspace&&t.push(`workspace=${encodeURIComponent(this._workspace)}`),this._token&&t.push(`token=${encodeURIComponent(this._token)}`),this._reconnection_token&&t.push(`reconnection_token=${encodeURIComponent(this._reconnection_token)}`);const n=e+(t.length>0?`?${t.join("&")}`:"");return await this._attempt_connection(n,!1)}_establish_connection(){return new Promise((e,t)=>{this._websocket.onmessage=n=>{const r=n.data,o=JSON.parse(r);if("connection_info"!=o.type){if("error"==o.type){const e="ConnectionAbortedError: "+o.message;return console.error("Failed to connect, "+e),void t(new Error(e))}return console.error("ConnectionAbortedError: Unexpected message received from the server:",r),void t(new Error("ConnectionAbortedError: Unexpected message received from the server"))}this.connection_info=o,this._workspace&&(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(this.connection_info.workspace===this._workspace,`Connected to the wrong workspace: ${this.connection_info.workspace}, expected: ${this._workspace}`),this.connection_info.reconnection_token&&(this._reconnection_token=this.connection_info.reconnection_token),this.connection_info.reconnection_token_life_time&&this._token_refresh_interval>this.connection_info.reconnection_token_life_time/1.5&&(console.warn(`Token refresh interval is too long (${this._token_refresh_interval}), setting it to 1.5 times of the token life time(${this.connection_info.reconnection_token_life_time}).`),this._token_refresh_interval=this.connection_info.reconnection_token_life_time/1.5),this.manager_id=this.connection_info.manager_id||null,console.log(`Successfully connected to the server, workspace: ${this.connection_info.workspace}, manager_id: ${this.manager_id}`),this.connection_info.announcement&&console.log(`${this.connection_info.announcement}`),e(this.connection_info)}})}async open(){console.log("Creating a new websocket connection to",this._server_url.split("?")[0]);try{if(this._websocket=await this._attempt_connection(this._server_url),this._legacy_auth)throw new Error("NotImplementedError: Legacy authentication is not supported");const e=JSON.stringify({client_id:this._client_id,workspace:this._workspace,token:this._token,reconnection_token:this._reconnection_token});return this._websocket.send(e),await(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.waitFor)(this._establish_connection(),this._timeout,"Failed to receive the first message from the server"),this._token_refresh_interval>0&&(this._refresh_token_delay=setTimeout(()=>{this._refresh_token_delay=null,this._closed||(this._send_refresh_token(),this._refresh_token_task=setInterval(()=>{this._send_refresh_token()},1e3*this._token_refresh_interval))},2e3)),this._enable_reconnect=!0,this._closed=!1,this._disconnectedNotified=!1,this._websocket.onmessage=e=>{if("string"==typeof e.data){const t=JSON.parse(e.data);"reconnection_token"===t.type?this._reconnection_token=t.reconnection_token:console.log("Received message from the server:",t)}else this._handle_message(e.data)},this._websocket.onerror=e=>{console.error("WebSocket connection error:",e),this._cleanup()},this._websocket.onclose=this._handle_close.bind(this),this._handle_connected&&this._handle_connected(this.connection_info),this.connection_info}catch(e){throw this._cleanup(),console.error("Failed to connect to",this._server_url.split("?")[0],e),e}}_send_refresh_token(){if(this._websocket&&this._websocket.readyState===WebSocket.OPEN){const e=JSON.stringify({type:"refresh_token"});this._websocket.send(e)}}_notifyDisconnected(e){this._disconnectedNotified||(this._disconnectedNotified=!0,this._handle_disconnected&&this._handle_disconnected(e))}_handle_close(e){if(!this._closed&&this._websocket&&this._websocket.readyState===WebSocket.CLOSED){if(this._cleanup(),this._disconnectedNotified=!1,this._enable_reconnect){if([1e3,1001].includes(e.code)?console.warn(`Websocket connection closed gracefully by server (code: ${e.code}): ${e.reason} - attempting reconnect`):console.warn("Websocket connection closed unexpectedly (code: %s): %s",e.code,e.reason),this._notifyDisconnected(e.reason),this._reconnecting)return void console.debug("Reconnection already in progress, skipping");this._reconnecting=!0;let t=0;const n=1e3,r=6e4,o=.1,i=async()=>{if(this._closed)return console.info("Connection was closed, stopping reconnection"),void(this._reconnecting=!1);try{console.warn(`Reconnecting to ${this._server_url.split("?")[0]} (attempt #${t})`),await this.open(),await new Promise(e=>setTimeout(e,500)),console.warn(`Successfully reconnected to server ${this._server_url} (services re-registered)`),this._reconnecting=!1}catch(e){if(`${e}`.includes("ConnectionAbortedError:"))return console.warn("Server refused to reconnect:",e),this._closed=!0,this._reconnecting=!1,void this._notifyDisconnected(`Server refused reconnection: ${e}`);if(`${e}`.includes("NotImplementedError:"))return console.error(`${e}\nIt appears that you are trying to connect to a hypha server that is older than 0.20.0, please upgrade the hypha server or use the websocket client in imjoy-rpc(https://www.npmjs.com/package/imjoy-rpc) instead`),this._closed=!0,this._reconnecting=!1,void this._notifyDisconnected(`Server too old: ${e}`);"NetworkError"===e.name||e.message.includes("network")?console.error(`Network error during reconnection: ${e.message}`):"TimeoutError"===e.name||e.message.includes("timeout")?console.error(`Connection timeout during reconnection: ${e.message}`):console.error(`Unexpected error during reconnection: ${e.message}`);const s=Math.min(n*Math.pow(2,t),r),c=(2*Math.random()-1)*o*s,a=Math.max(100,s+c);console.debug(`Waiting ${(a/1e3).toFixed(2)}s before next reconnection attempt`);const l=setTimeout(async()=>(this._reconnect_timeouts.delete(l),this._websocket&&this._websocket.readyState===WebSocket.OPEN?(console.info("Connection restored externally"),void(this._reconnecting=!1)):this._closed?(console.info("Connection was closed, stopping reconnection"),void(this._reconnecting=!1)):(t+=1,void(t<MAX_RETRY?await i():(console.error(`Failed to reconnect after ${MAX_RETRY} attempts, giving up.`),this._closed=!0,this._reconnecting=!1,this._notifyDisconnected("Max reconnection attempts exceeded"))))),a);this._reconnect_timeouts.add(l)}};i()}}else this._cleanup(),this._notifyDisconnected(e.reason)}async emit_message(e){if(this._closed)throw new Error("Connection is closed");this._websocket&&this._websocket.readyState===WebSocket.OPEN||await this.open();try{this._websocket.send(e)}catch(e){throw console.error(`Failed to send data, error: ${e}`),e}}disconnect(e){this._closed=!0,this._reconnecting=!1,this._websocket&&this._websocket.readyState!==WebSocket.CLOSED&&this._websocket.readyState!==WebSocket.CLOSING&&this._websocket.close(1e3,e),this._cleanup(),console.info(`WebSocket connection disconnected (${e})`)}}function normalizeServerUrl(e){if(!e)throw new Error("server_url is required");return e.startsWith("http://")?e=e.replace("http://","ws://").replace(/\/$/,"")+"/ws":e.startsWith("https://")&&(e=e.replace("https://","wss://").replace(/\/$/,"")+"/ws"),e}async function login(e){const t=e.login_service_id||"public/hypha-login",n=e.workspace,r=e.expires_in,o=e.login_timeout||60,i=e.login_callback,s=e.profile,c=e.additional_headers,a=e.transport||"websocket",l=await connectToServer({name:"initial login client",server_url:e.server_url,additional_headers:c,transport:a});try{const e=await l.getService(t);let c;return(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(e,`Failed to get the login service: ${t}`),c=n?await e.start({workspace:n,expires_in:r,_rkwargs:!0}):await e.start(),i?await i(c):console.log(`Please open your browser and login at ${c.login_url}`),await e.check(c.key,{timeout:o,profile:s,_rkwargs:!0})}catch(e){throw e}finally{await l.disconnect()}}async function logout(e){const t=e.login_service_id||"public/hypha-login",n=e.logout_callback,r=e.additional_headers,o=e.transport||"websocket",i=await connectToServer({name:"initial logout client",server_url:e.server_url,additional_headers:r,transport:o});try{const e=await i.getService(t);if((0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(e,`Failed to get the login service: ${t}`),!e.logout)throw new Error("Logout is not supported by this server. Please upgrade the Hypha server to a version that supports logout.");const r=await e.logout({});return n?await n(r):console.log(`Please open your browser to logout at ${r.logout_url}`),r}catch(e){throw e}finally{await i.disconnect()}}async function webrtcGetService(e,t,n){const r=void 0!==(n=n||{}).webrtc?n.webrtc:"auto",o=n.webrtc_config;void 0!==n.webrtc&&delete n.webrtc,void 0!==n.webrtc_config&&delete n.webrtc_config,(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)([void 0,!0,!1,"auto"].includes(r),"webrtc must be true, false or 'auto'");const i=await e.getService(t,n);if(!0===r||"auto"===r){if(i.id.includes(":")&&i.id.includes("/"))try{const t=i.id.split(":")[0].split("/"),r=t[t.length-1],s=`${t.slice(0,-1).join("/")}/${r}-rtc`,c=await(0,_webrtc_client_js__WEBPACK_IMPORTED_MODULE_3__.getRTCService)(e,s,o),a=await c.getService(i.id.split(":")[1],n);return a._webrtc=!0,a._peer=c,a._service=i,a}catch(e){console.warn("Failed to get webrtc service, using websocket connection",e)}if(!0===r)throw new Error("Failed to get the service via webrtc")}return i}async function connectToServer(e){if("http"===(e.transport||"websocket"))return await(0,_http_client_js__WEBPACK_IMPORTED_MODULE_4__.connectToServerHTTP)(e);e.server&&(e.server_url=e.server_url||e.server.url,e.WebSocketClass=e.WebSocketClass||e.server.WebSocketClass);let t=e.client_id;t||(t=(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.randId)(),e.client_id=t),0===Object.keys(e).length&&("undefined"!=typeof process&&process.env?(e.server_url=process.env.HYPHA_SERVER_URL,e.token=process.env.HYPHA_TOKEN,e.client_id=process.env.HYPHA_CLIENT_ID,e.workspace=process.env.HYPHA_WORKSPACE):"undefined"!=typeof self&&self.env?(e.server_url=self.env.HYPHA_SERVER_URL,e.token=self.env.HYPHA_TOKEN,e.client_id=self.env.HYPHA_CLIENT_ID,e.workspace=self.env.HYPHA_WORKSPACE):"undefined"!=typeof globalThis&&globalThis.env&&(e.server_url=globalThis.env.HYPHA_SERVER_URL,e.token=globalThis.env.HYPHA_TOKEN,e.client_id=globalThis.env.HYPHA_CLIENT_ID,e.workspace=globalThis.env.HYPHA_WORKSPACE));let n=normalizeServerUrl(e.server_url),r=new WebsocketRPCConnection(n,t,e.workspace,e.token,e.reconnection_token,e.method_timeout||60,e.WebSocketClass,e.token_refresh_interval,e.additional_headers);const o=await r.open();if((0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(o,"Failed to connect to the server, no connection info obtained. This issue is most likely due to an outdated Hypha server version. Please use `imjoy-rpc` for compatibility, or upgrade the Hypha server to the latest version."),await new Promise(e=>setTimeout(e,100)),!r.manager_id){console.warn("Manager ID not set immediately, waiting...");const e=5e3,t=100,n=Date.now();for(;!r.manager_id&&Date.now()-n<e;)await new Promise(e=>setTimeout(e,t));if(!r.manager_id)throw console.error("Manager ID still not set after waiting"),new Error("Failed to get manager ID from server");console.info(`Manager ID set after waiting: ${r.manager_id}`)}if(e.workspace&&o.workspace!==e.workspace)throw new Error(`Connected to the wrong workspace: ${o.workspace}, expected: ${e.workspace}`);const i=o.workspace,s=new _rpc_js__WEBPACK_IMPORTED_MODULE_0__.RPC(r,{client_id:t,workspace:i,default_context:{connection_type:"websocket"},name:e.name,method_timeout:e.method_timeout,app_id:e.app_id,server_base_url:o.public_base_url,long_message_chunk_size:e.long_message_chunk_size});await s.waitFor("services_registered",e.method_timeout||120);const c=await s.get_manager_service({timeout:e.method_timeout,case_conversion:"camel",kwargs_expansion:e.kwargs_expansion||!1});if(c.rpc=s,o&&(c.config=Object.assign(c.config,o)),c.export=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(async function(t){t.id="default",t.name=t.name||e.name||t.id,t.description=t.description||e.description,await s.register_service(t,{overwrite:!0})},{name:"export",description:"Export the api.",parameters:{properties:{api:{description:"The api to export",type:"object"}},required:["api"],type:"object"}}),c.getApp=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(async function(e){return e=e||"*",(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(!e.includes(":"),"clientId should not contain ':'"),e.includes("/")||(e=o.workspace+"/"+e),(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(2===e.split("/").length,"clientId should match pattern workspace/clientId"),await c.getService(`${e}:default`)},{name:"getApp",description:"Get the app.",parameters:{properties:{clientId:{default:"*",description:"The clientId",type:"string"}},type:"object"}}),c.listApps=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(async function(e){e=e||i,(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(!e.includes(":"),"workspace should not contain ':'"),(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(!e.includes("/"),"workspace should not contain '/'");const t={workspace:e,service_id:"default"};return await c.listServices(t)},{name:"listApps",description:"List the apps.",parameters:{properties:{workspace:{default:i,description:"The workspace",type:"string"}},type:"object"}}),c.disconnect=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.disconnect.bind(s),{name:"disconnect",description:"Disconnect from the server.",parameters:{type:"object",properties:{},required:[]}}),c.registerCodec=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.register_codec.bind(s),{name:"registerCodec",description:"Register a codec for the webrtc connection",parameters:{type:"object",properties:{codec:{type:"object",description:"Codec to register",properties:{name:{type:"string"},type:{},encoder:{type:"function"},decoder:{type:"function"}}}}}}),c.emit=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.emit.bind(s),{name:"emit",description:"Emit a message.",parameters:{properties:{data:{description:"The data to emit",type:"object"}},required:["data"],type:"object"}}),c.on=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.on.bind(s),{name:"on",description:"Register a message handler.",parameters:{properties:{event:{description:"The event to listen to",type:"string"},handler:{description:"The handler function",type:"function"}},required:["event","handler"],type:"object"}}),c.off=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.off.bind(s),{name:"off",description:"Remove a message handler.",parameters:{properties:{event:{description:"The event to remove",type:"string"},handler:{description:"The handler function",type:"function"}},required:["event","handler"],type:"object"}}),c.once=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.once.bind(s),{name:"once",description:"Register a one-time message handler.",parameters:{properties:{event:{description:"The event to listen to",type:"string"},handler:{description:"The handler function",type:"function"}},required:["event","handler"],type:"object"}}),c.getServiceSchema=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.get_service_schema,{name:"getServiceSchema",description:"Get the service schema.",parameters:{properties:{service:{description:"The service to extract schema",type:"object"}},required:["service"],type:"object"}}),c.registerService=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.register_service.bind(s),{name:"registerService",description:"Register a service.",parameters:{properties:{service:{description:"The service to register",type:"object"},force:{default:!1,description:"Force to register the service",type:"boolean"}},required:["service"],type:"object"}}),c.unregisterService=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.unregister_service.bind(s),{name:"unregisterService",description:"Unregister a service.",parameters:{properties:{service:{description:"The service id to unregister",type:"string"},notify:{default:!0,description:"Notify the workspace manager",type:"boolean"}},required:["service"],type:"object"}}),r.manager_id&&s.on("force-exit",async e=>{e.from==="*/"+r.manager_id&&(console.log("Disconnecting from server, reason:",e.reason),await s.disconnect())}),e.webrtc){await(0,_webrtc_client_js__WEBPACK_IMPORTED_MODULE_3__.registerRTCService)(c,`${t}-rtc`,e.webrtc_config);const n=Object.assign({},c),r=n.getService.__schema__.description,o=n.getService.__schema__.parameters;c.getService=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(webrtcGetService.bind(null,n),{name:"getService",description:r,parameters:o}),c.getRTCService=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(_webrtc_client_js__WEBPACK_IMPORTED_MODULE_3__.getRTCService.bind(null,c),{name:"getRTCService",description:"Get the webrtc connection, returns a peer connection.",parameters:{properties:{config:{description:"The config for the webrtc service",type:"object"}},required:["config"],type:"object"}})}else{const e=c.getService;c.getService=(t,n)=>e(t,n=n||{}),c.getService.__schema__=e.__schema__}return c.registerProbes=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(async function(e){return e.id="probes",e.name="Probes",e.config={visibility:"public"},e.type="probes",e.description=`Probes Service, visit ${n}/${i}services/probes for the available probes.`,await c.registerService(e,{overwrite:!0})},{name:"registerProbes",description:"Register probes service",parameters:{properties:{probes:{description:"The probes to register, e.g. {'liveness': {'type': 'function', 'description': 'Check the liveness of the service'}}",type:"object"}},required:["probes"],type:"object"}}),c}async function getRemoteService(e,t={}){const{serverUrl:n,workspace:r,clientId:o,serviceId:i,appId:s}=(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.parseServiceUrl)(e),c=`${r}/${o}:${i}@${s}`;if(t.serverUrl&&t.serverUrl!==n)throw new Error("server_url in config does not match the server_url in the url");t.serverUrl=n;const a=await connectToServer(t);return await a.getService(c)}class LocalWebSocket{constructor(e,t,n){this.url=e,this.onopen=()=>{},this.onmessage=()=>{},this.onclose=()=>{},this.onerror=()=>{},this.client_id=t,this.workspace=n;const r="undefined"!=typeof window?window:self,o="undefined"!=typeof window;if(this.postMessage=e=>{o?window.parent.postMessage(e,"*"):self.postMessage(e)},this.readyState=WebSocket.CONNECTING,this._context=r,this._messageListener=e=>{const{type:t,data:n,to:r}=e.data;if(r===this.client_id)switch(t){case"message":this.readyState===WebSocket.OPEN&&this.onmessage&&this.onmessage({data:n});break;case"connected":this.readyState=WebSocket.OPEN,this.onopen(e);break;case"closed":this.readyState=WebSocket.CLOSED,this.onclose(e)}},r.addEventListener("message",this._messageListener,!1),!this.client_id)throw new Error("client_id is required");if(!this.workspace)throw new Error("workspace is required");this.postMessage({type:"connect",url:this.url,from:this.client_id,workspace:this.workspace})}send(e){this.readyState===WebSocket.OPEN&&this.postMessage({type:"message",data:e,from:this.client_id,workspace:this.workspace})}close(){this.readyState=WebSocket.CLOSING,this.postMessage({type:"close",from:this.client_id,workspace:this.workspace}),this._context&&this._messageListener&&(this._context.removeEventListener("message",this._messageListener,!1),this._messageListener=null),this.onclose()}addEventListener(e,t){"message"===e&&(this.onmessage=t),"open"===e&&(this.onopen=t),"close"===e&&(this.onclose=t),"error"===e&&(this.onerror=t)}}const hyphaWebsocketClient={RPC:_rpc_js__WEBPACK_IMPORTED_MODULE_0__.RPC,API_VERSION:_rpc_js__WEBPACK_IMPORTED_MODULE_0__.API_VERSION,schemaFunction:_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction,loadRequirements:_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.loadRequirements,login:login,logout:logout,connectToServer:connectToServer,connectToServerHTTP:_http_client_js__WEBPACK_IMPORTED_MODULE_4__.connectToServerHTTP,getRemoteService:getRemoteService,getRemoteServiceHTTP:_http_client_js__WEBPACK_IMPORTED_MODULE_4__.getRemoteServiceHTTP,getRTCService:_webrtc_client_js__WEBPACK_IMPORTED_MODULE_3__.getRTCService,registerRTCService:_webrtc_client_js__WEBPACK_IMPORTED_MODULE_3__.registerRTCService,get setupLocalClient(){return setupLocalClient},get LocalWebSocket(){return LocalWebSocket},HTTPStreamingRPCConnection:_http_client_js__WEBPACK_IMPORTED_MODULE_4__.HTTPStreamingRPCConnection,normalizeServerUrlHTTP:_http_client_js__WEBPACK_IMPORTED_MODULE_4__.normalizeServerUrl};function setupLocalClient({enable_execution:enable_execution=!1,on_ready:on_ready=null}){return new Promise((resolve,reject)=>{const context="undefined"!=typeof window?window:self,isWindow="undefined"!=typeof window;context.addEventListener("message",event=>{const{type:type,server_url:server_url,workspace:workspace,client_id:client_id,token:token,method_timeout:method_timeout,name:name,config:config}=event.data;if("initializeHyphaClient"===type){if(!server_url||!workspace||!client_id)return void console.error("server_url, workspace, and client_id are required.");if(!server_url.startsWith("https://local-hypha-server:"))return void console.error("server_url should start with https://local-hypha-server:");class FixedLocalWebSocket extends LocalWebSocket{constructor(e){super(e,client_id,workspace)}}connectToServer({server_url:server_url,workspace:workspace,client_id:client_id,token:token,method_timeout:method_timeout,name:name,WebSocketClass:FixedLocalWebSocket}).then(async server=>{globalThis.api=server;try{if(isWindow&&enable_execution){function e(e){return new Promise((t,n)=>{const r=document.createElement("script");r.innerHTML=e.content,r.lang=e.lang,r.onload=()=>t(),r.onerror=e=>n(e),document.head.appendChild(r)})}if(config.styles&&config.styles.length>0)for(const t of config.styles){const n=document.createElement("style");n.innerHTML=t.content,n.lang=t.lang,document.head.appendChild(n)}if(config.links&&config.links.length>0)for(const r of config.links){const o=document.createElement("a");o.href=r.url,o.innerText=r.text,document.body.appendChild(o)}if(config.windows&&config.windows.length>0)for(const i of config.windows){document.body.innerHTML=i.content;break}if(config.scripts&&config.scripts.length>0)for(const s of config.scripts){if("javascript"!==s.lang)throw new Error("Only javascript scripts are supported");await e(s)}}else if(!isWindow&&enable_execution&&config.scripts&&config.scripts.length>0)for(const script of config.scripts){if("javascript"!==script.lang)throw new Error("Only javascript scripts are supported");eval(script.content)}on_ready&&await on_ready(server,config),resolve(server)}catch(c){reject(c)}})}},!1),isWindow?window.parent.postMessage({type:"hyphaClientReady"},"*"):self.postMessage({type:"hyphaClientReady"})})}var __webpack_exports__API_VERSION=__webpack_exports__.API_VERSION,__webpack_exports__HTTPStreamingRPCConnection=__webpack_exports__.HTTPStreamingRPCConnection,__webpack_exports__LocalWebSocket=__webpack_exports__.LocalWebSocket,__webpack_exports__RPC=__webpack_exports__.RPC,__webpack_exports__connectToServer=__webpack_exports__.connectToServer,__webpack_exports__connectToServerHTTP=__webpack_exports__.connectToServerHTTP,__webpack_exports__getRTCService=__webpack_exports__.getRTCService,__webpack_exports__getRemoteService=__webpack_exports__.getRemoteService,__webpack_exports__getRemoteServiceHTTP=__webpack_exports__.getRemoteServiceHTTP,__webpack_exports__hyphaWebsocketClient=__webpack_exports__.hyphaWebsocketClient,__webpack_exports__loadRequirements=__webpack_exports__.loadRequirements,__webpack_exports__login=__webpack_exports__.login,__webpack_exports__logout=__webpack_exports__.logout,__webpack_exports__normalizeServerUrlHTTP=__webpack_exports__.normalizeServerUrlHTTP,__webpack_exports__registerRTCService=__webpack_exports__.registerRTCService,__webpack_exports__schemaFunction=__webpack_exports__.schemaFunction,__webpack_exports__setupLocalClient=__webpack_exports__.setupLocalClient,hyphaRpcWebsocket=Object.freeze({__proto__:null,API_VERSION:__webpack_exports__API_VERSION,HTTPStreamingRPCConnection:__webpack_exports__HTTPStreamingRPCConnection,LocalWebSocket:__webpack_exports__LocalWebSocket,RPC:__webpack_exports__RPC,connectToServer:__webpack_exports__connectToServer,connectToServerHTTP:__webpack_exports__connectToServerHTTP,getRTCService:__webpack_exports__getRTCService,getRemoteService:__webpack_exports__getRemoteService,getRemoteServiceHTTP:__webpack_exports__getRemoteServiceHTTP,hyphaWebsocketClient:__webpack_exports__hyphaWebsocketClient,loadRequirements:__webpack_exports__loadRequirements,login:__webpack_exports__login,logout:__webpack_exports__logout,normalizeServerUrlHTTP:__webpack_exports__normalizeServerUrlHTTP,registerRTCService:__webpack_exports__registerRTCService,schemaFunction:__webpack_exports__schemaFunction,setupLocalClient:__webpack_exports__setupLocalClient}),hyphaRpc=Object.freeze({__proto__:null,API_VERSION:__webpack_exports__API_VERSION,HTTPStreamingRPCConnection:__webpack_exports__HTTPStreamingRPCConnection,LocalWebSocket:__webpack_exports__LocalWebSocket,RPC:__webpack_exports__RPC,connectToServer:__webpack_exports__connectToServer,connectToServerHTTP:__webpack_exports__connectToServerHTTP,getRTCService:__webpack_exports__getRTCService,getRemoteService:__webpack_exports__getRemoteService,getRemoteServiceHTTP:__webpack_exports__getRemoteServiceHTTP,hyphaWebsocketClient:hyphaRpcWebsocket,loadRequirements:__webpack_exports__loadRequirements,login:__webpack_exports__login,logout:__webpack_exports__logout,normalizeServerUrlHTTP:__webpack_exports__normalizeServerUrlHTTP,registerRTCService:__webpack_exports__registerRTCService,schemaFunction:__webpack_exports__schemaFunction,setupLocalClient:__webpack_exports__setupLocalClient});const overlayStyles="\n :host {\n all: initial;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n }\n\n * {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n\n .debugger-icon {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: #4a90d9;\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\n transition: transform 0.15s, background 0.15s;\n user-select: none;\n font-size: 18px;\n line-height: 1;\n }\n\n .debugger-icon:hover {\n transform: scale(1.1);\n background: #357abd;\n }\n\n .debugger-icon.connected {\n background: #27ae60;\n }\n\n .debugger-icon.error {\n background: #e74c3c;\n }\n\n .debugger-panel {\n display: none;\n width: 380px;\n max-height: 520px;\n background: #1e1e2e;\n color: #cdd6f4;\n border-radius: 8px;\n border: 1px solid #45475a;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);\n overflow: hidden;\n flex-direction: column;\n position: absolute;\n bottom: 50px;\n right: 0;\n font-size: 13px;\n }\n\n .debugger-panel.open {\n display: flex;\n }\n\n .panel-header {\n background: #313244;\n padding: 8px 12px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: default;\n border-bottom: 1px solid #45475a;\n font-weight: 600;\n font-size: 12px;\n letter-spacing: 0.3px;\n text-transform: uppercase;\n color: #a6adc8;\n }\n\n .panel-header .title {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .panel-header .close-btn {\n cursor: pointer;\n color: #6c7086;\n font-size: 16px;\n line-height: 1;\n padding: 2px 4px;\n border-radius: 3px;\n }\n\n .panel-header .close-btn:hover {\n color: #cdd6f4;\n background: #45475a;\n }\n\n .status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n display: inline-block;\n background: #6c7086;\n }\n\n .status-dot.connected {\n background: #a6e3a1;\n }\n\n .status-dot.error {\n background: #f38ba8;\n }\n\n .panel-body {\n padding: 10px 12px;\n overflow-y: auto;\n flex: 1;\n max-height: 440px;\n }\n\n .info-row {\n display: flex;\n justify-content: space-between;\n padding: 4px 0;\n border-bottom: 1px solid #313244;\n font-size: 12px;\n }\n\n .info-row .label {\n color: #6c7086;\n }\n\n .info-row .value {\n color: #cdd6f4;\n text-align: right;\n word-break: break-all;\n max-width: 180px;\n font-family: 'SF Mono', Monaco, Consolas, monospace;\n font-size: 11px;\n }\n\n .instructions-section {\n margin-top: 8px;\n padding-top: 6px;\n border-top: 1px solid #313244;\n }\n\n .instructions-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 4px;\n }\n\n .url-label {\n font-size: 11px;\n color: #6c7086;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 3px;\n }\n\n .instructions-block {\n font-family: 'SF Mono', Monaco, Consolas, monospace;\n font-size: 10px;\n color: #a6e3a1;\n background: #11111b;\n border: 1px solid #313244;\n border-radius: 4px;\n padding: 8px;\n white-space: pre-wrap;\n word-break: break-all;\n max-height: 200px;\n overflow-y: auto;\n line-height: 1.5;\n }\n\n .copy-btn {\n background: #45475a;\n color: #cdd6f4;\n border: none;\n border-radius: 3px;\n padding: 2px 8px;\n font-size: 10px;\n cursor: pointer;\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n .copy-btn:hover {\n background: #585b70;\n }\n\n .log-section {\n margin-top: 8px;\n }\n\n .log-title {\n font-size: 11px;\n color: #6c7086;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 4px;\n }\n\n .log-entry {\n font-family: 'SF Mono', Monaco, Consolas, monospace;\n font-size: 11px;\n padding: 3px 6px;\n border-radius: 3px;\n background: #313244;\n margin-bottom: 2px;\n color: #a6adc8;\n word-break: break-all;\n }\n\n .log-entry.call {\n border-left: 2px solid #89b4fa;\n }\n\n .log-entry.result {\n border-left: 2px solid #a6e3a1;\n }\n\n .log-entry.error {\n border-left: 2px solid #f38ba8;\n color: #f38ba8;\n }\n";class DebugOverlay{constructor(e){this.isOpen=!1,this.isDragging=!1,this.dragOffset={x:0,y:0},this.maxLogEntries=50,this.host=document.createElement("div"),this.host.id="hypha-debugger-host",Object.assign(this.host.style,{position:"fixed",bottom:"20px",right:"20px",zIndex:"2147483647",display:"flex",flexDirection:"column",alignItems:"flex-end"}),e?.position&&(this.host.style.bottom="auto",this.host.style.right="auto",this.host.style.left=e.position.x+"px",this.host.style.top=e.position.y+"px"),this.shadow=this.host.attachShadow({mode:"open"});const t=document.createElement("style");t.textContent=overlayStyles,this.shadow.appendChild(t);const n=document.createElement("div");n.style.position="relative",n.style.display="flex",n.style.flexDirection="column",n.style.alignItems="flex-end",this.panel=document.createElement("div"),this.panel.className="debugger-panel";const r=document.createElement("div");r.className="panel-header";const o=document.createElement("span");o.className="title",this.statusDot=document.createElement("span"),this.statusDot.className="status-dot",o.appendChild(this.statusDot),o.appendChild(document.createTextNode(" Hypha Debugger"));const i=document.createElement("span");i.className="close-btn",i.textContent="×",i.addEventListener("click",()=>this.toggle()),r.appendChild(o),r.appendChild(i);const s=document.createElement("div");s.className="panel-body",this.infoBody=document.createElement("div"),s.appendChild(this.infoBody);const c=document.createElement("div");c.className="log-section";const a=document.createElement("div");a.className="log-title",a.textContent="Remote Operations",this.logContainer=document.createElement("div"),c.appendChild(a),c.appendChild(this.logContainer),s.appendChild(c),this.panel.appendChild(r),this.panel.appendChild(s),this.icon=document.createElement("div"),this.icon.className="debugger-icon",this.icon.textContent="🐛",this.icon.addEventListener("click",e=>{this.isDragging||this.toggle()}),n.appendChild(this.panel),n.appendChild(this.icon),this.shadow.appendChild(n),document.documentElement.appendChild(this.host),this.setupDrag()}setupDrag(){let e=0,t=0,n=!1;this.icon.addEventListener("mousedown",r=>{e=r.clientX,t=r.clientY,n=!1;const o=this.host.getBoundingClientRect();this.dragOffset.x=r.clientX-o.left,this.dragOffset.y=r.clientY-o.top,r.preventDefault()}),document.addEventListener("mousemove",r=>{if(0===e&&0===t)return;const o=Math.abs(r.clientX-e),i=Math.abs(r.clientY-t);(o>3||i>3)&&(n=!0,this.isDragging=!0,this.host.style.left=r.clientX-this.dragOffset.x+"px",this.host.style.top=r.clientY-this.dragOffset.y+"px",this.host.style.right="auto",this.host.style.bottom="auto")}),document.addEventListener("mouseup",()=>{e=0,t=0,n&&setTimeout(()=>{this.isDragging=!1},50)})}toggle(){this.isOpen=!this.isOpen,this.panel.classList.toggle("open",this.isOpen)}setStatus(e){this.statusDot.className="status-dot",this.icon.className="debugger-icon","connected"===e?(this.statusDot.classList.add("connected"),this.icon.classList.add("connected")):"error"===e&&(this.statusDot.classList.add("error"),this.icon.classList.add("error"))}setInfo(e){this.infoBody.querySelectorAll(".info-row").forEach(e=>e.remove());const t=this.infoBody.firstChild;for(const[n,r]of Object.entries(e)){const e=document.createElement("div");e.className="info-row";const o=document.createElement("span");o.className="label",o.textContent=n;const i=document.createElement("span");i.className="value",i.textContent=r,i.title=r,e.appendChild(o),e.appendChild(i),this.infoBody.insertBefore(e,t)}}setInstructions(e){const t=this.infoBody.querySelector(".instructions-section");t&&t.remove();const n=document.createElement("div");n.className="instructions-section";const r=document.createElement("div");r.className="instructions-header";const o=document.createElement("span");o.className="url-label",o.textContent="Instructions";const i=document.createElement("button");i.className="copy-btn",i.textContent="Copy All",i.addEventListener("click",()=>{navigator.clipboard.writeText(e).then(()=>{i.textContent="Copied!",setTimeout(()=>{i.textContent="Copy All"},1500)})}),r.appendChild(o),r.appendChild(i),n.appendChild(r);const s=document.createElement("pre");s.className="instructions-block",s.textContent=e,n.appendChild(s),this.infoBody.appendChild(n)}addLog(e,t="call"){const n=document.createElement("div");for(n.className=`log-entry ${t}`,n.textContent=e,this.logContainer.appendChild(n);this.logContainer.children.length>this.maxLogEntries;)this.logContainer.removeChild(this.logContainer.firstChild);const r=this.panel.querySelector(".panel-body");r&&(r.scrollTop=r.scrollHeight)}destroy(){this.host.remove()}}const CURSOR_BORDER_SVG='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" fill="none"><g><path d="M 15 42 L 15 36.99 Q 15 31.99 23.7 31.99 L 28.05 31.99 Q 32.41 31.99 32.41 21.99 L 32.41 17 Q 32.41 12 41.09 16.95 L 76.31 37.05 Q 85 42 76.31 46.95 L 41.09 67.05 Q 32.41 72 32.41 62.01 L 32.41 57.01 Q 32.41 52.01 23.7 52.01 L 19.35 52.01 Q 15 52.01 15 47.01 Z" fill="none" stroke="currentColor" stroke-width="6" stroke-miterlimit="10"/></g></svg>',CURSOR_FILL_SVG='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><g style="filter: drop-shadow(rgba(0, 0, 0, 0.3) 3px 4px 4px);"><path d="M 15 42 L 15 36.99 Q 15 31.99 23.7 31.99 L 28.05 31.99 Q 32.41 31.99 32.41 21.99 L 32.41 17 Q 32.41 12 41.09 16.95 L 76.31 37.05 Q 85 42 76.31 46.95 L 41.09 67.05 Q 32.41 72 32.41 62.01 L 32.41 57.01 Q 32.41 52.01 23.7 52.01 L 19.35 52.01 Q 15 52.01 15 47.01 Z" fill="#ffffff" stroke="none"/></g></svg>',CURSOR_CSS="\n .hypha-cursor {\n position: fixed;\n width: 50px;\n height: 50px;\n pointer-events: none;\n z-index: 2147483646;\n transition: opacity 0.2s;\n opacity: 0;\n }\n .hypha-cursor.visible {\n opacity: 1;\n }\n .hypha-cursor-border {\n position: absolute;\n width: 100%;\n height: 100%;\n background: linear-gradient(45deg, rgb(57, 182, 255), rgb(189, 69, 251));\n mask-image: var(--cursor-border);\n -webkit-mask-image: var(--cursor-border);\n mask-size: 100% 100%;\n -webkit-mask-size: 100% 100%;\n mask-repeat: no-repeat;\n -webkit-mask-repeat: no-repeat;\n transform-origin: center;\n transform: rotate(-135deg) scale(1.2);\n margin-left: -10px;\n margin-top: -14px;\n }\n .hypha-cursor-fill {\n position: absolute;\n width: 100%;\n height: 100%;\n background-image: var(--cursor-fill);\n background-size: 100% 100%;\n background-repeat: no-repeat;\n transform-origin: center;\n transform: rotate(-135deg) scale(1.2);\n margin-left: -10px;\n margin-top: -14px;\n }\n .hypha-cursor-ripple {\n position: absolute;\n width: 100%;\n height: 100%;\n pointer-events: none;\n margin-left: -50%;\n margin-top: -50%;\n }\n .hypha-cursor-ripple::after {\n content: '';\n opacity: 0;\n position: absolute;\n inset: 0;\n border: 3px solid rgba(57, 182, 255, 1);\n border-radius: 50%;\n }\n .hypha-cursor.clicking .hypha-cursor-ripple::after {\n animation: hypha-cursor-ripple 400ms ease-out forwards;\n }\n @keyframes hypha-cursor-ripple {\n 0% { transform: scale(0); opacity: 1; }\n 100% { transform: scale(2.5); opacity: 0; }\n }\n";class AICursor{constructor(){this.currentX=0,this.currentY=0,this.targetX=0,this.targetY=0,this.animating=!1,this.visible=!1,this.hideTimeout=null,this.container=document.createElement("div"),this.container.id="hypha-debugger-cursor",this.container.setAttribute("data-browser-use-ignore","true"),this.container.setAttribute("data-page-agent-ignore","true");const e=document.createElement("style");e.textContent=CURSOR_CSS,this.container.appendChild(e),this.cursor=document.createElement("div"),this.cursor.className="hypha-cursor";const t='url("data:image/svg+xml,'+encodeURIComponent(CURSOR_BORDER_SVG)+'")',n='url("data:image/svg+xml,'+encodeURIComponent(CURSOR_FILL_SVG)+'")';this.cursor.style.setProperty("--cursor-border",t),this.cursor.style.setProperty("--cursor-fill",n);const r=document.createElement("div");r.className="hypha-cursor-ripple",this.cursor.appendChild(r);const o=document.createElement("div");o.className="hypha-cursor-fill",this.cursor.appendChild(o);const i=document.createElement("div");i.className="hypha-cursor-border",this.cursor.appendChild(i),this.container.appendChild(this.cursor),document.body.appendChild(this.container),window.addEventListener("HyphaDebugger::MovePointerTo",e=>{const{x:t,y:n}=e.detail;this.moveTo(t,n)}),window.addEventListener("HyphaDebugger::ClickPointer",()=>{this.triggerClickAnimation()})}moveTo(e,t){this.targetX=e,this.targetY=t,this.visible||(this.visible=!0,this.currentX=e,this.currentY=t,this.cursor.style.left=`${e}px`,this.cursor.style.top=`${t}px`,this.cursor.classList.add("visible")),this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=null),this.animating||(this.animating=!0,this.animateLoop())}animateLoop(){const e=this.targetX-this.currentX,t=this.targetY-this.currentY;Math.abs(e)>1||Math.abs(t)>1?(this.currentX+=.18*e,this.currentY+=.18*t,this.cursor.style.left=`${this.currentX}px`,this.cursor.style.top=`${this.currentY}px`,requestAnimationFrame(()=>this.animateLoop())):(this.currentX=this.targetX,this.currentY=this.targetY,this.cursor.style.left=`${this.currentX}px`,this.cursor.style.top=`${this.currentY}px`,this.animating=!1,this.hideTimeout=setTimeout(()=>{this.visible=!1,this.cursor.classList.remove("visible")},2e3))}triggerClickAnimation(){this.cursor.classList.remove("clicking"),this.cursor.offsetHeight,this.cursor.classList.add("clicking")}destroy(){this.hideTimeout&&clearTimeout(this.hideTimeout),this.container.remove()}}function detectFrameworks(){const e=[],t=window;if(t.__REACT_DEVTOOLS_GLOBAL_HOOK__?.renderers?.size>0)e.push("react");else{const t=document.querySelector("#root, #app, [data-reactroot]");if(t){Object.keys(t).some(e=>e.startsWith("__reactFiber$")||e.startsWith("__reactInternalInstance$"))&&e.push("react")}}if(t.__VUE__||t.__VUE_DEVTOOLS_GLOBAL_HOOK__)e.push("vue");else{const t=document.querySelector("[data-v-app], #app");t&&t.__vue_app__&&e.push("vue")}return(t.ng||document.querySelector("[ng-version]"))&&e.push("angular"),document.querySelector("[class*='svelte-']")&&e.push("svelte"),t.__NEXT_DATA__&&e.push("nextjs"),e}function collectPageInfo(){const e=performance.getEntriesByType("navigation")[0];return{url:window.location.href,title:document.title,viewport:{width:window.innerWidth,height:window.innerHeight},document_size:{width:document.documentElement.scrollWidth,height:document.documentElement.scrollHeight},user_agent:navigator.userAgent,timestamp:(new Date).toISOString(),cookies_enabled:navigator.cookieEnabled,language:navigator.language,platform:navigator.platform,online:navigator.onLine,performance:{load_time_ms:e?Math.round(e.loadEventEnd-e.startTime):null,dom_content_loaded_ms:e?Math.round(e.domContentLoadedEventEnd-e.startTime):null},frameworks:detectFrameworks()}}function getPageInfo(e,t,n){const r=collectPageInfo();if(e){const e=window.__HYPHA_DEBUGGER__?.consoleLogs??[],o=t??50;let i=n?e.filter(e=>e.level===n):e;r.console_logs=i.slice(-o)}return r}function getConsoleLogs(e){const t=window.__HYPHA_DEBUGGER__?.consoleLogs??[],n=e?.level,r=e?.limit??100;return(n?t.filter(e=>e.level===n):t).slice(-r)}function installConsoleCapture(e=500){var t;const n=(t=window).__HYPHA_DEBUGGER__??(t.__HYPHA_DEBUGGER__={});if(n.consoleInstalled)return;n.consoleLogs=[],n.consoleInstalled=!0;const r=["log","warn","error","info"];for(const t of r){const r=console[t].bind(console);console[t]=(...o)=>{const i=n.consoleLogs;i.push({level:t,message:o.map(e=>{try{return"string"==typeof e?e:JSON.stringify(e)}catch{return String(e)}}).join(" "),timestamp:(new Date).toISOString()}),i.length>e&&i.splice(0,i.length-e),r(...o)}}}function elementToInfo(e){const t=e.getBoundingClientRect(),n={};for(const t of Array.from(e.attributes))n[t.name]=t.value;return{tag:e.tagName.toLowerCase(),id:e.id,classes:Array.from(e.classList),text:(e.textContent??"").trim().slice(0,500),attributes:n,bounds:{x:Math.round(t.x),y:Math.round(t.y),width:Math.round(t.width),height:Math.round(t.height)},visible:t.width>0&&t.height>0&&"hidden"!==getComputedStyle(e).visibility&&"none"!==getComputedStyle(e).display,children_count:e.children.length}}function queryDom(e,t){t=t??20;const n=document.querySelectorAll(e),r=[];for(let e=0;e<Math.min(n.length,t);e++)r.push(elementToInfo(n[e]));return r}function clickElement$1(e){const t=document.querySelector(e);if(!t)return{success:!1,message:`No element found for selector: ${e}`};const n=t.getBoundingClientRect();return t.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0,view:window,clientX:n.left+n.width/2,clientY:n.top+n.height/2})),{success:!0,message:`Clicked element: ${e}`}}function fillInput(e,t){const n=document.querySelector(e);if(!n)return{success:!1,message:`No element found for selector: ${e}`};const r=n.tagName.toLowerCase();if("input"===r||"textarea"===r){const o=n,i="textarea"===r?HTMLTextAreaElement.prototype:HTMLInputElement.prototype,s=Object.getOwnPropertyDescriptor(i,"value")?.set;return s?s.call(o,t):o.value=t,o.dispatchEvent(new Event("input",{bubbles:!0})),o.dispatchEvent(new Event("change",{bubbles:!0})),{success:!0,message:`Filled ${e} with value`}}if("select"===r){const r=n,o=Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype,"value")?.set;return o?o.call(r,t):r.value=t,r.dispatchEvent(new Event("change",{bubbles:!0})),{success:!0,message:`Set ${e} to ${t}`}}return{success:!1,message:`Element ${e} is not an input/textarea/select`}}function scrollTo(e){if("string"==typeof e){const t=document.querySelector(e);return t?(t.scrollIntoView({behavior:"smooth",block:"center"}),{success:!0,message:`Scrolled to ${e}`}):{success:!1,message:`No element found for selector: ${e}`}}return window.scrollTo({left:e.x,top:e.y,behavior:"smooth"}),{success:!0,message:`Scrolled to (${e.x}, ${e.y})`}}function getComputedStyles(e,t){const n=document.querySelector(e);if(!n)return{error:`No element found for selector: ${e}`};const r=getComputedStyle(n),o={},i=t??["display","position","width","height","color","background-color","font-size","font-family","margin","padding","border","opacity","visibility","overflow","z-index"];for(const e of i)o[e]=r.getPropertyValue(e);return o}function getElementBounds(e){const t=document.querySelector(e);if(!t)return{error:`No element found for selector: ${e}`};const n=t.getBoundingClientRect();return{bounds:{x:Math.round(n.x),y:Math.round(n.y),width:Math.round(n.width),height:Math.round(n.height)},visible:n.width>0&&n.height>0&&"hidden"!==getComputedStyle(t).visibility&&"none"!==getComputedStyle(t).display}}function getHtml(e,t,n){const r=t??!0,o=n??5e4,i=e?document.querySelector(e):document.documentElement;if(!i)return{error:`No element found for selector: ${e}`};const s=r?i.outerHTML:i.innerHTML,c=s.length>o;return{html:c?s.slice(0,o):s,length:s.length,truncated:c}}function resolveUrl(e,t){if(e.match(/^[a-z]+:\/\//i))return e;if(e.match(/^\/\//))return window.location.protocol+e;if(e.match(/^[a-z]+:/i))return e;const n=document.implementation.createHTMLDocument(),r=n.createElement("base"),o=n.createElement("a");return n.head.appendChild(r),n.body.appendChild(o),t&&(r.href=t),o.href=e,o.href}getPageInfo.__schema__={name:"getPageInfo",description:"Get information about the current web page including URL, title, viewport size, detected frameworks, and performance timing. Optionally include recent console logs.",parameters:{type:"object",properties:{include_logs:{type:"boolean",description:"If true, include recent console output in the response. Default: false."},log_limit:{type:"number",description:"Maximum number of console log entries to include (most recent). Default: 50."},log_level:{type:"string",description:'Filter console logs by level: "log", "warn", "error", "info". Omit for all levels.',enum:["log","warn","error","info"]}}}},getConsoleLogs.__schema__={name:"getConsoleLogs",description:"Retrieve captured console output (log, warn, error, info).",parameters:{type:"object",properties:{level:{type:"string",description:'Filter by log level: "log", "warn", "error", "info". Omit for all levels.',enum:["log","warn","error","info"]},limit:{type:"number",description:"Maximum number of log entries to return (most recent). Default: 100."}}}},queryDom.__schema__={name:"queryDom",description:"Query DOM elements by CSS selector. Returns tag, id, classes, text content, attributes, bounding rect, and visibility for each matching element.",parameters:{type:"object",properties:{selector:{type:"string",description:'CSS selector to query, e.g. "button.primary", "#app > div".'},limit:{type:"number",description:"Maximum number of elements to return. Default: 20."}},required:["selector"]}},clickElement$1.__schema__={name:"clickElement",description:"Click a DOM element matching the CSS selector.",parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the element to click."}},required:["selector"]}},fillInput.__schema__={name:"fillInput",description:"Set the value of an input, textarea, or select element. Works with React controlled components.",parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the input element."},value:{type:"string",description:"The value to set."}},required:["selector","value"]}},scrollTo.__schema__={name:"scrollTo",description:"Scroll to a DOM element (by CSS selector) or to an absolute position {x, y}.",parameters:{type:"object",properties:{target:{description:"CSS selector string to scroll to an element, or an object {x, y} for absolute scroll position."}},required:["target"]}},getComputedStyles.__schema__={name:"getComputedStyles",description:"Get computed CSS styles for an element.",parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the element."},properties:{type:"array",items:{type:"string"},description:'CSS property names to retrieve, e.g. ["color", "font-size"]. Omit for common defaults.'}},required:["selector"]}},getElementBounds.__schema__={name:"getElementBounds",description:"Get the bounding rectangle and visibility of a DOM element.",parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the element."}},required:["selector"]}},getHtml.__schema__={name:"getHtml",description:"Get the HTML content of the page or a specific element. Returns outerHTML by default. Useful for understanding page structure.",parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the element. Omit to get the full page HTML."},outer:{type:"boolean",description:"If true (default), return outerHTML (includes the element itself). If false, return innerHTML (children only)."},max_length:{type:"number",description:"Maximum character length of the returned HTML. Default: 50000. Result will be truncated if longer."}}}};const uuid=(()=>{let e=0;return()=>(e+=1,`u${`0000${(Math.random()*36**4|0).toString(36)}`.slice(-4)}${e}`)})();function toArray(e){const t=[];for(let n=0,r=e.length;n<r;n++)t.push(e[n]);return t}let styleProps=null;function getStyleProperties(e={}){return styleProps||(e.includeStyleProperties?(styleProps=e.includeStyleProperties,styleProps):(styleProps=toArray(window.getComputedStyle(document.documentElement)),styleProps))}function px(e,t){const n=(e.ownerDocument.defaultView||window).getComputedStyle(e).getPropertyValue(t);return n?parseFloat(n.replace("px","")):0}function getNodeWidth(e){const t=px(e,"border-left-width"),n=px(e,"border-right-width");return e.clientWidth+t+n}function getNodeHeight(e){const t=px(e,"border-top-width"),n=px(e,"border-bottom-width");return e.clientHeight+t+n}function getImageSize(e,t={}){return{width:t.width||getNodeWidth(e),height:t.height||getNodeHeight(e)}}function getPixelRatio(){let e,t;try{t=process}catch(e){}const n=t&&t.env?t.env.devicePixelRatio:null;return n&&(e=parseInt(n,10),Number.isNaN(e)&&(e=1)),e||window.devicePixelRatio||1}const canvasDimensionLimit=16384;function checkCanvasDimensions(e){(e.width>canvasDimensionLimit||e.height>canvasDimensionLimit)&&(e.width>canvasDimensionLimit&&e.height>canvasDimensionLimit?e.width>e.height?(e.height*=canvasDimensionLimit/e.width,e.width=canvasDimensionLimit):(e.width*=canvasDimensionLimit/e.height,e.height=canvasDimensionLimit):e.width>canvasDimensionLimit?(e.height*=canvasDimensionLimit/e.width,e.width=canvasDimensionLimit):(e.width*=canvasDimensionLimit/e.height,e.height=canvasDimensionLimit))}function createImage(e){return new Promise((t,n)=>{const r=new Image;r.onload=()=>{r.decode().then(()=>{requestAnimationFrame(()=>t(r))})},r.onerror=n,r.crossOrigin="anonymous",r.decoding="async",r.src=e})}async function svgToDataURL(e){return Promise.resolve().then(()=>(new XMLSerializer).serializeToString(e)).then(encodeURIComponent).then(e=>`data:image/svg+xml;charset=utf-8,${e}`)}async function nodeToDataURL(e,t,n){const r="http://www.w3.org/2000/svg",o=document.createElementNS(r,"svg"),i=document.createElementNS(r,"foreignObject");return o.setAttribute("width",`${t}`),o.setAttribute("height",`${n}`),o.setAttribute("viewBox",`0 0 ${t} ${n}`),i.setAttribute("width","100%"),i.setAttribute("height","100%"),i.setAttribute("x","0"),i.setAttribute("y","0"),i.setAttribute("externalResourcesRequired","true"),o.appendChild(i),i.appendChild(e),svgToDataURL(o)}const isInstanceOfElement=(e,t)=>{if(e instanceof t)return!0;const n=Object.getPrototypeOf(e);return null!==n&&(n.constructor.name===t.name||isInstanceOfElement(n,t))};function formatCSSText(e){const t=e.getPropertyValue("content");return`${e.cssText} content: '${t.replace(/'|"/g,"")}';`}function formatCSSProperties(e,t){return getStyleProperties(t).map(t=>`${t}: ${e.getPropertyValue(t)}${e.getPropertyPriority(t)?" !important":""};`).join(" ")}function getPseudoElementStyle(e,t,n,r){const o=`.${e}:${t}`,i=n.cssText?formatCSSText(n):formatCSSProperties(n,r);return document.createTextNode(`${o}{${i}}`)}function clonePseudoElement(e,t,n,r){const o=window.getComputedStyle(e,n),i=o.getPropertyValue("content");if(""===i||"none"===i)return;const s=uuid();try{t.className=`${t.className} ${s}`}catch(e){return}const c=document.createElement("style");c.appendChild(getPseudoElementStyle(s,n,o,r)),t.appendChild(c)}function clonePseudoElements(e,t,n){clonePseudoElement(e,t,":before",n),clonePseudoElement(e,t,":after",n)}const WOFF="application/font-woff",JPEG="image/jpeg",mimes={woff:WOFF,woff2:WOFF,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:JPEG,jpeg:JPEG,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml",webp:"image/webp"};function getExtension(e){const t=/\.([^./]*?)$/g.exec(e);return t?t[1]:""}function getMimeType(e){const t=getExtension(e).toLowerCase();return mimes[t]||""}function getContentFromDataUrl(e){return e.split(/,/)[1]}function isDataUrl(e){return-1!==e.search(/^(data:)/)}function makeDataUrl(e,t){return`data:${t};base64,${e}`}async function fetchAsDataURL(e,t,n){const r=await fetch(e,t);if(404===r.status)throw new Error(`Resource "${r.url}" not found`);const o=await r.blob();return new Promise((e,t)=>{const i=new FileReader;i.onerror=t,i.onloadend=()=>{try{e(n({res:r,result:i.result}))}catch(e){t(e)}},i.readAsDataURL(o)})}const cache={};function getCacheKey(e,t,n){let r=e.replace(/\?.*/,"");return n&&(r=e),/ttf|otf|eot|woff2?/i.test(r)&&(r=r.replace(/.*\//,"")),t?`[${t}]${r}`:r}async function resourceToDataURL(e,t,n){const r=getCacheKey(e,t,n.includeQueryParams);if(null!=cache[r])return cache[r];let o;n.cacheBust&&(e+=(/\?/.test(e)?"&":"?")+(new Date).getTime());try{o=makeDataUrl(await fetchAsDataURL(e,n.fetchRequestInit,({res:e,result:n})=>(t||(t=e.headers.get("Content-Type")||""),getContentFromDataUrl(n))),t)}catch(t){o=n.imagePlaceholder||"";let r=`Failed to fetch resource: ${e}`;t&&(r="string"==typeof t?t:t.message),r&&console.warn(r)}return cache[r]=o,o}async function cloneCanvasElement(e){const t=e.toDataURL();return"data:,"===t?e.cloneNode(!1):createImage(t)}async function cloneVideoElement(e,t){if(e.currentSrc){const t=document.createElement("canvas"),n=t.getContext("2d");t.width=e.clientWidth,t.height=e.clientHeight,null==n||n.drawImage(e,0,0,t.width,t.height);return createImage(t.toDataURL())}const n=e.poster,r=getMimeType(n);return createImage(await resourceToDataURL(n,r,t))}async function cloneIFrameElement(e,t){var n;try{if(null===(n=null==e?void 0:e.contentDocument)||void 0===n?void 0:n.body)return await cloneNode(e.contentDocument.body,t,!0)}catch(e){}return e.cloneNode(!1)}async function cloneSingleNode(e,t){return isInstanceOfElement(e,HTMLCanvasElement)?cloneCanvasElement(e):isInstanceOfElement(e,HTMLVideoElement)?cloneVideoElement(e,t):isInstanceOfElement(e,HTMLIFrameElement)?cloneIFrameElement(e,t):e.cloneNode(isSVGElement(e))}const isSlotElement=e=>null!=e.tagName&&"SLOT"===e.tagName.toUpperCase(),isSVGElement=e=>null!=e.tagName&&"SVG"===e.tagName.toUpperCase();async function cloneChildren(e,t,n){var r,o;if(isSVGElement(t))return t;let i=[];return i=isSlotElement(e)&&e.assignedNodes?toArray(e.assignedNodes()):isInstanceOfElement(e,HTMLIFrameElement)&&(null===(r=e.contentDocument)||void 0===r?void 0:r.body)?toArray(e.contentDocument.body.childNodes):toArray((null!==(o=e.shadowRoot)&&void 0!==o?o:e).childNodes),0===i.length||isInstanceOfElement(e,HTMLVideoElement)||await i.reduce((e,r)=>e.then(()=>cloneNode(r,n)).then(e=>{e&&t.appendChild(e)}),Promise.resolve()),t}function cloneCSSStyle(e,t,n){const r=t.style;if(!r)return;const o=window.getComputedStyle(e);o.cssText?(r.cssText=o.cssText,r.transformOrigin=o.transformOrigin):getStyleProperties(n).forEach(n=>{let i=o.getPropertyValue(n);if("font-size"===n&&i.endsWith("px")){const e=Math.floor(parseFloat(i.substring(0,i.length-2)))-.1;i=`${e}px`}isInstanceOfElement(e,HTMLIFrameElement)&&"display"===n&&"inline"===i&&(i="block"),"d"===n&&t.getAttribute("d")&&(i=`path(${t.getAttribute("d")})`),r.setProperty(n,i,o.getPropertyPriority(n))})}function cloneInputValue(e,t){isInstanceOfElement(e,HTMLTextAreaElement)&&(t.innerHTML=e.value),isInstanceOfElement(e,HTMLInputElement)&&t.setAttribute("value",e.value)}function cloneSelectValue(e,t){if(isInstanceOfElement(e,HTMLSelectElement)){const n=t,r=Array.from(n.children).find(t=>e.value===t.getAttribute("value"));r&&r.setAttribute("selected","")}}function decorate(e,t,n){return isInstanceOfElement(t,Element)&&(cloneCSSStyle(e,t,n),clonePseudoElements(e,t,n),cloneInputValue(e,t),cloneSelectValue(e,t)),t}async function ensureSVGSymbols(e,t){const n=e.querySelectorAll?e.querySelectorAll("use"):[];if(0===n.length)return e;const r={};for(let o=0;o<n.length;o++){const i=n[o].getAttribute("xlink:href");if(i){const n=e.querySelector(i),o=document.querySelector(i);n||!o||r[i]||(r[i]=await cloneNode(o,t,!0))}}const o=Object.values(r);if(o.length){const t="http://www.w3.org/1999/xhtml",n=document.createElementNS(t,"svg");n.setAttribute("xmlns",t),n.style.position="absolute",n.style.width="0",n.style.height="0",n.style.overflow="hidden",n.style.display="none";const r=document.createElementNS(t,"defs");n.appendChild(r);for(let e=0;e<o.length;e++)r.appendChild(o[e]);e.appendChild(n)}return e}async function cloneNode(e,t,n){return n||!t.filter||t.filter(e)?Promise.resolve(e).then(e=>cloneSingleNode(e,t)).then(n=>cloneChildren(e,n,t)).then(n=>decorate(e,n,t)).then(e=>ensureSVGSymbols(e,t)):null}const URL_REGEX=/url\((['"]?)([^'"]+?)\1\)/g,URL_WITH_FORMAT_REGEX=/url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g,FONT_SRC_REGEX=/src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;function toRegex(e){const t=e.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1");return new RegExp(`(url\\(['"]?)(${t})(['"]?\\))`,"g")}function parseURLs(e){const t=[];return e.replace(URL_REGEX,(e,n,r)=>(t.push(r),e)),t.filter(e=>!isDataUrl(e))}async function embed(e,t,n,r,o){try{const i=n?resolveUrl(t,n):t,s=getMimeType(t);let c;return o||(c=await resourceToDataURL(i,s,r)),e.replace(toRegex(t),`$1${c}$3`)}catch(e){}return e}function filterPreferredFontFormat(e,{preferredFontFormat:t}){return t?e.replace(FONT_SRC_REGEX,e=>{for(;;){const[n,,r]=URL_WITH_FORMAT_REGEX.exec(e)||[];if(!r)return"";if(r===t)return`src: ${n};`}}):e}function shouldEmbed(e){return-1!==e.search(URL_REGEX)}async function embedResources(e,t,n){if(!shouldEmbed(e))return e;const r=filterPreferredFontFormat(e,n);return parseURLs(r).reduce((e,r)=>e.then(e=>embed(e,r,t,n)),Promise.resolve(r))}async function embedProp(e,t,n){var r;const o=null===(r=t.style)||void 0===r?void 0:r.getPropertyValue(e);if(o){const r=await embedResources(o,null,n);return t.style.setProperty(e,r,t.style.getPropertyPriority(e)),!0}return!1}async function embedBackground(e,t){await embedProp("background",e,t)||await embedProp("background-image",e,t),await embedProp("mask",e,t)||await embedProp("-webkit-mask",e,t)||await embedProp("mask-image",e,t)||await embedProp("-webkit-mask-image",e,t)}async function embedImageNode(e,t){const n=isInstanceOfElement(e,HTMLImageElement);if((!n||isDataUrl(e.src))&&(!isInstanceOfElement(e,SVGImageElement)||isDataUrl(e.href.baseVal)))return;const r=n?e.src:e.href.baseVal,o=await resourceToDataURL(r,getMimeType(r),t);await new Promise((r,i)=>{e.onload=r,e.onerror=t.onImageErrorHandler?(...e)=>{try{r(t.onImageErrorHandler(...e))}catch(e){i(e)}}:i;const s=e;s.decode&&(s.decode=r),"lazy"===s.loading&&(s.loading="eager"),n?(e.srcset="",e.src=o):e.href.baseVal=o})}async function embedChildren(e,t){const n=toArray(e.childNodes).map(e=>embedImages(e,t));await Promise.all(n).then(()=>e)}async function embedImages(e,t){isInstanceOfElement(e,Element)&&(await embedBackground(e,t),await embedImageNode(e,t),await embedChildren(e,t))}function applyStyle(e,t){const{style:n}=e;t.backgroundColor&&(n.backgroundColor=t.backgroundColor),t.width&&(n.width=`${t.width}px`),t.height&&(n.height=`${t.height}px`);const r=t.style;return null!=r&&Object.keys(r).forEach(e=>{n[e]=r[e]}),e}const cssFetchCache={};async function fetchCSS(e){let t=cssFetchCache[e];if(null!=t)return t;const n=await fetch(e);return t={url:e,cssText:await n.text()},cssFetchCache[e]=t,t}async function embedFonts(e,t){let n=e.cssText;const r=/url\(["']?([^"')]+)["']?\)/g,o=(n.match(/url\([^)]+\)/g)||[]).map(async o=>{let i=o.replace(r,"$1");return i.startsWith("https://")||(i=new URL(i,e.url).href),fetchAsDataURL(i,t.fetchRequestInit,({result:e})=>(n=n.replace(o,`url(${e})`),[o,e]))});return Promise.all(o).then(()=>n)}function parseCSS(e){if(null==e)return[];const t=[];let n=e.replace(/(\/\*[\s\S]*?\*\/)/gi,"");const r=new RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})","gi");for(;;){const e=r.exec(n);if(null===e)break;t.push(e[0])}n=n.replace(r,"");const o=/@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi,i=new RegExp("((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})","gi");for(;;){let e=o.exec(n);if(null===e){if(e=i.exec(n),null===e)break;o.lastIndex=i.lastIndex}else i.lastIndex=o.lastIndex;t.push(e[0])}return t}async function getCSSRules(e,t){const n=[],r=[];return e.forEach(n=>{if("cssRules"in n)try{toArray(n.cssRules||[]).forEach((e,o)=>{if(e.type===CSSRule.IMPORT_RULE){let i=o+1;const s=fetchCSS(e.href).then(e=>embedFonts(e,t)).then(e=>parseCSS(e).forEach(e=>{try{n.insertRule(e,e.startsWith("@import")?i+=1:n.cssRules.length)}catch(t){console.error("Error inserting rule from remote css",{rule:e,error:t})}})).catch(e=>{console.error("Error loading remote css",e.toString())});r.push(s)}})}catch(o){const i=e.find(e=>null==e.href)||document.styleSheets[0];null!=n.href&&r.push(fetchCSS(n.href).then(e=>embedFonts(e,t)).then(e=>parseCSS(e).forEach(e=>{i.insertRule(e,i.cssRules.length)})).catch(e=>{console.error("Error loading remote stylesheet",e)})),console.error("Error inlining remote css file",o)}}),Promise.all(r).then(()=>(e.forEach(e=>{if("cssRules"in e)try{toArray(e.cssRules||[]).forEach(e=>{n.push(e)})}catch(t){console.error(`Error while reading CSS rules from ${e.href}`,t)}}),n))}function getWebFontRules(e){return e.filter(e=>e.type===CSSRule.FONT_FACE_RULE).filter(e=>shouldEmbed(e.style.getPropertyValue("src")))}async function parseWebFontRules(e,t){if(null==e.ownerDocument)throw new Error("Provided element is not within a Document");const n=toArray(e.ownerDocument.styleSheets);return getWebFontRules(await getCSSRules(n,t))}function normalizeFontFamily(e){return e.trim().replace(/["']/g,"")}function getUsedFonts(e){const t=new Set;return function e(n){(n.style.fontFamily||getComputedStyle(n).fontFamily).split(",").forEach(e=>{t.add(normalizeFontFamily(e))}),Array.from(n.children).forEach(t=>{t instanceof HTMLElement&&e(t)})}(e),t}async function getWebFontCSS(e,t){const n=await parseWebFontRules(e,t),r=getUsedFonts(e);return(await Promise.all(n.filter(e=>r.has(normalizeFontFamily(e.style.fontFamily))).map(e=>{const n=e.parentStyleSheet?e.parentStyleSheet.href:null;return embedResources(e.cssText,n,t)}))).join("\n")}async function embedWebFonts(e,t){const n=null!=t.fontEmbedCSS?t.fontEmbedCSS:t.skipFonts?null:await getWebFontCSS(e,t);if(n){const t=document.createElement("style"),r=document.createTextNode(n);t.appendChild(r),e.firstChild?e.insertBefore(t,e.firstChild):e.appendChild(t)}}async function toSvg(e,t={}){const{width:n,height:r}=getImageSize(e,t),o=await cloneNode(e,t,!0);await embedWebFonts(o,t),await embedImages(o,t),applyStyle(o,t);return await nodeToDataURL(o,n,r)}async function toCanvas(e,t={}){const{width:n,height:r}=getImageSize(e,t),o=await toSvg(e,t),i=await createImage(o),s=document.createElement("canvas"),c=s.getContext("2d"),a=t.pixelRatio||getPixelRatio(),l=t.canvasWidth||n,d=t.canvasHeight||r;return s.width=l*a,s.height=d*a,t.skipAutoScale||checkCanvasDimensions(s),s.style.width=`${l}`,s.style.height=`${d}`,t.backgroundColor&&(c.fillStyle=t.backgroundColor,c.fillRect(0,0,s.width,s.height)),c.drawImage(i,0,0,s.width,s.height),s}async function toPng(e,t={}){return(await toCanvas(e,t)).toDataURL()}async function toJpeg(e,t={}){return(await toCanvas(e,t)).toDataURL("image/jpeg",t.quality||1)}async function takeScreenshot(e,t,n,r,o,i){const s=t??"png",c=n??.92,a=r??1,l=e?document.querySelector(e):document.body;if(!l)return{error:`No element found for selector: ${e}`};try{const e=l,t={quality:c,pixelRatio:a,cacheBust:!0,skipAutoScale:!0,filter:e=>"hypha-debugger-host"!==e.id};let n;n="jpeg"===s?await toJpeg(e,t):await toPng(e,t);const r=e.getBoundingClientRect();let d=Math.round(r.width*a),h=Math.round(r.height*a);if(o&&d>o){const e=o/d;d=o,h=Math.round(h*e)}if(i&&h>i){const e=i/h;h=i,d=Math.round(d*e)}return{data:n,format:s,width:d,height:h}}catch(e){return{error:`Screenshot failed: ${e.message??e}`}}}async function executeScript(e,t){const n=t??1e4;try{const t=await Promise.race([new Function("return (async () => {"+e+"})()")(),new Promise((e,t)=>setTimeout(()=>t(new Error("Execution timed out")),n))]);let r,o=typeof t;try{void 0===t?(r=null,o="undefined"):t instanceof HTMLElement?(r={tag:t.tagName.toLowerCase(),id:t.id,text:(t.textContent??"").trim().slice(0,500)},o="HTMLElement"):t instanceof NodeList||t instanceof HTMLCollection?(r=Array.from(t).map(e=>({tag:e.tagName?.toLowerCase(),id:e.id,text:(e.textContent??"").trim().slice(0,200)})),o="NodeList"):r=JSON.parse(JSON.stringify(t))}catch{r=String(t),o="string (serialized)"}return{result:r,type:o}}catch(e){return{error:`Execution error: ${e.message??e}`}}}takeScreenshot.__schema__={name:"takeScreenshot",description:"Capture a screenshot of the entire page or a specific element. Returns a base64-encoded data URL.",parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the element to capture. Omit to capture the entire page body."},format:{type:"string",enum:["png","jpeg"],description:'Image format. Default: "png".'},quality:{type:"number",description:"Image quality (0-1) for JPEG. Default: 0.92."},scale:{type:"number",description:"Pixel ratio / scale factor. Default: 1. Use 2 for retina."},max_width:{type:"number",description:"Maximum width in pixels. Image will be scaled down if larger."},max_height:{type:"number",description:"Maximum height in pixels. Image will be scaled down if larger."}}}},executeScript.__schema__={name:"executeScript",description:"Execute arbitrary JavaScript code in the page context. Supports async/await. Returns the result of the last expression.",parameters:{type:"object",properties:{code:{type:"string",description:'JavaScript code to execute. The result of the last expression is returned. Example: "return document.title"'},timeout_ms:{type:"number",description:"Maximum execution time in milliseconds. Default: 10000."}},required:["code"]}};const STORAGE_KEY$1="__hypha_debugger_config__";function getScriptUrl(){try{const e=sessionStorage.getItem(STORAGE_KEY$1);if(e){const t=JSON.parse(e);if(t.script_url)return t.script_url}}catch{}return"https://cdn.jsdelivr.net/npm/hypha-debugger/dist/hypha-debugger.min.js"}function injectLoader(e,t){const n=`<script src="${t}"><\/script>`;return e.includes("</body>")?e.replace("</body>",n+"\n</body>"):e.includes("</html>")?e.replace("</html>",n+"\n</html>"):e+"\n"+n}function softReplace(e,t){const n=getScriptUrl();fetch(e,{credentials:"same-origin",cache:"reload"}).then(e=>{if(!e.ok)throw new Error(`HTTP ${e.status}`);if(!(e.headers.get("content-type")??"").includes("text/html"))throw new Error("Not HTML");return e.text()}).then(e=>{const r=injectLoader(e,n);if(document.open(),document.write(r),document.close(),t)try{history.pushState({},"",t)}catch{}}).catch(()=>{t?window.location.href=t:window.location.reload()})}function isSameOrigin(e){try{return new URL(e,location.href).origin===location.origin}catch{return!1}}let _interceptInstalled=!1;function installNavigationInterceptor(){if(_interceptInstalled)return()=>{};_interceptInstalled=!0;const e=e=>{if(e.defaultPrevented||0!==e.button)return;if(e.metaKey||e.ctrlKey||e.shiftKey||e.altKey)return;let t=null,n=e.target;for(;n;){if("A"===n.tagName){t=n;break}n=n.parentElement}if(!t)return;const r=t.href;if(!r)return;if(t.target&&"_self"!==t.target)return;if(t.hasAttribute("download"))return;if(r.startsWith("javascript:")||r.startsWith("mailto:")||r.startsWith("tel:"))return;try{const e=new URL(r,location.href);if(e.origin===location.origin&&e.pathname===location.pathname&&e.search===location.search&&e.hash!==location.hash)return}catch{return}if(!isSameOrigin(r))return;e.preventDefault();const o=new URL(r,location.href).href;softReplace(o,o)},t=e=>{if(e.defaultPrevented)return;const t=e.target;if("GET"!==(t.method||"GET").toUpperCase())return;const n=t.action||location.href;if(!isSameOrigin(n))return;const r=new FormData(t),o=new URL(n,location.href);for(const[e,t]of r.entries())"string"==typeof t&&o.searchParams.set(e,t);t.target&&"_self"!==t.target||(e.preventDefault(),softReplace(o.href,o.href))},n=()=>{softReplace(location.href)};return document.addEventListener("click",e,!0),document.addEventListener("submit",t,!0),window.addEventListener("popstate",n),()=>{document.removeEventListener("click",e,!0),document.removeEventListener("submit",t,!0),window.removeEventListener("popstate",n),_interceptInstalled=!1}}function navigate(e){try{const t=new URL(e,location.href);return t.origin===location.origin?(setTimeout(()=>softReplace(t.href,t.href),150),{success:!0,message:`Navigating to ${e} (debugger will auto-reconnect)`}):(window.location.href=e,{success:!0,message:`Navigating to ${e} (cross-origin, debugger will disconnect)`})}catch(e){return{success:!1,message:`Navigation failed: ${e.message??e}`}}}function goBack(){try{return window.history.back(),{success:!0,message:"Navigated back (debugger will auto-reconnect via popstate)"}}catch(e){return{success:!1,message:`Back navigation failed: ${e.message??e}`}}}function goForward(){try{return window.history.forward(),{success:!0,message:"Navigated forward (debugger will auto-reconnect via popstate)"}}catch(e){return{success:!1,message:`Forward navigation failed: ${e.message??e}`}}}function reload(){try{return setTimeout(()=>softReplace(location.href),150),{success:!0,message:"Reloading page (debugger will auto-reconnect)"}}catch(e){return{success:!1,message:`Reload failed: ${e.message??e}`}}}function getFiberFromDOM(e){const t=Object.keys(e).find(e=>e.startsWith("__reactFiber$")||e.startsWith("__reactInternalInstance$"));return t?e[t]:null}function getComponentName(e){const{type:t}=e;if(!t)return"(unknown)";if("string"==typeof t)return t;if("function"==typeof t)return t.displayName||t.name||"Anonymous";if("object"==typeof t){if(t.displayName)return t.displayName;if(t.render)return t.render.displayName||t.render.name||"ForwardRef";if(t.type)return getComponentName({type:t.type});if("Symbol(react.memo)"===t.$$typeof?.toString())return`Memo(${getComponentName({type:t.type})})`}return"(unknown)"}function getFiberType(e){return 0===e.tag||11===e.tag||14===e.tag||15===e.tag?"function":1===e.tag?"class":5===e.tag||6===e.tag?"host":"other"}function safeSerialize(e,t=0,n=2){if(t>n)return"[max depth]";if(null==e)return e;if("function"==typeof e)return`[Function: ${e.name||"anonymous"}]`;if("object"!=typeof e)return e;if(e instanceof HTMLElement)return`[${e.tagName.toLowerCase()}#${e.id}]`;if(Array.isArray(e))return e.slice(0,10).map(e=>safeSerialize(e,t+1,n));const r={},o=Object.keys(e).slice(0,20);for(const i of o)if(!i.startsWith("_")&&!i.startsWith("$$"))try{r[i]=safeSerialize(e[i],t+1,n)}catch{r[i]="[unserializable]"}return r}function extractState(e){if(1===e.tag&&e.stateNode)return safeSerialize(e.stateNode.state);if(0===e.tag||11===e.tag||15===e.tag){const t=[];let n=e.memoizedState,r=0;for(;n&&r<20;)null!==n.queue&&void 0!==n.queue&&t.push(safeSerialize(n.memoizedState)),n=n.next,r++;return t.length>0?t:null}return null}function fiberToInfo(e,t,n){const r=getFiberType(e),o="function"===r||"class"===r,i={name:getComponentName(e),type:r,props:o?safeSerialize(e.memoizedProps):{},state:o?extractState(e):null,key:e.key,children:[]};if(t<n){let r=e.child;for(;r;){const e=fiberToInfo(r,t+1,n);e&&("host"!==e.type||e.children.length>0)&&i.children.push(e),r=r.sibling}}return i}function getReactTree(e,t){e=e??"#root";const n=t??5,r=document.querySelector(e);if(!r)return{error:`No element found for selector: ${e}`};const o=getFiberFromDOM(r);if(!o)return{error:`No React fiber found on element "${e}". Is this a React app?`};let i=o;for(;i&&3===i.tag;)i=i.child;if(!i)return{error:"Could not find root React component fiber."};const s=fiberToInfo(i,0,n);return s||{error:"Could not build React component tree."}}function generateSkillMd(e,t){const n=["---","name: web-debugger","description: Remote web page debugger. Inspect DOM, take screenshots, execute JavaScript, fill forms, click elements, and navigate pages — all via HTTP API calls.","compatibility: Requires network access to the Hypha server. Works with any HTTP client (curl, fetch, Python requests).","metadata:",' version: "0.1"',' author: "hypha-debugger"',"---"].join("\n"),r=["","# Web Debugger Skill","","This skill allows you to remotely debug and interact with a web page through HTTP API endpoints.","","## Recommended Workflow (Index-Based Interaction)","","The most reliable way to interact with a page is using the smart DOM analysis:","","### Step 1: Observe the page","```bash","curl '{SERVICE_URL}/get_browser_state'","```","This returns all interactive elements indexed as `[0]`, `[1]`, `[2]`, etc.","Elements are detected via smart heuristics: CSS cursor, ARIA roles, event listeners, tag names.","Visual highlight labels are overlaid on the page for each detected element.","","Example output:","```","[0]<a aria-label=Home>Home />","[1]<input placeholder=Search... />","[2]<button>Sign In />","[3]<select name=language>English />",'[4]<div data-scrollable="top=200, bottom=1500">Content area />',"```","","### Step 2: Act on elements by index","```bash","# Click a button (e.g. [2] Sign In):","curl -X POST '{SERVICE_URL}/click_element_by_index' \\"," -H 'Content-Type: application/json' -d '{\"index\": 2}'","","# Type into an input (e.g. [1] Search):","curl -X POST '{SERVICE_URL}/input_text' \\",' -H \'Content-Type: application/json\' -d \'{"index": 1, "text": "hello world"}\'',"","# Select a dropdown option (e.g. [3] Language):","curl -X POST '{SERVICE_URL}/select_option' \\",' -H \'Content-Type: application/json\' -d \'{"index": 3, "option_text": "French"}\'',"","# Scroll down:","curl -X POST '{SERVICE_URL}/scroll' \\"," -H 'Content-Type: application/json' -d '{\"direction\": \"down\"}'","","# Scroll a specific container (e.g. [4]):","curl -X POST '{SERVICE_URL}/scroll' \\",' -H \'Content-Type: application/json\' -d \'{"direction": "down", "index": 4}\'',"```","","### Step 3: Verify","```bash","curl '{SERVICE_URL}/take_screenshot'","```","","### Remove visual highlights (optional, for clean screenshots)","```bash","curl '{SERVICE_URL}/remove_highlights'","```","","## CSS Selector-Based Functions (Alternative)","","You can also use CSS selectors directly for precise targeting:","```bash","curl -X POST '{SERVICE_URL}/click_element' \\"," -H 'Content-Type: application/json' -d '{\"selector\": \"button.submit\"}'","","curl -X POST '{SERVICE_URL}/fill_input' \\",' -H \'Content-Type: application/json\' -d \'{"selector": "#email", "value": "user@example.com"}\'',"```","","## How to call functions","","All functions are available as HTTP endpoints. Replace `{SERVICE_URL}` with the actual service URL.","","- **GET** for functions with no required parameters","- **POST** with JSON body for functions with parameters",""].join("\n"),o=["## Available Functions",""],i=Object.entries(e).filter(([e,t])=>t?.__schema__&&"get_skill_md"!==e);for(const[e,t]of i){const n=t.__schema__;o.push(`### \`${e}\``),o.push(""),o.push(n.description),o.push("");const r=n.parameters?.properties,i=n.parameters?.required??[];if(r&&Object.keys(r).length>0){o.push("**Parameters:**"),o.push(""),o.push("| Parameter | Type | Required | Description |"),o.push("|-----------|------|----------|-------------|");for(const[e,t]of Object.entries(r)){const n=i.includes(e);let r=t.type??"any";t.enum&&(r=t.enum.map(e=>`"${e}"`).join(" | ")),t.items&&(r=`${t.items.type}[]`),o.push(`| \`${e}\` | ${r} | ${n?"Yes":"No"} | ${t.description??""} |`)}if(o.push(""),i.length>0){const t={};for(const e of i){const n=r[e];t[e]="string"===n?.type?`<${e}>`:"number"===n?.type?"0":`<${e}>`}o.push("**Example:**"),o.push("```bash"),o.push(`curl -X POST '{SERVICE_URL}/${e}' \\`),o.push(" -H 'Content-Type: application/json' \\"),o.push(` -d '${JSON.stringify(t)}'`),o.push("```")}else o.push("**Example:**"),o.push("```bash"),o.push(`curl '{SERVICE_URL}/${e}'`),o.push("```")}else o.push("**Parameters:** None"),o.push(""),o.push("**Example:**"),o.push("```bash"),o.push(`curl '{SERVICE_URL}/${e}'`),o.push("```");o.push("")}const s=["## Tips","","- **Start with `get_browser_state`** — it's the best way to understand what's on the page and what you can interact with.","- **Prefer index-based interaction** (`click_element_by_index`, `input_text`, `select_option`) over CSS selectors — indices are more reliable across dynamic pages.","- **After each action, call `get_browser_state` again** — element indices change when the DOM updates.","- **Use `take_screenshot`** to visually verify the page state. Call `remove_highlights` first for a clean view.","- **Use `execute_script`** for anything not covered by the built-in functions — it runs arbitrary JavaScript.","- **Use `scroll`** with an element index to scroll inside a specific container (e.g. a chat window, sidebar).","- **Use `get_page_info` with `include_logs=true`** to check for JavaScript errors or debug output.","- **Use `get_react_tree`** if the page uses React — it gives you component names, props, and state.","- All POST endpoints accept JSON body with the parameter names as keys.",""].join("\n");return[n,r,o.join("\n"),s].join("\n")}function wrapFn(e){const t=e.__schema__,n=t?.parameters?.properties?Object.keys(t.parameters.properties):[];if(0===n.length)return e;const r=n.join(", "),o=new Function("fn",`return async function(${r}) { return fn(${r}); }`)(e);return t&&(o.__schema__=t),o}navigate.__schema__={name:"navigate",description:"Navigate the browser to a new URL. For same-origin URLs, the debugger auto-reconnects. Cross-origin navigation will disconnect the debugger.",parameters:{type:"object",properties:{url:{type:"string",description:"The URL to navigate to."}},required:["url"]}},goBack.__schema__={name:"goBack",description:"Navigate back in browser history. The debugger auto-reconnects for same-origin pages.",parameters:{type:"object",properties:{}}},goForward.__schema__={name:"goForward",description:"Navigate forward in browser history. The debugger auto-reconnects for same-origin pages.",parameters:{type:"object",properties:{}}},reload.__schema__={name:"reload",description:"Reload the current page. The debugger auto-reconnects after reload using soft page replacement.",parameters:{type:"object",properties:{}}},getReactTree.__schema__={name:"getReactTree",description:"Inspect the React component tree starting from a DOM element. Returns component names, props, state (including hooks), and children hierarchy.",parameters:{type:"object",properties:{selector:{type:"string",description:'CSS selector of the React root element. Default: "#root".'},max_depth:{type:"number",description:"Maximum depth to traverse the component tree. Default: 5."}}}};var domTree=(e={doHighlightElements:!0,focusHighlightIndex:-1,viewportExpansion:0,debugMode:!1,interactiveBlacklist:[],interactiveWhitelist:[],highlightOpacity:.1,highlightLabelOpacity:.5})=>{const{interactiveBlacklist:t,interactiveWhitelist:n,highlightOpacity:r,highlightLabelOpacity:o}=e,{doHighlightElements:i,focusHighlightIndex:s,viewportExpansion:c,debugMode:a}=e;let l=0;const d=new WeakMap;const h={boundingRects:new WeakMap,clientRects:new WeakMap,computedStyles:new WeakMap,clearCache:()=>{h.boundingRects=new WeakMap,h.clientRects=new WeakMap,h.computedStyles=new WeakMap}};function u(e){if(!e)return null;if(h.boundingRects.has(e))return h.boundingRects.get(e);const t=e.getBoundingClientRect();return t&&h.boundingRects.set(e,t),t}function _(e){if(!e)return null;if(h.computedStyles.has(e))return h.computedStyles.get(e);const t=window.getComputedStyle(e);return t&&h.computedStyles.set(e,t),t}const p={},f={current:0},m="playwright-highlight-container";function g(e,t,n=null){if(!e)return t;const i=[];let s=null,c=20,a=16,l=null;try{let d=document.getElementById(m);d||(d=document.createElement("div"),d.id=m,d.style.position="fixed",d.style.pointerEvents="none",d.style.top="0",d.style.left="0",d.style.width="100%",d.style.height="100%",d.style.zIndex="2147483640",d.style.backgroundColor="transparent",document.body.appendChild(d));const h=e.getClientRects();if(!h||0===h.length)return t;const u=["#FF0000","#00FF00","#0000FF","#FFA500","#800080","#008080","#FF69B4","#4B0082","#FF4500","#2E8B57","#DC143C","#4682B4"];let _=u[t%u.length];const p=_+Math.floor(255*r).toString(16).padStart(2,"0");_+=Math.floor(255*o).toString(16).padStart(2,"0");let f={x:0,y:0};if(n){const e=n.getBoundingClientRect();f.x=e.left,f.y=e.top}const g=document.createDocumentFragment();for(const e of h){if(0===e.width||0===e.height)continue;const t=document.createElement("div");t.style.position="fixed",t.style.border=`2px solid ${_}`,t.style.backgroundColor=p,t.style.pointerEvents="none",t.style.boxSizing="border-box";const n=e.top+f.y,r=e.left+f.x;t.style.top=`${n}px`,t.style.left=`${r}px`,t.style.width=`${e.width}px`,t.style.height=`${e.height}px`,g.appendChild(t),i.push({element:t,initialRect:e})}const y=h[0];s=document.createElement("div"),s.className="playwright-highlight-label",s.style.position="fixed",s.style.background=_,s.style.color="white",s.style.padding="1px 4px",s.style.borderRadius="4px",s.style.fontSize=`${Math.min(12,Math.max(8,y.height/2))}px`,s.textContent=t.toString(),c=s.offsetWidth>0?s.offsetWidth:c,a=s.offsetHeight>0?s.offsetHeight:a;const w=y.top+f.y,b=y.left+f.x;let v=w+2,E=b+y.width-c-2;(y.width<c+4||y.height<a+4)&&(v=w-a-2,E=b+y.width-c,E<f.x&&(E=b)),v=Math.max(0,Math.min(v,window.innerHeight-a)),E=Math.max(0,Math.min(E,window.innerWidth-c)),s.style.top=`${v}px`,s.style.left=`${E}px`,g.appendChild(s);const k=(e,t)=>{let n=0;return(...r)=>{const o=performance.now();if(!(o-n<t))return n=o,e(...r)}},x=k(()=>{const t=e.getClientRects();let r={x:0,y:0};if(n){const e=n.getBoundingClientRect();r.x=e.left,r.y=e.top}if(i.forEach((e,n)=>{if(n<t.length){const o=t[n],i=o.top+r.y,s=o.left+r.x;e.element.style.top=`${i}px`,e.element.style.left=`${s}px`,e.element.style.width=`${o.width}px`,e.element.style.height=`${o.height}px`,e.element.style.display=0===o.width||0===o.height?"none":"block"}else e.element.style.display="none"}),t.length<i.length)for(let e=t.length;e<i.length;e++)i[e].element.style.display="none";if(s&&t.length>0){const e=t[0],n=e.top+r.y,o=e.left+r.x;let i=n+2,l=o+e.width-c-2;(e.width<c+4||e.height<a+4)&&(i=n-a-2,l=o+e.width-c,l<r.x&&(l=o)),i=Math.max(0,Math.min(i,window.innerHeight-a)),l=Math.max(0,Math.min(l,window.innerWidth-c)),s.style.top=`${i}px`,s.style.left=`${l}px`,s.style.display="block"}else s&&(s.style.display="none")},16);return window.addEventListener("scroll",x,!0),window.addEventListener("resize",x),l=()=>{window.removeEventListener("scroll",x,!0),window.removeEventListener("resize",x),i.forEach(e=>e.element.remove()),s&&s.remove()},d.appendChild(g),t+1}finally{l&&(window._highlightCleanupFunctions=window._highlightCleanupFunctions||[]).push(l)}}function y(e){if(!e||e.nodeType!==Node.ELEMENT_NODE)return null;const t=_(e);if(!t)return null;const n=t.display;if("inline"===n||"inline-block"===n)return null;const r=t.overflowX,o=t.overflowY,i="auto"===r||"scroll"===r,s="auto"===o||"scroll"===o;if(!i&&!s)return null;const c=e.scrollWidth-e.clientWidth,a=e.scrollHeight-e.clientHeight;if(c<4&&a<4)return null;if(!s&&c<4)return null;if(!i&&a<4)return null;const l=e.scrollTop,h=e.scrollLeft,u={top:l,right:e.scrollWidth-e.clientWidth-e.scrollLeft,bottom:e.scrollHeight-e.clientHeight-e.scrollTop,left:h};return function(e,t){e&&e.nodeType===Node.ELEMENT_NODE&&d.set(e,{...d.get(e),...t})}(e,{scrollable:!0,scrollData:u}),u}function w(e){try{if(-1===c){const t=e.parentElement;if(!t)return!1;try{return t.checkVisibility({checkOpacity:!0,checkVisibilityCSS:!0})}catch(e){const n=window.getComputedStyle(t);return"none"!==n.display&&"hidden"!==n.visibility&&"0"!==n.opacity}}const t=document.createRange();t.selectNodeContents(e);const n=t.getClientRects();if(!n||0===n.length)return!1;let r=!1,o=!1;for(const e of n)if(e.width>0&&e.height>0&&(r=!0,!(e.bottom<-c||e.top>window.innerHeight+c||e.right<-c||e.left>window.innerWidth+c))){o=!0;break}if(!r||!o)return!1;const i=e.parentElement;if(!i)return!1;try{return i.checkVisibility({checkOpacity:!0,checkVisibilityCSS:!0})}catch(e){const t=window.getComputedStyle(i);return"none"!==t.display&&"hidden"!==t.visibility&&"0"!==t.opacity}}catch(e){return console.warn("Error checking text node visibility:",e),!1}}function b(e){const t=_(e);return e.offsetWidth>0&&e.offsetHeight>0&&"hidden"!==t?.visibility&&"none"!==t?.display}function v(e){if(!e||e.nodeType!==Node.ELEMENT_NODE)return!1;if(t.includes(e))return!1;if(n.includes(e))return!0;const r=e.tagName.toLowerCase(),o=_(e),i=new Set(["pointer","move","text","grab","grabbing","cell","copy","alias","all-scroll","col-resize","context-menu","crosshair","e-resize","ew-resize","help","n-resize","ne-resize","nesw-resize","ns-resize","nw-resize","nwse-resize","row-resize","s-resize","se-resize","sw-resize","vertical-text","w-resize","zoom-in","zoom-out"]),s=new Set(["not-allowed","no-drop","wait","progress","initial","inherit"]);let c=function(e){return"html"!==e.tagName.toLowerCase()&&!(!o?.cursor||!i.has(o.cursor))}(e);if(c)return!0;const a=new Set(["a","button","input","select","textarea","details","summary","label","option","optgroup","fieldset","legend"]),l=new Set(["disabled","readonly"]);if(a.has(r)){if(o?.cursor&&s.has(o.cursor))return!1;for(const t of l)if(e.hasAttribute(t)||"true"===e.getAttribute(t)||""===e.getAttribute(t))return!1;return!e.disabled&&(!e.readOnly&&!e.inert)}const d=e.getAttribute("role"),h=e.getAttribute("aria-role");if("true"===e.getAttribute("contenteditable")||e.isContentEditable)return!0;if(e.classList&&(e.classList.contains("button")||e.classList.contains("dropdown-toggle")||e.getAttribute("data-index")||"dropdown"===e.getAttribute("data-toggle")||"true"===e.getAttribute("aria-haspopup")))return!0;const u=new Set(["button","menu","menubar","menuitem","menuitemradio","menuitemcheckbox","radio","checkbox","tab","switch","slider","spinbutton","combobox","searchbox","textbox","listbox","option","scrollbar"]);if(a.has(r)||d&&u.has(d)||h&&u.has(h))return!0;try{if("function"==typeof getEventListeners){const t=getEventListeners(e),n=["click","mousedown","mouseup","dblclick"];for(const e of n)if(t[e]&&t[e].length>0)return!0}const t=e?.ownerDocument?.defaultView?.getEventListenersForNode||window.getEventListenersForNode;if("function"==typeof t){const n=t(e),r=["click","mousedown","mouseup","keydown","keyup","submit","change","input","focus","blur"];for(const e of r)for(const t of n)if(t.type===e)return!0}const n=["onclick","onmousedown","onmouseup","ondblclick"];for(const t of n)if(e.hasAttribute(t)||"function"==typeof e[t])return!0}catch(e){}return!!y(e)}function E(e){if(-1===c)return!0;const t=function(e){if(!e)return null;if(h.clientRects.has(e))return h.clientRects.get(e);const t=e.getClientRects();return t&&h.clientRects.set(e,t),t}(e);if(!t||0===t.length)return!1;let n=!1;for(const e of t)if(e.width>0&&e.height>0&&!(e.bottom<-c||e.top>window.innerHeight+c||e.right<-c||e.left>window.innerWidth+c)){n=!0;break}if(!n)return!1;if(e.ownerDocument!==window.document)return!0;let r=Array.from(t).find(e=>e.width>0&&e.height>0);if(!r)return!1;const o=e.getRootNode();if(o instanceof ShadowRoot){const t=r.left+r.width/2,n=r.top+r.height/2;try{const r=o.elementFromPoint(t,n);if(!r)return!1;let i=r;for(;i&&i!==o;){if(i===e)return!0;i=i.parentElement}return!1}catch(e){return!0}}return[{x:r.left+r.width/2,y:r.top+r.height/2},{x:r.left+5,y:r.top+5},{x:r.right-5,y:r.bottom-5}].some(({x:t,y:n})=>{try{const r=document.elementFromPoint(t,n);if(!r)return!1;let o=r;for(;o&&o!==document.documentElement;){if(o===e)return!0;o=o.parentElement}return!1}catch(e){return!0}})}const k=new Set(["a","button","input","select","textarea","summary","details","label","option"]),x=new Set(["button","link","menuitem","menuitemradio","menuitemcheckbox","radio","checkbox","tab","switch","slider","spinbutton","combobox","searchbox","textbox","listbox","option","scrollbar"]);function S(e){if(!e||e.nodeType!==Node.ELEMENT_NODE)return!1;const t=e.tagName.toLowerCase(),n=e.getAttribute("role");if("iframe"===t)return!0;if(k.has(t))return!0;if(n&&x.has(n))return!0;if(e.isContentEditable||"true"===e.getAttribute("contenteditable"))return!0;if(e.hasAttribute("data-testid")||e.hasAttribute("data-cy")||e.hasAttribute("data-test"))return!0;if(e.hasAttribute("onclick")||"function"==typeof e.onclick)return!0;try{const t=e?.ownerDocument?.defaultView?.getEventListenersForNode||window.getEventListenersForNode;if("function"==typeof t){const n=t(e),r=["click","mousedown","mouseup","keydown","keyup","submit","change","input","focus","blur"];for(const e of r)for(const t of n)if(t.type===e)return!0}if(["onmousedown","onmouseup","onkeydown","onkeyup","onsubmit","onchange","oninput","onfocus","onblur"].some(t=>e.hasAttribute(t)))return!0}catch(e){}return!!function(e){if(!e||e.nodeType!==Node.ELEMENT_NODE)return!1;if(!b(e))return!1;const t=e.hasAttribute("role")||e.hasAttribute("tabindex")||e.hasAttribute("onclick")||"function"==typeof e.onclick,n=/\b(btn|clickable|menu|item|entry|link)\b/i.test(e.className||""),r=Boolean(e.closest('button,a,[role="button"],.menu,.dropdown,.list,.toolbar')),o=[...e.children].some(b),i=e.parentElement&&e.parentElement.isSameNode(document.body);return(v(e)||t||n)&&o&&r&&!i}(e)}function T(e,t,n,r){if(!e.isInteractive)return!1;let o=!1;return o=!r||!!S(t),!(!o||(e.isInViewport=function(e,t){if(-1===t)return!0;const n=e.getClientRects();if(!n||0===n.length){const n=u(e);return!(!n||0===n.width||0===n.height||n.bottom<-t||n.top>window.innerHeight+t||n.right<-t||n.left>window.innerWidth+t)}for(const e of n)if(0!==e.width&&0!==e.height&&!(e.bottom<-t||e.top>window.innerHeight+t||e.right<-t||e.left>window.innerWidth+t))return!0;return!1}(t,c),!e.isInViewport&&-1!==c||(e.highlightIndex=l++,!i)))&&(s>=0?s===e.highlightIndex&&g(t,e.highlightIndex,n):g(t,e.highlightIndex,n),!0)}const C=function e(t,n=null,r=!1){if(!t||t.id===m||t.nodeType!==Node.ELEMENT_NODE&&t.nodeType!==Node.TEXT_NODE)return null;if(!t||t.id===m)return null;if("true"===t.dataset?.browserUseIgnore||"true"===t.dataset?.pageAgentIgnore)return null;if(t.getAttribute&&"true"===t.getAttribute("aria-hidden"))return null;if(t===document.body){const r={tagName:"body",attributes:{},xpath:"/body",children:[]};for(const o of t.childNodes){const t=e(o,n,!1);t&&r.children.push(t)}const o=""+f.current++;return p[o]=r,o}if(t.nodeType!==Node.ELEMENT_NODE&&t.nodeType!==Node.TEXT_NODE)return null;if(t.nodeType===Node.TEXT_NODE){const e=t.textContent?.trim();if(!e)return null;const n=t.parentElement;if(!n||"script"===n.tagName.toLowerCase())return null;const r=""+f.current++;return p[r]={type:"TEXT_NODE",text:e,isVisible:w(t)},r}if(t.nodeType===Node.ELEMENT_NODE&&!function(e){if(!e||!e.tagName)return!1;const t=new Set(["body","div","main","article","section","nav","header","footer"]),n=e.tagName.toLowerCase();return!!t.has(n)||!new Set(["svg","script","style","link","meta","noscript","template"]).has(n)}(t))return null;if(-1!==c&&!t.shadowRoot){const e=u(t),n=_(t),r=n&&("fixed"===n.position||"sticky"===n.position),o=t.offsetWidth>0||t.offsetHeight>0;if(!e||!r&&!o&&(e.bottom<-c||e.top>window.innerHeight+c||e.right<-c||e.left>window.innerWidth+c))return null}const o={tagName:t.tagName.toLowerCase(),attributes:{},children:[]};if(function(e){if(!e||e.nodeType!==Node.ELEMENT_NODE)return!1;const t=e.tagName.toLowerCase();return!!new Set(["a","button","input","select","textarea","details","summary","label"]).has(t)||(e.hasAttribute("onclick")||e.hasAttribute("role")||e.hasAttribute("tabindex")||e.hasAttribute("aria-")||e.hasAttribute("data-action")||"true"===e.getAttribute("contenteditable"))}(t)||"iframe"===t.tagName.toLowerCase()||"body"===t.tagName.toLowerCase()){const e=t.getAttributeNames?.()||[];for(const n of e){const e=t.getAttribute(n);o.attributes[n]=e}"input"!==t.tagName.toLowerCase()||"checkbox"!==t.type&&"radio"!==t.type||(o.attributes.checked=t.checked?"true":"false")}let i=!1;if(t.nodeType===Node.ELEMENT_NODE&&(o.isVisible=b(t),o.isVisible)){o.isTopElement=E(t);const e=t.getAttribute("role"),s="menu"===e||"menubar"===e||"listbox"===e;if((o.isTopElement||s)&&(o.isInteractive=v(t),i=T(o,t,n,r),o.ref=t,o.isInteractive&&0===Object.keys(o.attributes).length)){const e=t.getAttributeNames?.()||[];for(const n of e){const e=t.getAttribute(n);o.attributes[n]=e}}}if(t.tagName){const s=t.tagName.toLowerCase();if("iframe"===s)try{const n=t.contentDocument||t.contentWindow?.document;if(n)for(const r of n.childNodes){const n=e(r,t,!1);n&&o.children.push(n)}}catch(e){console.warn("Unable to access iframe:",e)}else if(t.isContentEditable||"true"===t.getAttribute("contenteditable")||"tinymce"===t.id||t.classList.contains("mce-content-body")||"body"===s&&t.getAttribute("data-id")?.startsWith("mce_"))for(const r of t.childNodes){const t=e(r,n,i);t&&o.children.push(t)}else{if(t.shadowRoot){o.shadowRoot=!0;for(const r of t.shadowRoot.childNodes){const t=e(r,n,i);t&&o.children.push(t)}}for(const s of t.childNodes){const t=e(s,n,i||r);t&&o.children.push(t)}}}if("a"===o.tagName&&0===o.children.length&&!o.attributes.href){const e=u(t);if(!(e&&e.width>0&&e.height>0||t.offsetWidth>0||t.offsetHeight>0))return null}o.extra=d.get(t)||null;const s=""+f.current++;return p[s]=o,s}(document.body);return h.clearCache(),{rootId:C,map:p}};const DEFAULT_VIEWPORT_EXPANSION=-1;function resolveViewportExpansion(e){return e??DEFAULT_VIEWPORT_EXPANSION}const newElementsCache=new WeakMap;function getFlatTree(e){const t=resolveViewportExpansion(e.viewportExpansion),n=[];for(const t of e.interactiveBlacklist||[])"function"==typeof t?n.push(t()):n.push(t);const r=[];for(const t of e.interactiveWhitelist||[])"function"==typeof t?r.push(t()):r.push(t);const o=domTree({doHighlightElements:!0,debugMode:!0,focusHighlightIndex:-1,viewportExpansion:t,interactiveBlacklist:n,interactiveWhitelist:r,highlightOpacity:e.highlightOpacity??0,highlightLabelOpacity:e.highlightLabelOpacity??.1});for(const e in o.map){const t=o.map[e];if(t.isInteractive&&t.ref){const e=t.ref;newElementsCache.has(e)||(newElementsCache.set(e,window.location.href),t.isNew=!0)}}return o}const globRegexCache=new Map;function globToRegex(e){let t=globRegexCache.get(e);if(!t){const n=e.replace(/[.+^${}()|[\]\\]/g,"\\$&");t=new RegExp(`^${n.replace(/\*/g,".*")}$`),globRegexCache.set(e,t)}return t}function matchAttributes(e,t){const n={};for(const r of t)if(r.includes("*")){const t=globToRegex(r);for(const r of Object.keys(e))t.test(r)&&e[r].trim()&&(n[r]=e[r].trim())}else{const t=e[r];t&&t.trim()&&(n[r]=t.trim())}return n}function flatTreeToString(e,t){const n=[...t||[],"title","type","checked","name","role","value","placeholder","data-date-format","alt","aria-label","aria-expanded","data-state","aria-checked","id","for","target","aria-haspopup","aria-controls","aria-owns","contenteditable"],r=t=>{const n=e.map[t];if(!n)return null;if("TEXT_NODE"===n.type){const e=n;return{type:"text",text:e.text,isVisible:e.isVisible,parent:null,children:[]}}{const e=n,t=[];if(e.children)for(const n of e.children){const e=r(n);e&&t.push(e)}return{type:"element",tagName:e.tagName,attributes:e.attributes??{},isVisible:e.isVisible??!1,isInteractive:e.isInteractive??!1,isTopElement:e.isTopElement??!1,isNew:e.isNew??!1,highlightIndex:e.highlightIndex,parent:null,children:t,extra:e.extra??{}}}},o=(e,t=null)=>{e.parent=t;for(const t of e.children)o(t,e)},i=r(e.rootId);if(!i)return"";o(i);const s=(e,t,r)=>{let o=t;const i="\t".repeat(t);if("element"===e.type){if(void 0!==e.highlightIndex){o+=1;const t=getAllTextTillNextClickableElement(e);let s="";if(n.length>0&&e.attributes){const r=matchAttributes(e.attributes,n),o=Object.keys(r);if(o.length>1){const e=new Set,t={};for(const n of o){const o=r[n];o.length>5&&(o in t?e.add(n):t[o]=n)}for(const t of e)delete r[t]}r.role===e.tagName&&delete r.role;const i=["aria-label","placeholder","title"];for(const e of i)r[e]&&r[e].toLowerCase().trim()===t.toLowerCase().trim()&&delete r[e];Object.keys(r).length>0&&(s=Object.entries(r).map(([e,t])=>`${e}=${((e,t)=>e.length>t?e.substring(0,t)+"...":e)(t,20)}`).join(" "))}let c=`${i}${e.isNew?`*[${e.highlightIndex}]`:`[${e.highlightIndex}]`}<${e.tagName??""}`;if(s&&(c+=` ${s}`),e.extra&&e.extra.scrollable){let t="";e.extra.scrollData?.left&&(t+=`left=${e.extra.scrollData.left}, `),e.extra.scrollData?.top&&(t+=`top=${e.extra.scrollData.top}, `),e.extra.scrollData?.right&&(t+=`right=${e.extra.scrollData.right}, `),e.extra.scrollData?.bottom&&(t+=`bottom=${e.extra.scrollData.bottom}`),c+=` data-scrollable="${t}"`}if(t){s||(c+=" "),c+=`>${t.trim()}`}else s||(c+=" ");c+=" />",r.push(c)}for(const t of e.children)s(t,o,r)}else if("text"===e.type){if((e=>{let t=e.parent;for(;t;){if("element"===t.type&&void 0!==t.highlightIndex)return!0;t=t.parent}return!1})(e))return;e.parent&&"element"===e.parent.type&&e.parent.isVisible&&e.parent.isTopElement&&r.push(`${i}${e.text??""}`)}},c=[];return s(i,0,c),c.join("\n")}const getAllTextTillNextClickableElement=(e,t=-1)=>{const n=[],r=(o,i)=>{if(!(-1!==t&&i>t||"element"===o.type&&o!==e&&void 0!==o.highlightIndex))if("text"===o.type&&o.text)n.push(o.text);else if("element"===o.type)for(const e of o.children)r(e,i+1)};return r(e,0),n.join("\n").trim()};function getSelectorMap(e){const t=new Map,n=Object.keys(e.map);for(const r of n){const n=e.map[r];n.isInteractive&&"number"==typeof n.highlightIndex&&t.set(n.highlightIndex,n)}return t}function getElementTextMap(e){const t=e.split("\n").map(e=>e.trim()).filter(e=>e.length>0),n=new Map;for(const e of t){const t=/^\[(\d+)\]<[^>]+>([^<]*)/.exec(e);if(t){const r=parseInt(t[1],10);n.set(r,e)}}return n}function cleanUpHighlights(){const e=window._highlightCleanupFunctions||[];for(const t of e)"function"==typeof t&&t();window._highlightCleanupFunctions=[]}async function waitFor(e){await new Promise(t=>setTimeout(t,1e3*e))}function getElementByIndex(e,t){const n=e.get(t);if(!n)throw new Error(`No interactive element found at index ${t}`);const r=n.ref;if(!r)throw new Error(`Element at index ${t} does not have a reference`);if(!(r instanceof HTMLElement))throw new Error(`Element at index ${t} is not an HTMLElement`);return r}let lastClickedElement=null;function blurLastClickedElement(){lastClickedElement&&(lastClickedElement.blur(),lastClickedElement.dispatchEvent(new MouseEvent("mouseout",{bubbles:!0,cancelable:!0})),lastClickedElement=null)}async function scrollIntoViewIfNeeded(e){const t=e.getBoundingClientRect();t.top>=0&&t.bottom<=window.innerHeight&&t.left>=0&&t.right<=window.innerWidth||(e.scrollIntoView({behavior:"smooth",block:"center",inline:"nearest"}),await waitFor(.4))}async function movePointerToElement(e){const t=e.getBoundingClientRect(),n=t.left+t.width/2,r=t.top+t.height/2;window.dispatchEvent(new CustomEvent("HyphaDebugger::MovePointerTo",{detail:{x:n,y:r}})),await waitFor(.3)}async function clickElement(e){blurLastClickedElement(),lastClickedElement=e,await scrollIntoViewIfNeeded(e),await movePointerToElement(e),window.dispatchEvent(new CustomEvent("HyphaDebugger::ClickPointer")),await waitFor(.05),e.dispatchEvent(new MouseEvent("mouseenter",{bubbles:!0,cancelable:!0})),e.dispatchEvent(new MouseEvent("mouseover",{bubbles:!0,cancelable:!0})),e.dispatchEvent(new MouseEvent("mousedown",{bubbles:!0,cancelable:!0})),e.focus(),e.dispatchEvent(new MouseEvent("mouseup",{bubbles:!0,cancelable:!0})),e.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0})),await waitFor(.2)}let _nativeInputValueSetter=null,_nativeTextAreaValueSetter=null;function getNativeInputValueSetter(){return _nativeInputValueSetter||(_nativeInputValueSetter=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,"value").set),_nativeInputValueSetter}function getNativeTextAreaValueSetter(){return _nativeTextAreaValueSetter||(_nativeTextAreaValueSetter=Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype,"value").set),_nativeTextAreaValueSetter}async function inputTextElement(e,t){const n=e.isContentEditable;if(!(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||n))throw new Error("Element is not an input, textarea, or contenteditable");await clickElement(e),n?(e.dispatchEvent(new InputEvent("beforeinput",{bubbles:!0,cancelable:!0,inputType:"deleteContent"}))&&(e.innerText="",e.dispatchEvent(new InputEvent("input",{bubbles:!0,inputType:"deleteContent"}))),e.dispatchEvent(new InputEvent("beforeinput",{bubbles:!0,cancelable:!0,inputType:"insertText",data:t}))&&(e.innerText=t,e.dispatchEvent(new InputEvent("input",{bubbles:!0,inputType:"insertText",data:t}))),e.dispatchEvent(new Event("change",{bubbles:!0})),e.blur()):e instanceof HTMLTextAreaElement?getNativeTextAreaValueSetter().call(e,t):getNativeInputValueSetter().call(e,t),n||e.dispatchEvent(new Event("input",{bubbles:!0})),await waitFor(.1),blurLastClickedElement()}async function selectOptionElement(e,t){if(!(e instanceof HTMLSelectElement))throw new Error("Element is not a select element");await scrollIntoViewIfNeeded(e);const n=e.getBoundingClientRect();window.dispatchEvent(new CustomEvent("HyphaDebugger::MovePointerTo",{detail:{x:n.left+n.width/2,y:n.top+n.height/2}})),await waitFor(.3),window.dispatchEvent(new CustomEvent("HyphaDebugger::ClickPointer"));const r=Array.from(e.options).find(e=>e.textContent?.trim()===t.trim());if(!r)throw new Error(`Option with text "${t}" not found in select element`);e.value=r.value,e.dispatchEvent(new Event("change",{bubbles:!0})),await waitFor(.1)}async function scrollVertically(e,t,n){if(n){let e=n,r=!1,o=null,i=0,s=0;const c=t;for(;e&&s<10;){const t=window.getComputedStyle(e),n=/(auto|scroll|overlay)/.test(t.overflowY),a=e.scrollHeight>e.clientHeight;if(n&&a){const t=e.scrollTop,n=e.scrollHeight-e.clientHeight;let s=c/3;s=s>0?Math.min(s,n-t):Math.max(s,-t),e.scrollTop=t+s;const a=e.scrollTop-t;if(Math.abs(a)>.5){r=!0,o=e,i=a;break}}if(e===document.body||e===document.documentElement)break;e=e.parentElement,s++}return r?`Scrolled container (${o?.tagName}) by ${i}px`:`No scrollable container found for element (${n.tagName})`}const r=t,o=e=>e&&/(auto|scroll|overlay)/.test(getComputedStyle(e).overflowY)&&e.scrollHeight>e.clientHeight&&(e=>e.clientHeight>=.5*window.innerHeight)(e);let i=document.activeElement;for(;i&&!o(i)&&i!==document.body;)i=i.parentElement;if(i=o(i)?i:Array.from(document.querySelectorAll("*")).find(o)||document.scrollingElement||document.documentElement,i===document.scrollingElement||i===document.documentElement||i===document.body){const e=window.scrollY;window.scrollBy(0,r);const t=window.scrollY,n=t-e;if(Math.abs(n)<1)return r>0?"Already at the bottom of the page.":"Already at the top of the page.";const o=document.documentElement.scrollHeight-window.innerHeight;return r>0&&t>=o-1?`Scrolled page by ${n}px. Reached the bottom.`:r<0&&t<=1?`Scrolled page by ${n}px. Reached the top.`:`Scrolled page by ${n}px.`}{const e=i.scrollTop,t=i.scrollHeight-i.clientHeight;i.scrollBy({top:r,behavior:"smooth"}),await waitFor(.1);const n=i.scrollTop,o=n-e;if(Math.abs(o)<1)return r>0?`Already at the bottom of container (${i.tagName}).`:`Already at the top of container (${i.tagName}).`;const s=r<0&&n<=1;return r>0&&n>=t-1?`Scrolled container (${i.tagName}) by ${o}px. Reached the bottom.`:s?`Scrolled container (${i.tagName}) by ${o}px. Reached the top.`:`Scrolled container (${i.tagName}) by ${o}px.`}}async function scrollHorizontally(e,t,n){if(n){let r=n,o=!1,i=null,s=0,c=0;const a=e?t:-t;for(;r&&c<10;){const e=window.getComputedStyle(r),t=/(auto|scroll|overlay)/.test(e.overflowX),n=r.scrollWidth>r.clientWidth;if(t&&n){const e=r.scrollLeft,t=r.scrollWidth-r.clientWidth;let n=a/3;n=n>0?Math.min(n,t-e):Math.max(n,-e),r.scrollLeft=e+n;const c=r.scrollLeft-e;if(Math.abs(c)>.5){o=!0,i=r,s=c;break}}if(r===document.body||r===document.documentElement)break;r=r.parentElement,c++}return o?`Scrolled container (${i?.tagName}) horizontally by ${s}px`:`No horizontally scrollable container found for element (${n.tagName})`}const r=e?t:-t,o=e=>e&&/(auto|scroll|overlay)/.test(getComputedStyle(e).overflowX)&&e.scrollWidth>e.clientWidth&&(e=>e.clientWidth>=.5*window.innerWidth)(e);let i=document.activeElement;for(;i&&!o(i)&&i!==document.body;)i=i.parentElement;if(i=o(i)?i:Array.from(document.querySelectorAll("*")).find(o)||document.scrollingElement||document.documentElement,i===document.scrollingElement||i===document.documentElement||i===document.body){const e=window.scrollX,t=document.documentElement.scrollWidth-window.innerWidth;window.scrollBy(r,0);const n=window.scrollX,o=n-e;if(Math.abs(o)<1)return r>0?"Already at the right edge of the page.":"Already at the left edge of the page.";return r>0&&n>=t-1?`Scrolled page by ${o}px. Reached the right edge.`:r<0&&n<=1?`Scrolled page by ${o}px. Reached the left edge.`:`Scrolled page horizontally by ${o}px.`}{const e=i.scrollLeft,t=i.scrollWidth-i.clientWidth;i.scrollBy({left:r,behavior:"smooth"}),await waitFor(.1);const n=i.scrollLeft,o=n-e;if(Math.abs(o)<1)return r>0?`Already at the right edge of container (${i.tagName}).`:`Already at the left edge of container (${i.tagName}).`;const s=r<0&&n<=1;return r>0&&n>=t-1?`Scrolled container (${i.tagName}) by ${o}px. Reached the right edge.`:s?`Scrolled container (${i.tagName}) by ${o}px. Reached the left edge.`:`Scrolled container (${i.tagName}) horizontally by ${o}px.`}}function getPageScrollInfo(){const e=window.innerWidth,t=window.innerHeight,n=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth||0),r=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight||0),o=window.scrollX||window.pageXOffset||document.documentElement.scrollLeft||0,i=window.scrollY||window.pageYOffset||document.documentElement.scrollTop||0,s=Math.max(0,r-(window.innerHeight+i)),c=Math.max(0,n-(window.innerWidth+o));return{viewport_width:e,viewport_height:t,page_width:n,page_height:r,scroll_x:o,scroll_y:i,pixels_above:i,pixels_below:s,pages_above:t>0?i/t:0,pages_below:t>0?s/t:0,total_pages:t>0?r/t:0,current_page_position:i/Math.max(1,r-t),pixels_left:o,pixels_right:c}}class PageController{constructor(e={}){this.flatTree=null,this.selectorMap=new Map,this.elementTextMap=new Map,this.simplifiedHTML="",this.isIndexed=!1,this.config=e}async getBrowserState(){const e=window.location.href,t=document.title,n=getPageScrollInfo(),r=resolveViewportExpansion(this.config.viewportExpansion);await this.updateTree();const o=this.simplifiedHTML;return{url:e,title:t,header:`${`Current Page: [${t}](${e})`}\n${`Page info: ${n.viewport_width}x${n.viewport_height}px viewport, ${n.page_width}x${n.page_height}px total, ${n.pages_above.toFixed(1)} pages above, ${n.pages_below.toFixed(1)} pages below, at ${(100*n.current_page_position).toFixed(0)}%`}\n\n${-1===r?"Interactive elements (full page):":"Interactive elements (viewport):"}\n\n${n.pixels_above>4&&-1!==r?`... ${n.pixels_above} pixels above - scroll to see more ...`:"[Start of page]"}`,content:o,footer:n.pixels_below>4&&-1!==r?`... ${n.pixels_below} pixels below - scroll to see more ...`:"[End of page]",element_count:this.selectorMap.size}}async updateTree(){return cleanUpHighlights(),this.flatTree=getFlatTree(this.config),this.simplifiedHTML=flatTreeToString(this.flatTree,this.config.includeAttributes),this.selectorMap.clear(),this.selectorMap=getSelectorMap(this.flatTree),this.elementTextMap.clear(),this.elementTextMap=getElementTextMap(this.simplifiedHTML),this.isIndexed=!0,this.simplifiedHTML}async cleanUpHighlights(){cleanUpHighlights()}assertIndexed(){if(!this.isIndexed)throw new Error("DOM tree not indexed yet. Call get_browser_state first.")}cleanUpAfterAction(){cleanUpHighlights()}async clickElement(e){try{this.assertIndexed();const t=getElementByIndex(this.selectorMap,e),n=this.elementTextMap.get(e);return this.cleanUpAfterAction(),await clickElement(t),t instanceof HTMLAnchorElement&&"_blank"===t.target?{success:!0,message:`Clicked element (${n??e}). Link opened in a new tab.`}:{success:!0,message:`Clicked element (${n??e}).`}}catch(e){return{success:!1,message:`Failed to click element: ${e}`}}}async inputText(e,t){try{this.assertIndexed();const n=getElementByIndex(this.selectorMap,e),r=this.elementTextMap.get(e);return this.cleanUpAfterAction(),await inputTextElement(n,t),{success:!0,message:`Input text "${t}" into element (${r??e}).`}}catch(e){return{success:!1,message:`Failed to input text: ${e}`}}}async selectOption(e,t){try{this.assertIndexed();const n=getElementByIndex(this.selectorMap,e),r=this.elementTextMap.get(e);return this.cleanUpAfterAction(),await selectOptionElement(n,t),{success:!0,message:`Selected option "${t}" in element (${r??e}).`}}catch(e){return{success:!1,message:`Failed to select option: ${e}`}}}async scroll(e){try{this.assertIndexed(),this.cleanUpAfterAction();const{direction:t,amount:n,index:r}=e,o=void 0!==r?getElementByIndex(this.selectorMap,r):null;let i;if("left"===t||"right"===t){const e=n??.8*window.innerWidth;i=await scrollHorizontally("right"===t,e,o)}else{const e=n??.8*window.innerHeight,r="down"===t?e:-e;i=await scrollVertically("down"===t,r,o)}return{success:!0,message:i}}catch(e){return{success:!1,message:`Failed to scroll: ${e}`}}}dispose(){cleanUpHighlights(),this.flatTree=null,this.selectorMap.clear(),this.elementTextMap.clear(),this.simplifiedHTML="",this.isIndexed=!1}}let controller=null;function getController(){return controller||(controller=new PageController({viewportExpansion:-1,highlightOpacity:.1,highlightLabelOpacity:.5})),controller}async function getBrowserState(e){const t=getController();return void 0!==e&&(t.config.viewportExpansion=e?0:-1),t.getBrowserState()}async function clickElementByIndex(e){return getController().clickElement(e)}async function inputText(e,t){return getController().inputText(e,t)}async function selectOption(e,t){return getController().selectOption(e,t)}async function scroll(e,t,n){return getController().scroll({direction:e,amount:t,index:n})}async function removeHighlights(){return getController().cleanUpHighlights(),{success:!0,message:"Highlights removed."}}function disposeController(){controller&&(controller.dispose(),controller=null)}function randomHex(e=8){const t=new Uint8Array(e);return crypto.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}getBrowserState.__schema__={name:"getBrowserState",description:"Get the current page state with all interactive elements indexed as [0], [1], [2], etc. Returns a simplified HTML representation optimized for LLM consumption. Interactive elements (buttons, links, inputs, scrollable areas) are detected via smart heuristics (CSS cursor, ARIA roles, event listeners, tag names). Use the returned indices with click_element_by_index, input_text, select_option, or scroll. Call this first to understand the page before performing any actions.",parameters:{type:"object",properties:{viewport_only:{type:"boolean",description:"If true, only return elements visible in the current viewport. Default: false (full page)."}}}},clickElementByIndex.__schema__={name:"clickElementByIndex",description:"Click an interactive element by its numeric index from get_browser_state output. Simulates a full mouse event sequence (hover, mousedown, focus, mouseup, click) to trigger all event listeners including React/Vue handlers.",parameters:{type:"object",properties:{index:{type:"number",description:"The element index from get_browser_state (e.g. 0 for [0], 5 for [5])."}},required:["index"]}},inputText.__schema__={name:"inputText",description:"Type text into an input, textarea, or contenteditable element by its index. Replaces existing content. Works with React controlled components, contenteditable editors (LinkedIn, Quill), and native inputs.",parameters:{type:"object",properties:{index:{type:"number",description:"The element index from get_browser_state."},text:{type:"string",description:"The text to type into the element."}},required:["index","text"]}},selectOption.__schema__={name:"selectOption",description:"Select a dropdown option in a <select> element by its index and the visible option text.",parameters:{type:"object",properties:{index:{type:"number",description:"The <select> element index from get_browser_state."},option_text:{type:"string",description:"The visible text of the option to select (case-sensitive, trimmed)."}},required:["index","option_text"]}},scroll.__schema__={name:"scroll",description:"Scroll the page or a specific scrollable container. If index is provided, scrolls the nearest scrollable ancestor of that element. Otherwise scrolls the page or the largest scrollable container.",parameters:{type:"object",properties:{direction:{type:"string",enum:["up","down","left","right"],description:"Scroll direction."},amount:{type:"number",description:"Scroll amount in pixels. Default: ~80% of viewport height (vertical) or width (horizontal)."},index:{type:"number",description:"Optional element index. If provided, scrolls the nearest scrollable ancestor of this element."}},required:["direction"]}},removeHighlights.__schema__={name:"removeHighlights",description:"Remove all visual element index labels/highlights from the page. Useful after taking a screenshot if you want a clean view.",parameters:{type:"object",properties:{}}};const STORAGE_KEY="__hypha_debugger_config__";class HyphaDebugger{constructor(e){this.overlay=null,this.cursor=null,this.server=null,this.serviceInfo=null,this.boundBeforeUnload=null,this.cleanupInterceptor=null;const t=e.require_token??!1;let n=e.service_id??"web-debugger";e.service_id||(n=`web-debugger-${randomHex(16)}`);const r=e.visibility??(t?"protected":"unlisted");this.config={server_url:e.server_url,workspace:e.workspace??"",token:e.token??"",service_id:n,service_name:e.service_name??"Web Debugger",show_ui:e.show_ui??!0,visibility:r,require_token:t}}async start(){installConsoleCapture();const e=window;if(e.__HYPHA_DEBUGGER__?.instance)return console.warn("[hypha-debugger] Already running, returning existing session."),e.__HYPHA_DEBUGGER__.session;this.config.show_ui&&(this.overlay=new DebugOverlay,this.overlay.setStatus("disconnected"),this.overlay.setInfo({Status:"Connecting..."}),this.cursor=new AICursor);try{const t=this.getConnectToServer(),n={server_url:this.config.server_url};this.config.workspace&&(n.workspace=this.config.workspace),this.config.token&&(n.token=this.config.token),this.server=await t(n),this.serviceInfo=await this.server.registerService(this.buildServiceDefinition());const r=await this.updateSession();return this.overlay&&this.overlay.addLog("Service registered","result"),e.__HYPHA_DEBUGGER__=e.__HYPHA_DEBUGGER__??{},e.__HYPHA_DEBUGGER__.instance=this,this.saveConfigToStorage(),this.boundBeforeUnload=()=>this.saveConfigToStorage(),window.addEventListener("beforeunload",this.boundBeforeUnload),this.cleanupInterceptor=installNavigationInterceptor(),r}catch(e){throw console.error("[hypha-debugger] Failed to start:",e),this.overlay&&(this.overlay.setStatus("error"),this.overlay.setInfo({Status:"Error",Error:e.message??String(e)})),e}}async destroy(){this.boundBeforeUnload&&(window.removeEventListener("beforeunload",this.boundBeforeUnload),this.boundBeforeUnload=null),this.cleanupInterceptor&&(this.cleanupInterceptor(),this.cleanupInterceptor=null);try{this.serviceInfo&&this.server&&await this.server.unregisterService(this.serviceInfo.id)}catch{}try{sessionStorage.removeItem(STORAGE_KEY)}catch{}disposeController(),this.cursor?.destroy(),this.cursor=null,this.overlay?.destroy(),this.overlay=null;const e=window;e.__HYPHA_DEBUGGER__&&(delete e.__HYPHA_DEBUGGER__.instance,delete e.__HYPHA_DEBUGGER__.session)}saveConfigToStorage(){try{const e={server_url:this.config.server_url,workspace:this.server?.config?.workspace??this.config.workspace,token:this.config.token,service_id:this.config.service_id,service_name:this.config.service_name,show_ui:this.config.show_ui,visibility:this.config.visibility,require_token:this.config.require_token,script_url:this.detectScriptUrl()};sessionStorage.setItem(STORAGE_KEY,JSON.stringify(e))}catch{}}detectScriptUrl(){try{const e=document.querySelectorAll("script[src]");for(const t of Array.from(e))if(t.src&&t.src.includes("hypha-debugger"))return t.src}catch{}return"https://cdn.jsdelivr.net/npm/hypha-debugger/dist/hypha-debugger.min.js"}async updateSession(e){const t=this.serviceInfo?.id??this.config.service_id,n=this.buildServiceUrl(t),r=this.server.config?.workspace??"",o=this.config.require_token?await this.server.generateToken({expires_in:86400}):"";this.overlay&&(this.overlay.setStatus("connected"),this.overlay.setInfo({Status:"Connected",Server:this.config.server_url,...e}),this.overlay.setInstructions(this.buildInstructionBlock(n,o))),console.log(`[hypha-debugger] Service URL: ${n}`),o?(console.log(`[hypha-debugger] Token: ${o}`),console.log(`[hypha-debugger] Test:\n curl '${n}/get_page_info' -H 'Authorization: Bearer ${o}'`)):console.log(`[hypha-debugger] Test:\n curl '${n}/get_page_info'`);const i={service_id:t,workspace:r,server:this.server,service_url:n,token:o,destroy:()=>this.destroy()},s=window;return s.__HYPHA_DEBUGGER__=s.__HYPHA_DEBUGGER__??{},s.__HYPHA_DEBUGGER__.session=i,i}buildServiceUrl(e){const t=this.config.server_url.replace(/\/+$/,""),n=e.indexOf("/");if(-1!==n){const r=e.substring(0,n),o=e.substring(n+1),i=o.indexOf(":");return`${t}/${r}/services/${-1!==i?o.substring(i+1):o}`}return`${t}/services/${e}`}getHyphaModule(){if(__webpack_exports__connectToServer)return hyphaRpc;if(__webpack_exports__connectToServer)return hyphaRpcWebsocket;const e=window;if(e.hyphaWebsocketClient?.connectToServer)return e.hyphaWebsocketClient;throw new Error('hypha-rpc not found. Install it via npm or load it via: <script src="https://cdn.jsdelivr.net/npm/hypha-rpc@0.20.97/dist/hypha-rpc-websocket.min.js"><\/script>')}getConnectToServer(){return this.getHyphaModule().connectToServer}buildServiceDefinition(){return{id:this.config.service_id,name:this.config.service_name,type:"debugger",description:"Remote web page debugger. Allows inspecting DOM, taking screenshots, executing JavaScript, and interacting with the page.",config:{visibility:this.config.visibility},get_page_info:this.wrapFn(getPageInfo,"get_page_info"),get_html:this.wrapFn(getHtml,"get_html"),query_dom:this.wrapFn(queryDom,"query_dom"),click_element:this.wrapFn(clickElement$1,"click_element"),fill_input:this.wrapFn(fillInput,"fill_input"),scroll_to:this.wrapFn(scrollTo,"scroll_to"),take_screenshot:this.wrapFn(takeScreenshot,"take_screenshot"),execute_script:this.wrapFn(executeScript,"execute_script"),navigate:this.wrapFn(navigate,"navigate"),get_react_tree:this.wrapFn(getReactTree,"get_react_tree"),get_browser_state:this.wrapFn(getBrowserState,"get_browser_state"),click_element_by_index:this.wrapFn(clickElementByIndex,"click_element_by_index"),input_text:this.wrapFn(inputText,"input_text"),select_option:this.wrapFn(selectOption,"select_option"),scroll:this.wrapFn(scroll,"scroll"),remove_highlights:this.wrapFn(removeHighlights,"remove_highlights"),get_skill_md:this.wrapFn(this.createGetSkillMd(),"get_skill_md")}}createGetSkillMd(){const e=()=>{const e={},t={get_page_info:getPageInfo,get_html:getHtml,query_dom:queryDom,click_element:clickElement$1,fill_input:fillInput,scroll_to:scrollTo,take_screenshot:takeScreenshot,execute_script:executeScript,navigate:navigate,get_react_tree:getReactTree,get_browser_state:getBrowserState,click_element_by_index:clickElementByIndex,input_text:inputText,select_option:selectOption,scroll:scroll,remove_highlights:removeHighlights};for(const[n,r]of Object.entries(t))r.__schema__&&(e[n]=r);return!this.serviceInfo||this.buildServiceUrl(this.serviceInfo.id??this.config.service_id),generateSkillMd(e)};return e.__schema__={name:"getSkillMd",description:"Get the SKILL.md document describing all available debugger functions, their parameters, and usage examples. Follows the agentskills.io specification.",parameters:{type:"object",properties:{}}},e}buildInstructionBlock(e,t){const n=t?' -H "Authorization: Bearer $TOKEN"':"",r=["# Hypha Remote Debugger — Web Page","# A debugger is attached to a live web page.","# You can remotely inspect, interact with, and control this page via the HTTP API below.","#","# RECOMMENDED WORKFLOW (index-based, most reliable):","# 1. get_browser_state → see all interactive elements as [0], [1], [2], ...","# 2. click_element_by_index / input_text / select_option / scroll → act by index","# 3. take_screenshot → verify the result visually","#","# Also available: get_page_info, get_html, query_dom, click_element, fill_input,","# scroll_to, execute_script, navigate, get_react_tree, remove_highlights","#","# POST endpoints accept JSON body with parameter names as keys.","",`SERVICE_URL="${e}"`];return t&&r.push(`TOKEN="${t}"`),r.push("","# 1. Get interactive elements (smart DOM analysis with indexed elements):",`curl "$SERVICE_URL/get_browser_state"${n}`,"","# 2. Click element by index (e.g. click [3]):",`curl -X POST "$SERVICE_URL/click_element_by_index"${n} -H "Content-Type: application/json" -d '{"index": 3}'`,"","# 3. Type into an input by index:",`curl -X POST "$SERVICE_URL/input_text"${n} -H "Content-Type: application/json" -d '{"index": 5, "text": "hello"}'`,"","# Take a screenshot:",`curl "$SERVICE_URL/take_screenshot"${n}`,"","# Execute JavaScript remotely:",`curl -X POST "$SERVICE_URL/execute_script"${n} -H "Content-Type: application/json" -d '{"code": "document.title"}'`,"","# Full API docs:",`curl "$SERVICE_URL/get_skill_md"${n}`),r.join("\n")}wrapFn(e,t){const n=this,r=async(...r)=>{n.overlay?.addLog(`${t}(${n.summarizeArgs(r)})`,"call");try{const o=await e(...r);return o&&"object"==typeof o&&"error"in o?n.overlay?.addLog(`${t}: ${o.error}`,"error"):n.overlay?.addLog(`${t} -> OK`,"result"),o}catch(e){throw n.overlay?.addLog(`${t}: ${e.message}`,"error"),e}};return e.__schema__&&(r.__schema__=e.__schema__),wrapFn(r)}summarizeArgs(e){return 0===e.length?"":e.map(e=>"string"==typeof e?e.length>40?e.slice(0,40)+"...":e:"object"==typeof e&&null!==e?"{...}":String(e)).join(", ")}}async function startDebugger(e){return new HyphaDebugger(e).start()}function autoStart(){if("undefined"==typeof window||"undefined"==typeof document)return;if(window.__HYPHA_DEBUGGER__?.instance)return;try{const e=sessionStorage.getItem("__hypha_debugger_config__");if(e){const t=JSON.parse(e);if(t.server_url)return console.log("[hypha-debugger] Reconnecting from saved session..."),void startDebugger(t).catch(e=>{console.error("[hypha-debugger] Auto-reconnect failed:",e)})}}catch{}const e=document.querySelectorAll("script[src]");let t=null;for(const n of Array.from(e))if(n.src&&n.src.includes("hypha-debugger")){t=n;break}if(t?.hasAttribute("data-manual"))return;const n={server_url:t?.getAttribute("data-server-url")??"https://hypha.aicell.io"};t?.getAttribute("data-workspace")&&(n.workspace=t.getAttribute("data-workspace")),t?.getAttribute("data-token")&&(n.token=t.getAttribute("data-token")),t?.getAttribute("data-service-id")&&(n.service_id=t.getAttribute("data-service-id")),t?.hasAttribute("data-no-ui")&&(n.show_ui=!1),t?.hasAttribute("data-require-token")&&(n.require_token=!0),startDebugger(n).catch(e=>{console.error("[hypha-debugger] Auto-start failed:",e)})}"undefined"!=typeof window&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",autoStart):autoStart()),exports.AICursor=AICursor,exports.HyphaDebugger=HyphaDebugger,exports.PageController=PageController,exports.clickElement=clickElement$1,exports.clickElementByIndex=clickElementByIndex,exports.disposeController=disposeController,exports.executeScript=executeScript,exports.fillInput=fillInput,exports.generateSkillMd=generateSkillMd,exports.getBrowserState=getBrowserState,exports.getComputedStyles=getComputedStyles,exports.getConsoleLogs=getConsoleLogs,exports.getElementBounds=getElementBounds,exports.getHtml=getHtml,exports.getPageInfo=getPageInfo,exports.getReactTree=getReactTree,exports.goBack=goBack,exports.goForward=goForward,exports.inputText=inputText,exports.installConsoleCapture=installConsoleCapture,exports.installNavigationInterceptor=installNavigationInterceptor,exports.navigate=navigate,exports.queryDom=queryDom,exports.reload=reload,exports.removeHighlights=removeHighlights,exports.scroll=scroll,exports.scrollTo=scrollTo,exports.selectOption=selectOption,exports.softReplace=softReplace,exports.startDebugger=startDebugger,exports.takeScreenshot=takeScreenshot,exports.wrapFn=wrapFn});
|
|
58
|
+
\*********************************/__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{API_VERSION:()=>_rpc_js__WEBPACK_IMPORTED_MODULE_0__.API_VERSION,HTTPStreamingRPCConnection:()=>_http_client_js__WEBPACK_IMPORTED_MODULE_4__.HTTPStreamingRPCConnection,LocalWebSocket:()=>LocalWebSocket,RPC:()=>_rpc_js__WEBPACK_IMPORTED_MODULE_0__.RPC,connectToServer:()=>connectToServer,connectToServerHTTP:()=>_http_client_js__WEBPACK_IMPORTED_MODULE_4__.connectToServerHTTP,getRTCService:()=>_webrtc_client_js__WEBPACK_IMPORTED_MODULE_3__.getRTCService,getRemoteService:()=>getRemoteService,getRemoteServiceHTTP:()=>_http_client_js__WEBPACK_IMPORTED_MODULE_4__.getRemoteServiceHTTP,hyphaWebsocketClient:()=>hyphaWebsocketClient,loadRequirements:()=>_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.loadRequirements,login:()=>login,logout:()=>logout,normalizeServerUrlHTTP:()=>_http_client_js__WEBPACK_IMPORTED_MODULE_4__.normalizeServerUrl,registerRTCService:()=>_webrtc_client_js__WEBPACK_IMPORTED_MODULE_3__.registerRTCService,schemaFunction:()=>_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction,setupLocalClient:()=>setupLocalClient});var _rpc_js__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*! ./rpc.js */"./src/rpc.js"),_utils_index_js__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(/*! ./utils/index.js */"./src/utils/index.js"),_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(/*! ./utils/schema.js */"./src/utils/schema.js"),_webrtc_client_js__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(/*! ./webrtc-client.js */"./src/webrtc-client.js"),_http_client_js__WEBPACK_IMPORTED_MODULE_4__=__webpack_require__(/*! ./http-client.js */"./src/http-client.js");const MAX_RETRY=1e6;class WebsocketRPCConnection{constructor(e,t,n,r,o=null,i=60,s=null,c=7200,a=null){(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(e&&t,"server_url and client_id are required"),this._server_url=e,this._client_id=t,this._workspace=n,this._token=r,this._reconnection_token=o,this._websocket=null,this._handle_message=null,this._handle_connected=null,this._handle_disconnected=null,this._timeout=i,this._WebSocketClass=s||WebSocket,this._closed=!1,this._legacy_auth=null,this.connection_info=null,this._enable_reconnect=!1,this._token_refresh_interval=c,this.manager_id=null,this._refresh_token_task=null,this._reconnect_timeouts=new Set,this._additional_headers=a,this._reconnecting=!1,this._disconnectedNotified=!1}_cleanup(){this._refresh_token_delay&&(clearTimeout(this._refresh_token_delay),this._refresh_token_delay=null),this._refresh_token_task&&(clearInterval(this._refresh_token_task),this._refresh_token_task=null);for(const e of this._reconnect_timeouts)clearTimeout(e);this._reconnect_timeouts.clear()}on_message(e){(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(e,"handler is required"),this._handle_message=e}on_connected(e){this._handle_connected=e}on_disconnected(e){this._handle_disconnected=e}async _attempt_connection(e,t=!0){return new Promise((n,r)=>{this._legacy_auth=!1;const o=new this._WebSocketClass(e);o.binaryType="arraybuffer",o.onopen=()=>{console.info("WebSocket connection established"),n(o)},o.onerror=e=>{console.error("WebSocket connection error:",e),r(new Error(`WebSocket connection error: ${e}`))},o.onclose=o=>{1003===o.code&&t?(console.info("Received 1003 error, attempting connection with query parameters."),this._legacy_auth=!0,this._attempt_connection_with_query_params(e).then(n).catch(r)):this._notifyDisconnected(o.reason)}})}async _attempt_connection_with_query_params(e){const t=[];this._client_id&&t.push(`client_id=${encodeURIComponent(this._client_id)}`),this._workspace&&t.push(`workspace=${encodeURIComponent(this._workspace)}`),this._token&&t.push(`token=${encodeURIComponent(this._token)}`),this._reconnection_token&&t.push(`reconnection_token=${encodeURIComponent(this._reconnection_token)}`);const n=e+(t.length>0?`?${t.join("&")}`:"");return await this._attempt_connection(n,!1)}_establish_connection(){return new Promise((e,t)=>{this._websocket.onmessage=n=>{const r=n.data,o=JSON.parse(r);if("connection_info"!=o.type){if("error"==o.type){const e="ConnectionAbortedError: "+o.message;return console.error("Failed to connect, "+e),void t(new Error(e))}return console.error("ConnectionAbortedError: Unexpected message received from the server:",r),void t(new Error("ConnectionAbortedError: Unexpected message received from the server"))}this.connection_info=o,this._workspace&&(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(this.connection_info.workspace===this._workspace,`Connected to the wrong workspace: ${this.connection_info.workspace}, expected: ${this._workspace}`),this.connection_info.reconnection_token&&(this._reconnection_token=this.connection_info.reconnection_token),this.connection_info.reconnection_token_life_time&&this._token_refresh_interval>this.connection_info.reconnection_token_life_time/1.5&&(console.warn(`Token refresh interval is too long (${this._token_refresh_interval}), setting it to 1.5 times of the token life time(${this.connection_info.reconnection_token_life_time}).`),this._token_refresh_interval=this.connection_info.reconnection_token_life_time/1.5),this.manager_id=this.connection_info.manager_id||null,console.log(`Successfully connected to the server, workspace: ${this.connection_info.workspace}, manager_id: ${this.manager_id}`),this.connection_info.announcement&&console.log(`${this.connection_info.announcement}`),e(this.connection_info)}})}async open(){console.log("Creating a new websocket connection to",this._server_url.split("?")[0]);try{if(this._websocket=await this._attempt_connection(this._server_url),this._legacy_auth)throw new Error("NotImplementedError: Legacy authentication is not supported");const e=JSON.stringify({client_id:this._client_id,workspace:this._workspace,token:this._token,reconnection_token:this._reconnection_token});return this._websocket.send(e),await(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.waitFor)(this._establish_connection(),this._timeout,"Failed to receive the first message from the server"),this._token_refresh_interval>0&&(this._refresh_token_delay=setTimeout(()=>{this._refresh_token_delay=null,this._closed||(this._send_refresh_token(),this._refresh_token_task=setInterval(()=>{this._send_refresh_token()},1e3*this._token_refresh_interval))},2e3)),this._enable_reconnect=!0,this._closed=!1,this._disconnectedNotified=!1,this._websocket.onmessage=e=>{if("string"==typeof e.data){const t=JSON.parse(e.data);"reconnection_token"===t.type?this._reconnection_token=t.reconnection_token:console.log("Received message from the server:",t)}else this._handle_message(e.data)},this._websocket.onerror=e=>{console.error("WebSocket connection error:",e),this._cleanup()},this._websocket.onclose=this._handle_close.bind(this),this._handle_connected&&this._handle_connected(this.connection_info),this.connection_info}catch(e){throw this._cleanup(),console.error("Failed to connect to",this._server_url.split("?")[0],e),e}}_send_refresh_token(){if(this._websocket&&this._websocket.readyState===WebSocket.OPEN){const e=JSON.stringify({type:"refresh_token"});this._websocket.send(e)}}_notifyDisconnected(e){this._disconnectedNotified||(this._disconnectedNotified=!0,this._handle_disconnected&&this._handle_disconnected(e))}_handle_close(e){if(!this._closed&&this._websocket&&this._websocket.readyState===WebSocket.CLOSED){if(this._cleanup(),this._disconnectedNotified=!1,this._enable_reconnect){if([1e3,1001].includes(e.code)?console.warn(`Websocket connection closed gracefully by server (code: ${e.code}): ${e.reason} - attempting reconnect`):console.warn("Websocket connection closed unexpectedly (code: %s): %s",e.code,e.reason),this._notifyDisconnected(e.reason),this._reconnecting)return void console.debug("Reconnection already in progress, skipping");this._reconnecting=!0;let t=0;const n=1e3,r=6e4,o=.1,i=async()=>{if(this._closed)return console.info("Connection was closed, stopping reconnection"),void(this._reconnecting=!1);try{console.warn(`Reconnecting to ${this._server_url.split("?")[0]} (attempt #${t})`),await this.open(),await new Promise(e=>setTimeout(e,500)),console.warn(`Successfully reconnected to server ${this._server_url} (services re-registered)`),this._reconnecting=!1}catch(e){if(`${e}`.includes("ConnectionAbortedError:"))return console.warn("Server refused to reconnect:",e),this._closed=!0,this._reconnecting=!1,void this._notifyDisconnected(`Server refused reconnection: ${e}`);if(`${e}`.includes("NotImplementedError:"))return console.error(`${e}\nIt appears that you are trying to connect to a hypha server that is older than 0.20.0, please upgrade the hypha server or use the websocket client in imjoy-rpc(https://www.npmjs.com/package/imjoy-rpc) instead`),this._closed=!0,this._reconnecting=!1,void this._notifyDisconnected(`Server too old: ${e}`);"NetworkError"===e.name||e.message.includes("network")?console.error(`Network error during reconnection: ${e.message}`):"TimeoutError"===e.name||e.message.includes("timeout")?console.error(`Connection timeout during reconnection: ${e.message}`):console.error(`Unexpected error during reconnection: ${e.message}`);const s=Math.min(n*Math.pow(2,t),r),c=(2*Math.random()-1)*o*s,a=Math.max(100,s+c);console.debug(`Waiting ${(a/1e3).toFixed(2)}s before next reconnection attempt`);const l=setTimeout(async()=>(this._reconnect_timeouts.delete(l),this._websocket&&this._websocket.readyState===WebSocket.OPEN?(console.info("Connection restored externally"),void(this._reconnecting=!1)):this._closed?(console.info("Connection was closed, stopping reconnection"),void(this._reconnecting=!1)):(t+=1,void(t<MAX_RETRY?await i():(console.error(`Failed to reconnect after ${MAX_RETRY} attempts, giving up.`),this._closed=!0,this._reconnecting=!1,this._notifyDisconnected("Max reconnection attempts exceeded"))))),a);this._reconnect_timeouts.add(l)}};i()}}else this._cleanup(),this._notifyDisconnected(e.reason)}async emit_message(e){if(this._closed)throw new Error("Connection is closed");this._websocket&&this._websocket.readyState===WebSocket.OPEN||await this.open();try{this._websocket.send(e)}catch(e){throw console.error(`Failed to send data, error: ${e}`),e}}disconnect(e){this._closed=!0,this._reconnecting=!1,this._websocket&&this._websocket.readyState!==WebSocket.CLOSED&&this._websocket.readyState!==WebSocket.CLOSING&&this._websocket.close(1e3,e),this._cleanup(),console.info(`WebSocket connection disconnected (${e})`)}}function normalizeServerUrl(e){if(!e)throw new Error("server_url is required");return e.startsWith("http://")?e=e.replace("http://","ws://").replace(/\/$/,"")+"/ws":e.startsWith("https://")&&(e=e.replace("https://","wss://").replace(/\/$/,"")+"/ws"),e}async function login(e){const t=e.login_service_id||"public/hypha-login",n=e.workspace,r=e.expires_in,o=e.login_timeout||60,i=e.login_callback,s=e.profile,c=e.additional_headers,a=e.transport||"websocket",l=await connectToServer({name:"initial login client",server_url:e.server_url,additional_headers:c,transport:a});try{const e=await l.getService(t);let c;return(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(e,`Failed to get the login service: ${t}`),c=n?await e.start({workspace:n,expires_in:r,_rkwargs:!0}):await e.start(),i?await i(c):console.log(`Please open your browser and login at ${c.login_url}`),await e.check(c.key,{timeout:o,profile:s,_rkwargs:!0})}catch(e){throw e}finally{await l.disconnect()}}async function logout(e){const t=e.login_service_id||"public/hypha-login",n=e.logout_callback,r=e.additional_headers,o=e.transport||"websocket",i=await connectToServer({name:"initial logout client",server_url:e.server_url,additional_headers:r,transport:o});try{const e=await i.getService(t);if((0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(e,`Failed to get the login service: ${t}`),!e.logout)throw new Error("Logout is not supported by this server. Please upgrade the Hypha server to a version that supports logout.");const r=await e.logout({});return n?await n(r):console.log(`Please open your browser to logout at ${r.logout_url}`),r}catch(e){throw e}finally{await i.disconnect()}}async function webrtcGetService(e,t,n){const r=void 0!==(n=n||{}).webrtc?n.webrtc:"auto",o=n.webrtc_config;void 0!==n.webrtc&&delete n.webrtc,void 0!==n.webrtc_config&&delete n.webrtc_config,(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)([void 0,!0,!1,"auto"].includes(r),"webrtc must be true, false or 'auto'");const i=await e.getService(t,n);if(!0===r||"auto"===r){if(i.id.includes(":")&&i.id.includes("/"))try{const t=i.id.split(":")[0].split("/"),r=t[t.length-1],s=`${t.slice(0,-1).join("/")}/${r}-rtc`,c=await(0,_webrtc_client_js__WEBPACK_IMPORTED_MODULE_3__.getRTCService)(e,s,o),a=await c.getService(i.id.split(":")[1],n);return a._webrtc=!0,a._peer=c,a._service=i,a}catch(e){console.warn("Failed to get webrtc service, using websocket connection",e)}if(!0===r)throw new Error("Failed to get the service via webrtc")}return i}async function connectToServer(e){if("http"===(e.transport||"websocket"))return await(0,_http_client_js__WEBPACK_IMPORTED_MODULE_4__.connectToServerHTTP)(e);e.server&&(e.server_url=e.server_url||e.server.url,e.WebSocketClass=e.WebSocketClass||e.server.WebSocketClass);let t=e.client_id;t||(t=(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.randId)(),e.client_id=t),0===Object.keys(e).length&&("undefined"!=typeof process&&process.env?(e.server_url=process.env.HYPHA_SERVER_URL,e.token=process.env.HYPHA_TOKEN,e.client_id=process.env.HYPHA_CLIENT_ID,e.workspace=process.env.HYPHA_WORKSPACE):"undefined"!=typeof self&&self.env?(e.server_url=self.env.HYPHA_SERVER_URL,e.token=self.env.HYPHA_TOKEN,e.client_id=self.env.HYPHA_CLIENT_ID,e.workspace=self.env.HYPHA_WORKSPACE):"undefined"!=typeof globalThis&&globalThis.env&&(e.server_url=globalThis.env.HYPHA_SERVER_URL,e.token=globalThis.env.HYPHA_TOKEN,e.client_id=globalThis.env.HYPHA_CLIENT_ID,e.workspace=globalThis.env.HYPHA_WORKSPACE));let n=normalizeServerUrl(e.server_url),r=new WebsocketRPCConnection(n,t,e.workspace,e.token,e.reconnection_token,e.method_timeout||60,e.WebSocketClass,e.token_refresh_interval,e.additional_headers);const o=await r.open();if((0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(o,"Failed to connect to the server, no connection info obtained. This issue is most likely due to an outdated Hypha server version. Please use `imjoy-rpc` for compatibility, or upgrade the Hypha server to the latest version."),await new Promise(e=>setTimeout(e,100)),!r.manager_id){console.warn("Manager ID not set immediately, waiting...");const e=5e3,t=100,n=Date.now();for(;!r.manager_id&&Date.now()-n<e;)await new Promise(e=>setTimeout(e,t));if(!r.manager_id)throw console.error("Manager ID still not set after waiting"),new Error("Failed to get manager ID from server");console.info(`Manager ID set after waiting: ${r.manager_id}`)}if(e.workspace&&o.workspace!==e.workspace)throw new Error(`Connected to the wrong workspace: ${o.workspace}, expected: ${e.workspace}`);const i=o.workspace,s=new _rpc_js__WEBPACK_IMPORTED_MODULE_0__.RPC(r,{client_id:t,workspace:i,default_context:{connection_type:"websocket"},name:e.name,method_timeout:e.method_timeout,app_id:e.app_id,server_base_url:o.public_base_url,long_message_chunk_size:e.long_message_chunk_size});await s.waitFor("services_registered",e.method_timeout||120);const c=await s.get_manager_service({timeout:e.method_timeout,case_conversion:"camel",kwargs_expansion:e.kwargs_expansion||!1});if(c.rpc=s,o&&(c.config=Object.assign(c.config,o)),c.export=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(async function(t){t.id="default",t.name=t.name||e.name||t.id,t.description=t.description||e.description,await s.register_service(t,{overwrite:!0})},{name:"export",description:"Export the api.",parameters:{properties:{api:{description:"The api to export",type:"object"}},required:["api"],type:"object"}}),c.getApp=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(async function(e){return e=e||"*",(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(!e.includes(":"),"clientId should not contain ':'"),e.includes("/")||(e=o.workspace+"/"+e),(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(2===e.split("/").length,"clientId should match pattern workspace/clientId"),await c.getService(`${e}:default`)},{name:"getApp",description:"Get the app.",parameters:{properties:{clientId:{default:"*",description:"The clientId",type:"string"}},type:"object"}}),c.listApps=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(async function(e){e=e||i,(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(!e.includes(":"),"workspace should not contain ':'"),(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.assert)(!e.includes("/"),"workspace should not contain '/'");const t={workspace:e,service_id:"default"};return await c.listServices(t)},{name:"listApps",description:"List the apps.",parameters:{properties:{workspace:{default:i,description:"The workspace",type:"string"}},type:"object"}}),c.disconnect=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.disconnect.bind(s),{name:"disconnect",description:"Disconnect from the server.",parameters:{type:"object",properties:{},required:[]}}),c.registerCodec=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.register_codec.bind(s),{name:"registerCodec",description:"Register a codec for the webrtc connection",parameters:{type:"object",properties:{codec:{type:"object",description:"Codec to register",properties:{name:{type:"string"},type:{},encoder:{type:"function"},decoder:{type:"function"}}}}}}),c.emit=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.emit.bind(s),{name:"emit",description:"Emit a message.",parameters:{properties:{data:{description:"The data to emit",type:"object"}},required:["data"],type:"object"}}),c.on=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.on.bind(s),{name:"on",description:"Register a message handler.",parameters:{properties:{event:{description:"The event to listen to",type:"string"},handler:{description:"The handler function",type:"function"}},required:["event","handler"],type:"object"}}),c.off=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.off.bind(s),{name:"off",description:"Remove a message handler.",parameters:{properties:{event:{description:"The event to remove",type:"string"},handler:{description:"The handler function",type:"function"}},required:["event","handler"],type:"object"}}),c.once=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.once.bind(s),{name:"once",description:"Register a one-time message handler.",parameters:{properties:{event:{description:"The event to listen to",type:"string"},handler:{description:"The handler function",type:"function"}},required:["event","handler"],type:"object"}}),c.getServiceSchema=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.get_service_schema,{name:"getServiceSchema",description:"Get the service schema.",parameters:{properties:{service:{description:"The service to extract schema",type:"object"}},required:["service"],type:"object"}}),c.registerService=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.register_service.bind(s),{name:"registerService",description:"Register a service.",parameters:{properties:{service:{description:"The service to register",type:"object"},force:{default:!1,description:"Force to register the service",type:"boolean"}},required:["service"],type:"object"}}),c.unregisterService=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(s.unregister_service.bind(s),{name:"unregisterService",description:"Unregister a service.",parameters:{properties:{service:{description:"The service id to unregister",type:"string"},notify:{default:!0,description:"Notify the workspace manager",type:"boolean"}},required:["service"],type:"object"}}),r.manager_id&&s.on("force-exit",async e=>{e.from==="*/"+r.manager_id&&(console.log("Disconnecting from server, reason:",e.reason),await s.disconnect())}),e.webrtc){await(0,_webrtc_client_js__WEBPACK_IMPORTED_MODULE_3__.registerRTCService)(c,`${t}-rtc`,e.webrtc_config);const n=Object.assign({},c),r=n.getService.__schema__.description,o=n.getService.__schema__.parameters;c.getService=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(webrtcGetService.bind(null,n),{name:"getService",description:r,parameters:o}),c.getRTCService=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(_webrtc_client_js__WEBPACK_IMPORTED_MODULE_3__.getRTCService.bind(null,c),{name:"getRTCService",description:"Get the webrtc connection, returns a peer connection.",parameters:{properties:{config:{description:"The config for the webrtc service",type:"object"}},required:["config"],type:"object"}})}else{const e=c.getService;c.getService=(t,n)=>e(t,n=n||{}),c.getService.__schema__=e.__schema__}return c.registerProbes=(0,_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction)(async function(e){return e.id="probes",e.name="Probes",e.config={visibility:"public"},e.type="probes",e.description=`Probes Service, visit ${n}/${i}services/probes for the available probes.`,await c.registerService(e,{overwrite:!0})},{name:"registerProbes",description:"Register probes service",parameters:{properties:{probes:{description:"The probes to register, e.g. {'liveness': {'type': 'function', 'description': 'Check the liveness of the service'}}",type:"object"}},required:["probes"],type:"object"}}),c}async function getRemoteService(e,t={}){const{serverUrl:n,workspace:r,clientId:o,serviceId:i,appId:s}=(0,_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.parseServiceUrl)(e),c=`${r}/${o}:${i}@${s}`;if(t.serverUrl&&t.serverUrl!==n)throw new Error("server_url in config does not match the server_url in the url");t.serverUrl=n;const a=await connectToServer(t);return await a.getService(c)}class LocalWebSocket{constructor(e,t,n){this.url=e,this.onopen=()=>{},this.onmessage=()=>{},this.onclose=()=>{},this.onerror=()=>{},this.client_id=t,this.workspace=n;const r="undefined"!=typeof window?window:self,o="undefined"!=typeof window;if(this.postMessage=e=>{o?window.parent.postMessage(e,"*"):self.postMessage(e)},this.readyState=WebSocket.CONNECTING,this._context=r,this._messageListener=e=>{const{type:t,data:n,to:r}=e.data;if(r===this.client_id)switch(t){case"message":this.readyState===WebSocket.OPEN&&this.onmessage&&this.onmessage({data:n});break;case"connected":this.readyState=WebSocket.OPEN,this.onopen(e);break;case"closed":this.readyState=WebSocket.CLOSED,this.onclose(e)}},r.addEventListener("message",this._messageListener,!1),!this.client_id)throw new Error("client_id is required");if(!this.workspace)throw new Error("workspace is required");this.postMessage({type:"connect",url:this.url,from:this.client_id,workspace:this.workspace})}send(e){this.readyState===WebSocket.OPEN&&this.postMessage({type:"message",data:e,from:this.client_id,workspace:this.workspace})}close(){this.readyState=WebSocket.CLOSING,this.postMessage({type:"close",from:this.client_id,workspace:this.workspace}),this._context&&this._messageListener&&(this._context.removeEventListener("message",this._messageListener,!1),this._messageListener=null),this.onclose()}addEventListener(e,t){"message"===e&&(this.onmessage=t),"open"===e&&(this.onopen=t),"close"===e&&(this.onclose=t),"error"===e&&(this.onerror=t)}}const hyphaWebsocketClient={RPC:_rpc_js__WEBPACK_IMPORTED_MODULE_0__.RPC,API_VERSION:_rpc_js__WEBPACK_IMPORTED_MODULE_0__.API_VERSION,schemaFunction:_utils_schema_js__WEBPACK_IMPORTED_MODULE_2__.schemaFunction,loadRequirements:_utils_index_js__WEBPACK_IMPORTED_MODULE_1__.loadRequirements,login:login,logout:logout,connectToServer:connectToServer,connectToServerHTTP:_http_client_js__WEBPACK_IMPORTED_MODULE_4__.connectToServerHTTP,getRemoteService:getRemoteService,getRemoteServiceHTTP:_http_client_js__WEBPACK_IMPORTED_MODULE_4__.getRemoteServiceHTTP,getRTCService:_webrtc_client_js__WEBPACK_IMPORTED_MODULE_3__.getRTCService,registerRTCService:_webrtc_client_js__WEBPACK_IMPORTED_MODULE_3__.registerRTCService,get setupLocalClient(){return setupLocalClient},get LocalWebSocket(){return LocalWebSocket},HTTPStreamingRPCConnection:_http_client_js__WEBPACK_IMPORTED_MODULE_4__.HTTPStreamingRPCConnection,normalizeServerUrlHTTP:_http_client_js__WEBPACK_IMPORTED_MODULE_4__.normalizeServerUrl};function setupLocalClient({enable_execution:enable_execution=!1,on_ready:on_ready=null}){return new Promise((resolve,reject)=>{const context="undefined"!=typeof window?window:self,isWindow="undefined"!=typeof window;context.addEventListener("message",event=>{const{type:type,server_url:server_url,workspace:workspace,client_id:client_id,token:token,method_timeout:method_timeout,name:name,config:config}=event.data;if("initializeHyphaClient"===type){if(!server_url||!workspace||!client_id)return void console.error("server_url, workspace, and client_id are required.");if(!server_url.startsWith("https://local-hypha-server:"))return void console.error("server_url should start with https://local-hypha-server:");class FixedLocalWebSocket extends LocalWebSocket{constructor(e){super(e,client_id,workspace)}}connectToServer({server_url:server_url,workspace:workspace,client_id:client_id,token:token,method_timeout:method_timeout,name:name,WebSocketClass:FixedLocalWebSocket}).then(async server=>{globalThis.api=server;try{if(isWindow&&enable_execution){function e(e){return new Promise((t,n)=>{const r=document.createElement("script");r.innerHTML=e.content,r.lang=e.lang,r.onload=()=>t(),r.onerror=e=>n(e),document.head.appendChild(r)})}if(config.styles&&config.styles.length>0)for(const t of config.styles){const n=document.createElement("style");n.innerHTML=t.content,n.lang=t.lang,document.head.appendChild(n)}if(config.links&&config.links.length>0)for(const r of config.links){const o=document.createElement("a");o.href=r.url,o.innerText=r.text,document.body.appendChild(o)}if(config.windows&&config.windows.length>0)for(const i of config.windows){document.body.innerHTML=i.content;break}if(config.scripts&&config.scripts.length>0)for(const s of config.scripts){if("javascript"!==s.lang)throw new Error("Only javascript scripts are supported");await e(s)}}else if(!isWindow&&enable_execution&&config.scripts&&config.scripts.length>0)for(const script of config.scripts){if("javascript"!==script.lang)throw new Error("Only javascript scripts are supported");eval(script.content)}on_ready&&await on_ready(server,config),resolve(server)}catch(c){reject(c)}})}},!1),isWindow?window.parent.postMessage({type:"hyphaClientReady"},"*"):self.postMessage({type:"hyphaClientReady"})})}var __webpack_exports__API_VERSION=__webpack_exports__.API_VERSION,__webpack_exports__HTTPStreamingRPCConnection=__webpack_exports__.HTTPStreamingRPCConnection,__webpack_exports__LocalWebSocket=__webpack_exports__.LocalWebSocket,__webpack_exports__RPC=__webpack_exports__.RPC,__webpack_exports__connectToServer=__webpack_exports__.connectToServer,__webpack_exports__connectToServerHTTP=__webpack_exports__.connectToServerHTTP,__webpack_exports__getRTCService=__webpack_exports__.getRTCService,__webpack_exports__getRemoteService=__webpack_exports__.getRemoteService,__webpack_exports__getRemoteServiceHTTP=__webpack_exports__.getRemoteServiceHTTP,__webpack_exports__hyphaWebsocketClient=__webpack_exports__.hyphaWebsocketClient,__webpack_exports__loadRequirements=__webpack_exports__.loadRequirements,__webpack_exports__login=__webpack_exports__.login,__webpack_exports__logout=__webpack_exports__.logout,__webpack_exports__normalizeServerUrlHTTP=__webpack_exports__.normalizeServerUrlHTTP,__webpack_exports__registerRTCService=__webpack_exports__.registerRTCService,__webpack_exports__schemaFunction=__webpack_exports__.schemaFunction,__webpack_exports__setupLocalClient=__webpack_exports__.setupLocalClient,hyphaRpcWebsocket=Object.freeze({__proto__:null,API_VERSION:__webpack_exports__API_VERSION,HTTPStreamingRPCConnection:__webpack_exports__HTTPStreamingRPCConnection,LocalWebSocket:__webpack_exports__LocalWebSocket,RPC:__webpack_exports__RPC,connectToServer:__webpack_exports__connectToServer,connectToServerHTTP:__webpack_exports__connectToServerHTTP,getRTCService:__webpack_exports__getRTCService,getRemoteService:__webpack_exports__getRemoteService,getRemoteServiceHTTP:__webpack_exports__getRemoteServiceHTTP,hyphaWebsocketClient:__webpack_exports__hyphaWebsocketClient,loadRequirements:__webpack_exports__loadRequirements,login:__webpack_exports__login,logout:__webpack_exports__logout,normalizeServerUrlHTTP:__webpack_exports__normalizeServerUrlHTTP,registerRTCService:__webpack_exports__registerRTCService,schemaFunction:__webpack_exports__schemaFunction,setupLocalClient:__webpack_exports__setupLocalClient}),hyphaRpc=Object.freeze({__proto__:null,API_VERSION:__webpack_exports__API_VERSION,HTTPStreamingRPCConnection:__webpack_exports__HTTPStreamingRPCConnection,LocalWebSocket:__webpack_exports__LocalWebSocket,RPC:__webpack_exports__RPC,connectToServer:__webpack_exports__connectToServer,connectToServerHTTP:__webpack_exports__connectToServerHTTP,getRTCService:__webpack_exports__getRTCService,getRemoteService:__webpack_exports__getRemoteService,getRemoteServiceHTTP:__webpack_exports__getRemoteServiceHTTP,hyphaWebsocketClient:hyphaRpcWebsocket,loadRequirements:__webpack_exports__loadRequirements,login:__webpack_exports__login,logout:__webpack_exports__logout,normalizeServerUrlHTTP:__webpack_exports__normalizeServerUrlHTTP,registerRTCService:__webpack_exports__registerRTCService,schemaFunction:__webpack_exports__schemaFunction,setupLocalClient:__webpack_exports__setupLocalClient});const overlayStyles="\n :host {\n all: initial;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n }\n\n * {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n\n .debugger-icon {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: #4a90d9;\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\n transition: transform 0.15s, background 0.15s;\n user-select: none;\n font-size: 18px;\n line-height: 1;\n }\n\n .debugger-icon:hover {\n transform: scale(1.1);\n background: #357abd;\n }\n\n .debugger-icon.connected {\n background: #27ae60;\n }\n\n .debugger-icon.error {\n background: #e74c3c;\n }\n\n .debugger-panel {\n display: none;\n width: 380px;\n max-height: 520px;\n background: #1e1e2e;\n color: #cdd6f4;\n border-radius: 8px;\n border: 1px solid #45475a;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);\n overflow: hidden;\n flex-direction: column;\n position: absolute;\n bottom: 50px;\n right: 0;\n font-size: 13px;\n }\n\n .debugger-panel.open {\n display: flex;\n }\n\n .panel-header {\n background: #313244;\n padding: 8px 12px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: default;\n border-bottom: 1px solid #45475a;\n font-weight: 600;\n font-size: 12px;\n letter-spacing: 0.3px;\n text-transform: uppercase;\n color: #a6adc8;\n }\n\n .panel-header .title {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .panel-header .close-btn {\n cursor: pointer;\n color: #6c7086;\n font-size: 16px;\n line-height: 1;\n padding: 2px 4px;\n border-radius: 3px;\n }\n\n .panel-header .close-btn:hover {\n color: #cdd6f4;\n background: #45475a;\n }\n\n .status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n display: inline-block;\n background: #6c7086;\n }\n\n .status-dot.connected {\n background: #a6e3a1;\n }\n\n .status-dot.error {\n background: #f38ba8;\n }\n\n .panel-body {\n padding: 10px 12px;\n overflow-y: auto;\n flex: 1;\n max-height: 440px;\n }\n\n .info-row {\n display: flex;\n justify-content: space-between;\n padding: 4px 0;\n border-bottom: 1px solid #313244;\n font-size: 12px;\n }\n\n .info-row .label {\n color: #6c7086;\n }\n\n .info-row .value {\n color: #cdd6f4;\n text-align: right;\n word-break: break-all;\n max-width: 180px;\n font-family: 'SF Mono', Monaco, Consolas, monospace;\n font-size: 11px;\n }\n\n .instructions-section {\n margin-top: 8px;\n padding-top: 6px;\n border-top: 1px solid #313244;\n }\n\n .instructions-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 4px;\n }\n\n .url-label {\n font-size: 11px;\n color: #6c7086;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 3px;\n }\n\n .instructions-block {\n font-family: 'SF Mono', Monaco, Consolas, monospace;\n font-size: 10px;\n color: #a6e3a1;\n background: #11111b;\n border: 1px solid #313244;\n border-radius: 4px;\n padding: 8px;\n white-space: pre-wrap;\n word-break: break-all;\n max-height: 200px;\n overflow-y: auto;\n line-height: 1.5;\n }\n\n .copy-btn {\n background: #45475a;\n color: #cdd6f4;\n border: none;\n border-radius: 3px;\n padding: 2px 8px;\n font-size: 10px;\n cursor: pointer;\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n .copy-btn:hover {\n background: #585b70;\n }\n\n .log-section {\n margin-top: 8px;\n }\n\n .log-title {\n font-size: 11px;\n color: #6c7086;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 4px;\n }\n\n .log-entry {\n font-family: 'SF Mono', Monaco, Consolas, monospace;\n font-size: 11px;\n padding: 3px 6px;\n border-radius: 3px;\n background: #313244;\n margin-bottom: 2px;\n color: #a6adc8;\n word-break: break-all;\n }\n\n .log-entry.call {\n border-left: 2px solid #89b4fa;\n }\n\n .log-entry.result {\n border-left: 2px solid #a6e3a1;\n }\n\n .log-entry.error {\n border-left: 2px solid #f38ba8;\n color: #f38ba8;\n }\n";class DebugOverlay{constructor(e){this.isOpen=!1,this.isDragging=!1,this.dragOffset={x:0,y:0},this.maxLogEntries=50,this.host=document.createElement("div"),this.host.id="hypha-debugger-host",Object.assign(this.host.style,{position:"fixed",bottom:"20px",right:"20px",zIndex:"2147483647",display:"flex",flexDirection:"column",alignItems:"flex-end"}),e?.position&&(this.host.style.bottom="auto",this.host.style.right="auto",this.host.style.left=e.position.x+"px",this.host.style.top=e.position.y+"px"),this.shadow=this.host.attachShadow({mode:"open"});const t=document.createElement("style");t.textContent=overlayStyles,this.shadow.appendChild(t);const n=document.createElement("div");n.style.position="relative",n.style.display="flex",n.style.flexDirection="column",n.style.alignItems="flex-end",this.panel=document.createElement("div"),this.panel.className="debugger-panel";const r=document.createElement("div");r.className="panel-header";const o=document.createElement("span");o.className="title",this.statusDot=document.createElement("span"),this.statusDot.className="status-dot",o.appendChild(this.statusDot),o.appendChild(document.createTextNode(" Hypha Debugger"));const i=document.createElement("span");i.className="close-btn",i.textContent="×",i.addEventListener("click",()=>this.toggle()),r.appendChild(o),r.appendChild(i);const s=document.createElement("div");s.className="panel-body",this.infoBody=document.createElement("div"),s.appendChild(this.infoBody);const c=document.createElement("div");c.className="log-section";const a=document.createElement("div");a.className="log-title",a.textContent="Remote Operations",this.logContainer=document.createElement("div"),c.appendChild(a),c.appendChild(this.logContainer),s.appendChild(c),this.panel.appendChild(r),this.panel.appendChild(s),this.icon=document.createElement("div"),this.icon.className="debugger-icon",this.icon.textContent="🐛",this.icon.addEventListener("click",e=>{this.isDragging||this.toggle()}),n.appendChild(this.panel),n.appendChild(this.icon),this.shadow.appendChild(n),document.documentElement.appendChild(this.host),this.setupDrag()}setupDrag(){let e=0,t=0,n=!1;this.icon.addEventListener("mousedown",r=>{e=r.clientX,t=r.clientY,n=!1;const o=this.host.getBoundingClientRect();this.dragOffset.x=r.clientX-o.left,this.dragOffset.y=r.clientY-o.top,r.preventDefault()}),document.addEventListener("mousemove",r=>{if(0===e&&0===t)return;const o=Math.abs(r.clientX-e),i=Math.abs(r.clientY-t);(o>3||i>3)&&(n=!0,this.isDragging=!0,this.host.style.left=r.clientX-this.dragOffset.x+"px",this.host.style.top=r.clientY-this.dragOffset.y+"px",this.host.style.right="auto",this.host.style.bottom="auto")}),document.addEventListener("mouseup",()=>{e=0,t=0,n&&setTimeout(()=>{this.isDragging=!1},50)})}toggle(){this.isOpen=!this.isOpen,this.panel.classList.toggle("open",this.isOpen)}setStatus(e){this.statusDot.className="status-dot",this.icon.className="debugger-icon","connected"===e?(this.statusDot.classList.add("connected"),this.icon.classList.add("connected")):"error"===e&&(this.statusDot.classList.add("error"),this.icon.classList.add("error"))}setInfo(e){this.infoBody.querySelectorAll(".info-row").forEach(e=>e.remove());const t=this.infoBody.firstChild;for(const[n,r]of Object.entries(e)){const e=document.createElement("div");e.className="info-row";const o=document.createElement("span");o.className="label",o.textContent=n;const i=document.createElement("span");i.className="value",i.textContent=r,i.title=r,e.appendChild(o),e.appendChild(i),this.infoBody.insertBefore(e,t)}}setInstructions(e){const t=this.infoBody.querySelector(".instructions-section");t&&t.remove();const n=document.createElement("div");n.className="instructions-section";const r=document.createElement("div");r.className="instructions-header";const o=document.createElement("span");o.className="url-label",o.textContent="Instructions";const i=document.createElement("button");i.className="copy-btn",i.textContent="Copy All",i.addEventListener("click",()=>{navigator.clipboard.writeText(e).then(()=>{i.textContent="Copied!",setTimeout(()=>{i.textContent="Copy All"},1500)})}),r.appendChild(o),r.appendChild(i),n.appendChild(r);const s=document.createElement("pre");s.className="instructions-block",s.textContent=e,n.appendChild(s),this.infoBody.appendChild(n)}addLog(e,t="call"){const n=document.createElement("div");for(n.className=`log-entry ${t}`,n.textContent=e,this.logContainer.appendChild(n);this.logContainer.children.length>this.maxLogEntries;)this.logContainer.removeChild(this.logContainer.firstChild);const r=this.panel.querySelector(".panel-body");r&&(r.scrollTop=r.scrollHeight)}destroy(){this.host.remove()}}const CURSOR_BORDER_SVG='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" fill="none"><g><path d="M 15 42 L 15 36.99 Q 15 31.99 23.7 31.99 L 28.05 31.99 Q 32.41 31.99 32.41 21.99 L 32.41 17 Q 32.41 12 41.09 16.95 L 76.31 37.05 Q 85 42 76.31 46.95 L 41.09 67.05 Q 32.41 72 32.41 62.01 L 32.41 57.01 Q 32.41 52.01 23.7 52.01 L 19.35 52.01 Q 15 52.01 15 47.01 Z" fill="none" stroke="currentColor" stroke-width="6" stroke-miterlimit="10"/></g></svg>',CURSOR_FILL_SVG='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><g style="filter: drop-shadow(rgba(0, 0, 0, 0.3) 3px 4px 4px);"><path d="M 15 42 L 15 36.99 Q 15 31.99 23.7 31.99 L 28.05 31.99 Q 32.41 31.99 32.41 21.99 L 32.41 17 Q 32.41 12 41.09 16.95 L 76.31 37.05 Q 85 42 76.31 46.95 L 41.09 67.05 Q 32.41 72 32.41 62.01 L 32.41 57.01 Q 32.41 52.01 23.7 52.01 L 19.35 52.01 Q 15 52.01 15 47.01 Z" fill="#ffffff" stroke="none"/></g></svg>',CURSOR_CSS="\n .hypha-cursor {\n position: fixed;\n width: 50px;\n height: 50px;\n pointer-events: none;\n z-index: 2147483646;\n transition: opacity 0.2s;\n opacity: 0;\n }\n .hypha-cursor.visible {\n opacity: 1;\n }\n .hypha-cursor-border {\n position: absolute;\n width: 100%;\n height: 100%;\n background: linear-gradient(45deg, rgb(57, 182, 255), rgb(189, 69, 251));\n mask-image: var(--cursor-border);\n -webkit-mask-image: var(--cursor-border);\n mask-size: 100% 100%;\n -webkit-mask-size: 100% 100%;\n mask-repeat: no-repeat;\n -webkit-mask-repeat: no-repeat;\n transform-origin: center;\n transform: rotate(-135deg) scale(1.2);\n margin-left: -10px;\n margin-top: -14px;\n }\n .hypha-cursor-fill {\n position: absolute;\n width: 100%;\n height: 100%;\n background-image: var(--cursor-fill);\n background-size: 100% 100%;\n background-repeat: no-repeat;\n transform-origin: center;\n transform: rotate(-135deg) scale(1.2);\n margin-left: -10px;\n margin-top: -14px;\n }\n .hypha-cursor-ripple {\n position: absolute;\n width: 100%;\n height: 100%;\n pointer-events: none;\n margin-left: -50%;\n margin-top: -50%;\n }\n .hypha-cursor-ripple::after {\n content: '';\n opacity: 0;\n position: absolute;\n inset: 0;\n border: 3px solid rgba(57, 182, 255, 1);\n border-radius: 50%;\n }\n .hypha-cursor.clicking .hypha-cursor-ripple::after {\n animation: hypha-cursor-ripple 400ms ease-out forwards;\n }\n @keyframes hypha-cursor-ripple {\n 0% { transform: scale(0); opacity: 1; }\n 100% { transform: scale(2.5); opacity: 0; }\n }\n";class AICursor{constructor(){this.currentX=0,this.currentY=0,this.targetX=0,this.targetY=0,this.animating=!1,this.visible=!1,this.hideTimeout=null,this.container=document.createElement("div"),this.container.id="hypha-debugger-cursor",this.container.setAttribute("data-browser-use-ignore","true"),this.container.setAttribute("data-page-agent-ignore","true");const e=document.createElement("style");e.textContent=CURSOR_CSS,this.container.appendChild(e),this.cursor=document.createElement("div"),this.cursor.className="hypha-cursor";const t='url("data:image/svg+xml,'+encodeURIComponent(CURSOR_BORDER_SVG)+'")',n='url("data:image/svg+xml,'+encodeURIComponent(CURSOR_FILL_SVG)+'")';this.cursor.style.setProperty("--cursor-border",t),this.cursor.style.setProperty("--cursor-fill",n);const r=document.createElement("div");r.className="hypha-cursor-ripple",this.cursor.appendChild(r);const o=document.createElement("div");o.className="hypha-cursor-fill",this.cursor.appendChild(o);const i=document.createElement("div");i.className="hypha-cursor-border",this.cursor.appendChild(i),this.container.appendChild(this.cursor),document.body.appendChild(this.container),window.addEventListener("HyphaDebugger::MovePointerTo",e=>{const{x:t,y:n}=e.detail;this.moveTo(t,n)}),window.addEventListener("HyphaDebugger::ClickPointer",()=>{this.triggerClickAnimation()})}moveTo(e,t){this.targetX=e,this.targetY=t,this.visible||(this.visible=!0,this.currentX=e,this.currentY=t,this.cursor.style.left=`${e}px`,this.cursor.style.top=`${t}px`,this.cursor.classList.add("visible")),this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=null),this.animating||(this.animating=!0,this.animateLoop())}animateLoop(){const e=this.targetX-this.currentX,t=this.targetY-this.currentY;Math.abs(e)>1||Math.abs(t)>1?(this.currentX+=.18*e,this.currentY+=.18*t,this.cursor.style.left=`${this.currentX}px`,this.cursor.style.top=`${this.currentY}px`,requestAnimationFrame(()=>this.animateLoop())):(this.currentX=this.targetX,this.currentY=this.targetY,this.cursor.style.left=`${this.currentX}px`,this.cursor.style.top=`${this.currentY}px`,this.animating=!1,this.hideTimeout=setTimeout(()=>{this.visible=!1,this.cursor.classList.remove("visible")},2e3))}triggerClickAnimation(){this.cursor.classList.remove("clicking"),this.cursor.offsetHeight,this.cursor.classList.add("clicking")}destroy(){this.hideTimeout&&clearTimeout(this.hideTimeout),this.container.remove()}}function detectFrameworks(){const e=[],t=window;if(t.__REACT_DEVTOOLS_GLOBAL_HOOK__?.renderers?.size>0)e.push("react");else{const t=document.querySelector("#root, #app, [data-reactroot]");if(t){Object.keys(t).some(e=>e.startsWith("__reactFiber$")||e.startsWith("__reactInternalInstance$"))&&e.push("react")}}if(t.__VUE__||t.__VUE_DEVTOOLS_GLOBAL_HOOK__)e.push("vue");else{const t=document.querySelector("[data-v-app], #app");t&&t.__vue_app__&&e.push("vue")}return(t.ng||document.querySelector("[ng-version]"))&&e.push("angular"),document.querySelector("[class*='svelte-']")&&e.push("svelte"),t.__NEXT_DATA__&&e.push("nextjs"),e}function collectPageInfo(){const e=performance.getEntriesByType("navigation")[0];return{url:window.location.href,title:document.title,viewport:{width:window.innerWidth,height:window.innerHeight},document_size:{width:document.documentElement.scrollWidth,height:document.documentElement.scrollHeight},user_agent:navigator.userAgent,timestamp:(new Date).toISOString(),cookies_enabled:navigator.cookieEnabled,language:navigator.language,platform:navigator.platform,online:navigator.onLine,performance:{load_time_ms:e?Math.round(e.loadEventEnd-e.startTime):null,dom_content_loaded_ms:e?Math.round(e.domContentLoadedEventEnd-e.startTime):null},frameworks:detectFrameworks()}}function getPageInfo(e,t,n){const r=collectPageInfo();if(e){const e=window.__HYPHA_DEBUGGER__?.consoleLogs??[],o=t??50;let i=n?e.filter(e=>e.level===n):e;r.console_logs=i.slice(-o)}return r}function getConsoleLogs(e){const t=window.__HYPHA_DEBUGGER__?.consoleLogs??[],n=e?.level,r=e?.limit??100;return(n?t.filter(e=>e.level===n):t).slice(-r)}function installConsoleCapture(e=500){var t;const n=(t=window).__HYPHA_DEBUGGER__??(t.__HYPHA_DEBUGGER__={});if(n.consoleInstalled)return;n.consoleLogs=[],n.consoleInstalled=!0;const r=["log","warn","error","info"];for(const t of r){const r=console[t].bind(console);console[t]=(...o)=>{const i=n.consoleLogs;i.push({level:t,message:o.map(e=>{try{return"string"==typeof e?e:JSON.stringify(e)}catch{return String(e)}}).join(" "),timestamp:(new Date).toISOString()}),i.length>e&&i.splice(0,i.length-e),r(...o)}}}function elementToInfo(e){const t=e.getBoundingClientRect(),n={};for(const t of Array.from(e.attributes))n[t.name]=t.value;return{tag:e.tagName.toLowerCase(),id:e.id,classes:Array.from(e.classList),text:(e.textContent??"").trim().slice(0,500),attributes:n,bounds:{x:Math.round(t.x),y:Math.round(t.y),width:Math.round(t.width),height:Math.round(t.height)},visible:t.width>0&&t.height>0&&"hidden"!==getComputedStyle(e).visibility&&"none"!==getComputedStyle(e).display,children_count:e.children.length}}function queryDom(e,t){t=t??20;const n=document.querySelectorAll(e),r=[];for(let e=0;e<Math.min(n.length,t);e++)r.push(elementToInfo(n[e]));return r}function clickElement$1(e){const t=document.querySelector(e);if(!t)return{success:!1,message:`No element found for selector: ${e}`};const n=t.getBoundingClientRect();return t.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0,view:window,clientX:n.left+n.width/2,clientY:n.top+n.height/2})),{success:!0,message:`Clicked element: ${e}`}}function fillInput(e,t){const n=document.querySelector(e);if(!n)return{success:!1,message:`No element found for selector: ${e}`};const r=n.tagName.toLowerCase();if("input"===r||"textarea"===r){const o=n,i="textarea"===r?HTMLTextAreaElement.prototype:HTMLInputElement.prototype,s=Object.getOwnPropertyDescriptor(i,"value")?.set;return s?s.call(o,t):o.value=t,o.dispatchEvent(new Event("input",{bubbles:!0})),o.dispatchEvent(new Event("change",{bubbles:!0})),{success:!0,message:`Filled ${e} with value`}}if("select"===r){const r=n,o=Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype,"value")?.set;return o?o.call(r,t):r.value=t,r.dispatchEvent(new Event("change",{bubbles:!0})),{success:!0,message:`Set ${e} to ${t}`}}return{success:!1,message:`Element ${e} is not an input/textarea/select`}}function scrollTo(e){if("string"==typeof e){const t=document.querySelector(e);return t?(t.scrollIntoView({behavior:"smooth",block:"center"}),{success:!0,message:`Scrolled to ${e}`}):{success:!1,message:`No element found for selector: ${e}`}}return window.scrollTo({left:e.x,top:e.y,behavior:"smooth"}),{success:!0,message:`Scrolled to (${e.x}, ${e.y})`}}function getComputedStyles(e,t){const n=document.querySelector(e);if(!n)return{error:`No element found for selector: ${e}`};const r=getComputedStyle(n),o={},i=t??["display","position","width","height","color","background-color","font-size","font-family","margin","padding","border","opacity","visibility","overflow","z-index"];for(const e of i)o[e]=r.getPropertyValue(e);return o}function getElementBounds(e){const t=document.querySelector(e);if(!t)return{error:`No element found for selector: ${e}`};const n=t.getBoundingClientRect();return{bounds:{x:Math.round(n.x),y:Math.round(n.y),width:Math.round(n.width),height:Math.round(n.height)},visible:n.width>0&&n.height>0&&"hidden"!==getComputedStyle(t).visibility&&"none"!==getComputedStyle(t).display}}function getHtml(e,t,n){const r=t??!0,o=n??5e4,i=e?document.querySelector(e):document.documentElement;if(!i)return{error:`No element found for selector: ${e}`};const s=r?i.outerHTML:i.innerHTML,c=s.length>o;return{html:c?s.slice(0,o):s,length:s.length,truncated:c}}function resolveUrl(e,t){if(e.match(/^[a-z]+:\/\//i))return e;if(e.match(/^\/\//))return window.location.protocol+e;if(e.match(/^[a-z]+:/i))return e;const n=document.implementation.createHTMLDocument(),r=n.createElement("base"),o=n.createElement("a");return n.head.appendChild(r),n.body.appendChild(o),t&&(r.href=t),o.href=e,o.href}getPageInfo.__schema__={name:"getPageInfo",description:"Get information about the current web page including URL, title, viewport size, detected frameworks, and performance timing. Optionally include recent console logs.",parameters:{type:"object",properties:{include_logs:{type:"boolean",description:"If true, include recent console output in the response. Default: false."},log_limit:{type:"number",description:"Maximum number of console log entries to include (most recent). Default: 50."},log_level:{type:"string",description:'Filter console logs by level: "log", "warn", "error", "info". Omit for all levels.',enum:["log","warn","error","info"]}}}},getConsoleLogs.__schema__={name:"getConsoleLogs",description:"Retrieve captured console output (log, warn, error, info).",parameters:{type:"object",properties:{level:{type:"string",description:'Filter by log level: "log", "warn", "error", "info". Omit for all levels.',enum:["log","warn","error","info"]},limit:{type:"number",description:"Maximum number of log entries to return (most recent). Default: 100."}}}},queryDom.__schema__={name:"queryDom",description:"Query DOM elements by CSS selector. Returns tag, id, classes, text content, attributes, bounding rect, and visibility for each matching element.",parameters:{type:"object",properties:{selector:{type:"string",description:'CSS selector to query, e.g. "button.primary", "#app > div".'},limit:{type:"number",description:"Maximum number of elements to return. Default: 20."}},required:["selector"]}},clickElement$1.__schema__={name:"clickElement",description:"Click a DOM element matching the CSS selector.",parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the element to click."}},required:["selector"]}},fillInput.__schema__={name:"fillInput",description:"Set the value of an input, textarea, or select element. Works with React controlled components.",parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the input element."},value:{type:"string",description:"The value to set."}},required:["selector","value"]}},scrollTo.__schema__={name:"scrollTo",description:"Scroll to a DOM element (by CSS selector) or to an absolute position {x, y}.",parameters:{type:"object",properties:{target:{description:"CSS selector string to scroll to an element, or an object {x, y} for absolute scroll position."}},required:["target"]}},getComputedStyles.__schema__={name:"getComputedStyles",description:"Get computed CSS styles for an element.",parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the element."},properties:{type:"array",items:{type:"string"},description:'CSS property names to retrieve, e.g. ["color", "font-size"]. Omit for common defaults.'}},required:["selector"]}},getElementBounds.__schema__={name:"getElementBounds",description:"Get the bounding rectangle and visibility of a DOM element.",parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the element."}},required:["selector"]}},getHtml.__schema__={name:"getHtml",description:"Get the HTML content of the page or a specific element. Returns outerHTML by default. Useful for understanding page structure.",parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the element. Omit to get the full page HTML."},outer:{type:"boolean",description:"If true (default), return outerHTML (includes the element itself). If false, return innerHTML (children only)."},max_length:{type:"number",description:"Maximum character length of the returned HTML. Default: 50000. Result will be truncated if longer."}}}};const uuid=(()=>{let e=0;return()=>(e+=1,`u${`0000${(Math.random()*36**4|0).toString(36)}`.slice(-4)}${e}`)})();function toArray(e){const t=[];for(let n=0,r=e.length;n<r;n++)t.push(e[n]);return t}let styleProps=null;function getStyleProperties(e={}){return styleProps||(e.includeStyleProperties?(styleProps=e.includeStyleProperties,styleProps):(styleProps=toArray(window.getComputedStyle(document.documentElement)),styleProps))}function px(e,t){const n=(e.ownerDocument.defaultView||window).getComputedStyle(e).getPropertyValue(t);return n?parseFloat(n.replace("px","")):0}function getNodeWidth(e){const t=px(e,"border-left-width"),n=px(e,"border-right-width");return e.clientWidth+t+n}function getNodeHeight(e){const t=px(e,"border-top-width"),n=px(e,"border-bottom-width");return e.clientHeight+t+n}function getImageSize(e,t={}){return{width:t.width||getNodeWidth(e),height:t.height||getNodeHeight(e)}}function getPixelRatio(){let e,t;try{t=process}catch(e){}const n=t&&t.env?t.env.devicePixelRatio:null;return n&&(e=parseInt(n,10),Number.isNaN(e)&&(e=1)),e||window.devicePixelRatio||1}const canvasDimensionLimit=16384;function checkCanvasDimensions(e){(e.width>canvasDimensionLimit||e.height>canvasDimensionLimit)&&(e.width>canvasDimensionLimit&&e.height>canvasDimensionLimit?e.width>e.height?(e.height*=canvasDimensionLimit/e.width,e.width=canvasDimensionLimit):(e.width*=canvasDimensionLimit/e.height,e.height=canvasDimensionLimit):e.width>canvasDimensionLimit?(e.height*=canvasDimensionLimit/e.width,e.width=canvasDimensionLimit):(e.width*=canvasDimensionLimit/e.height,e.height=canvasDimensionLimit))}function createImage(e){return new Promise((t,n)=>{const r=new Image;r.onload=()=>{r.decode().then(()=>{requestAnimationFrame(()=>t(r))})},r.onerror=n,r.crossOrigin="anonymous",r.decoding="async",r.src=e})}async function svgToDataURL(e){return Promise.resolve().then(()=>(new XMLSerializer).serializeToString(e)).then(encodeURIComponent).then(e=>`data:image/svg+xml;charset=utf-8,${e}`)}async function nodeToDataURL(e,t,n){const r="http://www.w3.org/2000/svg",o=document.createElementNS(r,"svg"),i=document.createElementNS(r,"foreignObject");return o.setAttribute("width",`${t}`),o.setAttribute("height",`${n}`),o.setAttribute("viewBox",`0 0 ${t} ${n}`),i.setAttribute("width","100%"),i.setAttribute("height","100%"),i.setAttribute("x","0"),i.setAttribute("y","0"),i.setAttribute("externalResourcesRequired","true"),o.appendChild(i),i.appendChild(e),svgToDataURL(o)}const isInstanceOfElement=(e,t)=>{if(e instanceof t)return!0;const n=Object.getPrototypeOf(e);return null!==n&&(n.constructor.name===t.name||isInstanceOfElement(n,t))};function formatCSSText(e){const t=e.getPropertyValue("content");return`${e.cssText} content: '${t.replace(/'|"/g,"")}';`}function formatCSSProperties(e,t){return getStyleProperties(t).map(t=>`${t}: ${e.getPropertyValue(t)}${e.getPropertyPriority(t)?" !important":""};`).join(" ")}function getPseudoElementStyle(e,t,n,r){const o=`.${e}:${t}`,i=n.cssText?formatCSSText(n):formatCSSProperties(n,r);return document.createTextNode(`${o}{${i}}`)}function clonePseudoElement(e,t,n,r){const o=window.getComputedStyle(e,n),i=o.getPropertyValue("content");if(""===i||"none"===i)return;const s=uuid();try{t.className=`${t.className} ${s}`}catch(e){return}const c=document.createElement("style");c.appendChild(getPseudoElementStyle(s,n,o,r)),t.appendChild(c)}function clonePseudoElements(e,t,n){clonePseudoElement(e,t,":before",n),clonePseudoElement(e,t,":after",n)}const WOFF="application/font-woff",JPEG="image/jpeg",mimes={woff:WOFF,woff2:WOFF,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:JPEG,jpeg:JPEG,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml",webp:"image/webp"};function getExtension(e){const t=/\.([^./]*?)$/g.exec(e);return t?t[1]:""}function getMimeType(e){const t=getExtension(e).toLowerCase();return mimes[t]||""}function getContentFromDataUrl(e){return e.split(/,/)[1]}function isDataUrl(e){return-1!==e.search(/^(data:)/)}function makeDataUrl(e,t){return`data:${t};base64,${e}`}async function fetchAsDataURL(e,t,n){const r=await fetch(e,t);if(404===r.status)throw new Error(`Resource "${r.url}" not found`);const o=await r.blob();return new Promise((e,t)=>{const i=new FileReader;i.onerror=t,i.onloadend=()=>{try{e(n({res:r,result:i.result}))}catch(e){t(e)}},i.readAsDataURL(o)})}const cache={};function getCacheKey(e,t,n){let r=e.replace(/\?.*/,"");return n&&(r=e),/ttf|otf|eot|woff2?/i.test(r)&&(r=r.replace(/.*\//,"")),t?`[${t}]${r}`:r}async function resourceToDataURL(e,t,n){const r=getCacheKey(e,t,n.includeQueryParams);if(null!=cache[r])return cache[r];let o;n.cacheBust&&(e+=(/\?/.test(e)?"&":"?")+(new Date).getTime());try{o=makeDataUrl(await fetchAsDataURL(e,n.fetchRequestInit,({res:e,result:n})=>(t||(t=e.headers.get("Content-Type")||""),getContentFromDataUrl(n))),t)}catch(t){o=n.imagePlaceholder||"";let r=`Failed to fetch resource: ${e}`;t&&(r="string"==typeof t?t:t.message),r&&console.warn(r)}return cache[r]=o,o}async function cloneCanvasElement(e){const t=e.toDataURL();return"data:,"===t?e.cloneNode(!1):createImage(t)}async function cloneVideoElement(e,t){if(e.currentSrc){const t=document.createElement("canvas"),n=t.getContext("2d");t.width=e.clientWidth,t.height=e.clientHeight,null==n||n.drawImage(e,0,0,t.width,t.height);return createImage(t.toDataURL())}const n=e.poster,r=getMimeType(n);return createImage(await resourceToDataURL(n,r,t))}async function cloneIFrameElement(e,t){var n;try{if(null===(n=null==e?void 0:e.contentDocument)||void 0===n?void 0:n.body)return await cloneNode(e.contentDocument.body,t,!0)}catch(e){}return e.cloneNode(!1)}async function cloneSingleNode(e,t){return isInstanceOfElement(e,HTMLCanvasElement)?cloneCanvasElement(e):isInstanceOfElement(e,HTMLVideoElement)?cloneVideoElement(e,t):isInstanceOfElement(e,HTMLIFrameElement)?cloneIFrameElement(e,t):e.cloneNode(isSVGElement(e))}const isSlotElement=e=>null!=e.tagName&&"SLOT"===e.tagName.toUpperCase(),isSVGElement=e=>null!=e.tagName&&"SVG"===e.tagName.toUpperCase();async function cloneChildren(e,t,n){var r,o;if(isSVGElement(t))return t;let i=[];return i=isSlotElement(e)&&e.assignedNodes?toArray(e.assignedNodes()):isInstanceOfElement(e,HTMLIFrameElement)&&(null===(r=e.contentDocument)||void 0===r?void 0:r.body)?toArray(e.contentDocument.body.childNodes):toArray((null!==(o=e.shadowRoot)&&void 0!==o?o:e).childNodes),0===i.length||isInstanceOfElement(e,HTMLVideoElement)||await i.reduce((e,r)=>e.then(()=>cloneNode(r,n)).then(e=>{e&&t.appendChild(e)}),Promise.resolve()),t}function cloneCSSStyle(e,t,n){const r=t.style;if(!r)return;const o=window.getComputedStyle(e);o.cssText?(r.cssText=o.cssText,r.transformOrigin=o.transformOrigin):getStyleProperties(n).forEach(n=>{let i=o.getPropertyValue(n);if("font-size"===n&&i.endsWith("px")){const e=Math.floor(parseFloat(i.substring(0,i.length-2)))-.1;i=`${e}px`}isInstanceOfElement(e,HTMLIFrameElement)&&"display"===n&&"inline"===i&&(i="block"),"d"===n&&t.getAttribute("d")&&(i=`path(${t.getAttribute("d")})`),r.setProperty(n,i,o.getPropertyPriority(n))})}function cloneInputValue(e,t){isInstanceOfElement(e,HTMLTextAreaElement)&&(t.innerHTML=e.value),isInstanceOfElement(e,HTMLInputElement)&&t.setAttribute("value",e.value)}function cloneSelectValue(e,t){if(isInstanceOfElement(e,HTMLSelectElement)){const n=t,r=Array.from(n.children).find(t=>e.value===t.getAttribute("value"));r&&r.setAttribute("selected","")}}function decorate(e,t,n){return isInstanceOfElement(t,Element)&&(cloneCSSStyle(e,t,n),clonePseudoElements(e,t,n),cloneInputValue(e,t),cloneSelectValue(e,t)),t}async function ensureSVGSymbols(e,t){const n=e.querySelectorAll?e.querySelectorAll("use"):[];if(0===n.length)return e;const r={};for(let o=0;o<n.length;o++){const i=n[o].getAttribute("xlink:href");if(i){const n=e.querySelector(i),o=document.querySelector(i);n||!o||r[i]||(r[i]=await cloneNode(o,t,!0))}}const o=Object.values(r);if(o.length){const t="http://www.w3.org/1999/xhtml",n=document.createElementNS(t,"svg");n.setAttribute("xmlns",t),n.style.position="absolute",n.style.width="0",n.style.height="0",n.style.overflow="hidden",n.style.display="none";const r=document.createElementNS(t,"defs");n.appendChild(r);for(let e=0;e<o.length;e++)r.appendChild(o[e]);e.appendChild(n)}return e}async function cloneNode(e,t,n){return n||!t.filter||t.filter(e)?Promise.resolve(e).then(e=>cloneSingleNode(e,t)).then(n=>cloneChildren(e,n,t)).then(n=>decorate(e,n,t)).then(e=>ensureSVGSymbols(e,t)):null}const URL_REGEX=/url\((['"]?)([^'"]+?)\1\)/g,URL_WITH_FORMAT_REGEX=/url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g,FONT_SRC_REGEX=/src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;function toRegex(e){const t=e.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1");return new RegExp(`(url\\(['"]?)(${t})(['"]?\\))`,"g")}function parseURLs(e){const t=[];return e.replace(URL_REGEX,(e,n,r)=>(t.push(r),e)),t.filter(e=>!isDataUrl(e))}async function embed(e,t,n,r,o){try{const i=n?resolveUrl(t,n):t,s=getMimeType(t);let c;return o||(c=await resourceToDataURL(i,s,r)),e.replace(toRegex(t),`$1${c}$3`)}catch(e){}return e}function filterPreferredFontFormat(e,{preferredFontFormat:t}){return t?e.replace(FONT_SRC_REGEX,e=>{for(;;){const[n,,r]=URL_WITH_FORMAT_REGEX.exec(e)||[];if(!r)return"";if(r===t)return`src: ${n};`}}):e}function shouldEmbed(e){return-1!==e.search(URL_REGEX)}async function embedResources(e,t,n){if(!shouldEmbed(e))return e;const r=filterPreferredFontFormat(e,n);return parseURLs(r).reduce((e,r)=>e.then(e=>embed(e,r,t,n)),Promise.resolve(r))}async function embedProp(e,t,n){var r;const o=null===(r=t.style)||void 0===r?void 0:r.getPropertyValue(e);if(o){const r=await embedResources(o,null,n);return t.style.setProperty(e,r,t.style.getPropertyPriority(e)),!0}return!1}async function embedBackground(e,t){await embedProp("background",e,t)||await embedProp("background-image",e,t),await embedProp("mask",e,t)||await embedProp("-webkit-mask",e,t)||await embedProp("mask-image",e,t)||await embedProp("-webkit-mask-image",e,t)}async function embedImageNode(e,t){const n=isInstanceOfElement(e,HTMLImageElement);if((!n||isDataUrl(e.src))&&(!isInstanceOfElement(e,SVGImageElement)||isDataUrl(e.href.baseVal)))return;const r=n?e.src:e.href.baseVal,o=await resourceToDataURL(r,getMimeType(r),t);await new Promise((r,i)=>{e.onload=r,e.onerror=t.onImageErrorHandler?(...e)=>{try{r(t.onImageErrorHandler(...e))}catch(e){i(e)}}:i;const s=e;s.decode&&(s.decode=r),"lazy"===s.loading&&(s.loading="eager"),n?(e.srcset="",e.src=o):e.href.baseVal=o})}async function embedChildren(e,t){const n=toArray(e.childNodes).map(e=>embedImages(e,t));await Promise.all(n).then(()=>e)}async function embedImages(e,t){isInstanceOfElement(e,Element)&&(await embedBackground(e,t),await embedImageNode(e,t),await embedChildren(e,t))}function applyStyle(e,t){const{style:n}=e;t.backgroundColor&&(n.backgroundColor=t.backgroundColor),t.width&&(n.width=`${t.width}px`),t.height&&(n.height=`${t.height}px`);const r=t.style;return null!=r&&Object.keys(r).forEach(e=>{n[e]=r[e]}),e}const cssFetchCache={};async function fetchCSS(e){let t=cssFetchCache[e];if(null!=t)return t;const n=await fetch(e);return t={url:e,cssText:await n.text()},cssFetchCache[e]=t,t}async function embedFonts(e,t){let n=e.cssText;const r=/url\(["']?([^"')]+)["']?\)/g,o=(n.match(/url\([^)]+\)/g)||[]).map(async o=>{let i=o.replace(r,"$1");return i.startsWith("https://")||(i=new URL(i,e.url).href),fetchAsDataURL(i,t.fetchRequestInit,({result:e})=>(n=n.replace(o,`url(${e})`),[o,e]))});return Promise.all(o).then(()=>n)}function parseCSS(e){if(null==e)return[];const t=[];let n=e.replace(/(\/\*[\s\S]*?\*\/)/gi,"");const r=new RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})","gi");for(;;){const e=r.exec(n);if(null===e)break;t.push(e[0])}n=n.replace(r,"");const o=/@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi,i=new RegExp("((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})","gi");for(;;){let e=o.exec(n);if(null===e){if(e=i.exec(n),null===e)break;o.lastIndex=i.lastIndex}else i.lastIndex=o.lastIndex;t.push(e[0])}return t}async function getCSSRules(e,t){const n=[],r=[];return e.forEach(n=>{if("cssRules"in n)try{toArray(n.cssRules||[]).forEach((e,o)=>{if(e.type===CSSRule.IMPORT_RULE){let i=o+1;const s=fetchCSS(e.href).then(e=>embedFonts(e,t)).then(e=>parseCSS(e).forEach(e=>{try{n.insertRule(e,e.startsWith("@import")?i+=1:n.cssRules.length)}catch(t){console.error("Error inserting rule from remote css",{rule:e,error:t})}})).catch(e=>{console.error("Error loading remote css",e.toString())});r.push(s)}})}catch(o){const i=e.find(e=>null==e.href)||document.styleSheets[0];null!=n.href&&r.push(fetchCSS(n.href).then(e=>embedFonts(e,t)).then(e=>parseCSS(e).forEach(e=>{i.insertRule(e,i.cssRules.length)})).catch(e=>{console.error("Error loading remote stylesheet",e)})),console.error("Error inlining remote css file",o)}}),Promise.all(r).then(()=>(e.forEach(e=>{if("cssRules"in e)try{toArray(e.cssRules||[]).forEach(e=>{n.push(e)})}catch(t){console.error(`Error while reading CSS rules from ${e.href}`,t)}}),n))}function getWebFontRules(e){return e.filter(e=>e.type===CSSRule.FONT_FACE_RULE).filter(e=>shouldEmbed(e.style.getPropertyValue("src")))}async function parseWebFontRules(e,t){if(null==e.ownerDocument)throw new Error("Provided element is not within a Document");const n=toArray(e.ownerDocument.styleSheets);return getWebFontRules(await getCSSRules(n,t))}function normalizeFontFamily(e){return e.trim().replace(/["']/g,"")}function getUsedFonts(e){const t=new Set;return function e(n){(n.style.fontFamily||getComputedStyle(n).fontFamily).split(",").forEach(e=>{t.add(normalizeFontFamily(e))}),Array.from(n.children).forEach(t=>{t instanceof HTMLElement&&e(t)})}(e),t}async function getWebFontCSS(e,t){const n=await parseWebFontRules(e,t),r=getUsedFonts(e);return(await Promise.all(n.filter(e=>r.has(normalizeFontFamily(e.style.fontFamily))).map(e=>{const n=e.parentStyleSheet?e.parentStyleSheet.href:null;return embedResources(e.cssText,n,t)}))).join("\n")}async function embedWebFonts(e,t){const n=null!=t.fontEmbedCSS?t.fontEmbedCSS:t.skipFonts?null:await getWebFontCSS(e,t);if(n){const t=document.createElement("style"),r=document.createTextNode(n);t.appendChild(r),e.firstChild?e.insertBefore(t,e.firstChild):e.appendChild(t)}}async function toSvg(e,t={}){const{width:n,height:r}=getImageSize(e,t),o=await cloneNode(e,t,!0);await embedWebFonts(o,t),await embedImages(o,t),applyStyle(o,t);return await nodeToDataURL(o,n,r)}async function toCanvas(e,t={}){const{width:n,height:r}=getImageSize(e,t),o=await toSvg(e,t),i=await createImage(o),s=document.createElement("canvas"),c=s.getContext("2d"),a=t.pixelRatio||getPixelRatio(),l=t.canvasWidth||n,d=t.canvasHeight||r;return s.width=l*a,s.height=d*a,t.skipAutoScale||checkCanvasDimensions(s),s.style.width=`${l}`,s.style.height=`${d}`,t.backgroundColor&&(c.fillStyle=t.backgroundColor,c.fillRect(0,0,s.width,s.height)),c.drawImage(i,0,0,s.width,s.height),s}async function toPng(e,t={}){return(await toCanvas(e,t)).toDataURL()}async function toJpeg(e,t={}){return(await toCanvas(e,t)).toDataURL("image/jpeg",t.quality||1)}async function takeScreenshot(e,t,n,r,o,i){const s=t??"png",c=n??.92,a=r??1,l=e?document.querySelector(e):document.body;if(!l)return{error:`No element found for selector: ${e}`};try{const e=l,t={quality:c,pixelRatio:a,cacheBust:!0,skipAutoScale:!0,filter:e=>"hypha-debugger-host"!==e.id};let n;n="jpeg"===s?await toJpeg(e,t):await toPng(e,t);const r=e.getBoundingClientRect();let d=Math.round(r.width*a),h=Math.round(r.height*a);if(o&&d>o){const e=o/d;d=o,h=Math.round(h*e)}if(i&&h>i){const e=i/h;h=i,d=Math.round(d*e)}return{data:n,format:s,width:d,height:h}}catch(e){return{error:`Screenshot failed: ${e.message??e}`}}}async function executeScript(e,t){const n=t??1e4;try{const t=await Promise.race([new Function("return (async () => {"+e+"})()")(),new Promise((e,t)=>setTimeout(()=>t(new Error("Execution timed out")),n))]);let r,o=typeof t;try{void 0===t?(r=null,o="undefined"):t instanceof HTMLElement?(r={tag:t.tagName.toLowerCase(),id:t.id,text:(t.textContent??"").trim().slice(0,500)},o="HTMLElement"):t instanceof NodeList||t instanceof HTMLCollection?(r=Array.from(t).map(e=>({tag:e.tagName?.toLowerCase(),id:e.id,text:(e.textContent??"").trim().slice(0,200)})),o="NodeList"):r=JSON.parse(JSON.stringify(t))}catch{r=String(t),o="string (serialized)"}return{result:r,type:o}}catch(e){return{error:`Execution error: ${e.message??e}`}}}takeScreenshot.__schema__={name:"takeScreenshot",description:"Capture a screenshot of the entire page or a specific element. Returns a base64-encoded data URL.",parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the element to capture. Omit to capture the entire page body."},format:{type:"string",enum:["png","jpeg"],description:'Image format. Default: "png".'},quality:{type:"number",description:"Image quality (0-1) for JPEG. Default: 0.92."},scale:{type:"number",description:"Pixel ratio / scale factor. Default: 1. Use 2 for retina."},max_width:{type:"number",description:"Maximum width in pixels. Image will be scaled down if larger."},max_height:{type:"number",description:"Maximum height in pixels. Image will be scaled down if larger."}}}},executeScript.__schema__={name:"executeScript",description:"Execute arbitrary JavaScript code in the page context. Supports async/await. Returns the result of the last expression.",parameters:{type:"object",properties:{code:{type:"string",description:'JavaScript code to execute. The result of the last expression is returned. Example: "return document.title"'},timeout_ms:{type:"number",description:"Maximum execution time in milliseconds. Default: 10000."}},required:["code"]}};const STORAGE_KEY$1="__hypha_debugger_config__";function getScriptUrl(){try{const e=sessionStorage.getItem(STORAGE_KEY$1);if(e){const t=JSON.parse(e);if(t.script_url)return t.script_url}}catch{}return"https://cdn.jsdelivr.net/npm/hypha-debugger/dist/hypha-debugger.min.js"}function injectLoader(e,t){const n=`<script src="${t}"><\/script>`;return e.includes("</body>")?e.replace("</body>",n+"\n</body>"):e.includes("</html>")?e.replace("</html>",n+"\n</html>"):e+"\n"+n}function softReplace(e,t){const n=getScriptUrl();fetch(e,{credentials:"same-origin",cache:"reload"}).then(e=>{if(!e.ok)throw new Error(`HTTP ${e.status}`);if(!(e.headers.get("content-type")??"").includes("text/html"))throw new Error("Not HTML");return e.text()}).then(e=>{const r=injectLoader(e,n);if(document.open(),document.write(r),document.close(),t)try{history.pushState({},"",t)}catch{}}).catch(()=>{t?window.location.href=t:window.location.reload()})}function isSameOrigin(e){try{return new URL(e,location.href).origin===location.origin}catch{return!1}}let _interceptInstalled=!1;function installNavigationInterceptor(){if(_interceptInstalled)return()=>{};_interceptInstalled=!0;const e=e=>{if(e.defaultPrevented||0!==e.button)return;if(e.metaKey||e.ctrlKey||e.shiftKey||e.altKey)return;let t=null,n=e.target;for(;n;){if("A"===n.tagName){t=n;break}n=n.parentElement}if(!t)return;const r=t.href;if(!r)return;if(t.target&&"_self"!==t.target)return;if(t.hasAttribute("download"))return;if(r.startsWith("javascript:")||r.startsWith("mailto:")||r.startsWith("tel:"))return;try{const e=new URL(r,location.href);if(e.origin===location.origin&&e.pathname===location.pathname&&e.search===location.search&&e.hash!==location.hash)return}catch{return}if(!isSameOrigin(r))return;e.preventDefault();const o=new URL(r,location.href).href;softReplace(o,o)},t=e=>{if(e.defaultPrevented)return;const t=e.target;if("GET"!==(t.method||"GET").toUpperCase())return;const n=t.action||location.href;if(!isSameOrigin(n))return;const r=new FormData(t),o=new URL(n,location.href);for(const[e,t]of r.entries())"string"==typeof t&&o.searchParams.set(e,t);t.target&&"_self"!==t.target||(e.preventDefault(),softReplace(o.href,o.href))},n=()=>{softReplace(location.href)};return document.addEventListener("click",e,!0),document.addEventListener("submit",t,!0),window.addEventListener("popstate",n),()=>{document.removeEventListener("click",e,!0),document.removeEventListener("submit",t,!0),window.removeEventListener("popstate",n),_interceptInstalled=!1}}function navigate(e){try{const t=new URL(e,location.href);return t.origin===location.origin?(setTimeout(()=>softReplace(t.href,t.href),150),{success:!0,message:`Navigating to ${e} (debugger will auto-reconnect)`}):(window.location.href=e,{success:!0,message:`Navigating to ${e} (cross-origin, debugger will disconnect)`})}catch(e){return{success:!1,message:`Navigation failed: ${e.message??e}`}}}function goBack(){try{return window.history.back(),{success:!0,message:"Navigated back (debugger will auto-reconnect via popstate)"}}catch(e){return{success:!1,message:`Back navigation failed: ${e.message??e}`}}}function goForward(){try{return window.history.forward(),{success:!0,message:"Navigated forward (debugger will auto-reconnect via popstate)"}}catch(e){return{success:!1,message:`Forward navigation failed: ${e.message??e}`}}}function reload(){try{return setTimeout(()=>softReplace(location.href),150),{success:!0,message:"Reloading page (debugger will auto-reconnect)"}}catch(e){return{success:!1,message:`Reload failed: ${e.message??e}`}}}function getFiberFromDOM(e){const t=Object.keys(e).find(e=>e.startsWith("__reactFiber$")||e.startsWith("__reactInternalInstance$"));return t?e[t]:null}function getComponentName(e){const{type:t}=e;if(!t)return"(unknown)";if("string"==typeof t)return t;if("function"==typeof t)return t.displayName||t.name||"Anonymous";if("object"==typeof t){if(t.displayName)return t.displayName;if(t.render)return t.render.displayName||t.render.name||"ForwardRef";if(t.type)return getComponentName({type:t.type});if("Symbol(react.memo)"===t.$$typeof?.toString())return`Memo(${getComponentName({type:t.type})})`}return"(unknown)"}function getFiberType(e){return 0===e.tag||11===e.tag||14===e.tag||15===e.tag?"function":1===e.tag?"class":5===e.tag||6===e.tag?"host":"other"}function safeSerialize(e,t=0,n=2){if(t>n)return"[max depth]";if(null==e)return e;if("function"==typeof e)return`[Function: ${e.name||"anonymous"}]`;if("object"!=typeof e)return e;if(e instanceof HTMLElement)return`[${e.tagName.toLowerCase()}#${e.id}]`;if(Array.isArray(e))return e.slice(0,10).map(e=>safeSerialize(e,t+1,n));const r={},o=Object.keys(e).slice(0,20);for(const i of o)if(!i.startsWith("_")&&!i.startsWith("$$"))try{r[i]=safeSerialize(e[i],t+1,n)}catch{r[i]="[unserializable]"}return r}function extractState(e){if(1===e.tag&&e.stateNode)return safeSerialize(e.stateNode.state);if(0===e.tag||11===e.tag||15===e.tag){const t=[];let n=e.memoizedState,r=0;for(;n&&r<20;)null!==n.queue&&void 0!==n.queue&&t.push(safeSerialize(n.memoizedState)),n=n.next,r++;return t.length>0?t:null}return null}function fiberToInfo(e,t,n){const r=getFiberType(e),o="function"===r||"class"===r,i={name:getComponentName(e),type:r,props:o?safeSerialize(e.memoizedProps):{},state:o?extractState(e):null,key:e.key,children:[]};if(t<n){let r=e.child;for(;r;){const e=fiberToInfo(r,t+1,n);e&&("host"!==e.type||e.children.length>0)&&i.children.push(e),r=r.sibling}}return i}function getReactTree(e,t){e=e??"#root";const n=t??5,r=document.querySelector(e);if(!r)return{error:`No element found for selector: ${e}`};const o=getFiberFromDOM(r);if(!o)return{error:`No React fiber found on element "${e}". Is this a React app?`};let i=o;for(;i&&3===i.tag;)i=i.child;if(!i)return{error:"Could not find root React component fiber."};const s=fiberToInfo(i,0,n);return s||{error:"Could not build React component tree."}}function generateSkillMd(e,t){const n=["---","name: web-debugger","description: Remote web page debugger. Inspect DOM, take screenshots, execute JavaScript, fill forms, click elements, and navigate pages — all via HTTP API calls.","compatibility: Requires network access to the Hypha server. Works with any HTTP client (curl, fetch, Python requests).","metadata:",' version: "0.1"',' author: "hypha-debugger"',"---"].join("\n"),r=["","# Web Debugger Skill","","This skill allows you to remotely debug and interact with a web page through HTTP API endpoints.","","## Recommended Workflow (Index-Based Interaction)","","The most reliable way to interact with a page is using the smart DOM analysis:","","### Step 1: Observe the page","```bash","curl '{SERVICE_URL}/get_browser_state'","```","This returns all interactive elements indexed as `[0]`, `[1]`, `[2]`, etc.","Elements are detected via smart heuristics: CSS cursor, ARIA roles, event listeners, tag names.","Visual highlight labels are overlaid on the page for each detected element.","","Example output:","```","[0]<a aria-label=Home>Home />","[1]<input placeholder=Search... />","[2]<button>Sign In />","[3]<select name=language>English />",'[4]<div data-scrollable="top=200, bottom=1500">Content area />',"```","","### Step 2: Act on elements by index","```bash","# Click a button (e.g. [2] Sign In):","curl -X POST '{SERVICE_URL}/click_element_by_index' \\"," -H 'Content-Type: application/json' -d '{\"index\": 2}'","","# Type into an input (e.g. [1] Search):","curl -X POST '{SERVICE_URL}/input_text' \\",' -H \'Content-Type: application/json\' -d \'{"index": 1, "text": "hello world"}\'',"","# Select a dropdown option (e.g. [3] Language):","curl -X POST '{SERVICE_URL}/select_option' \\",' -H \'Content-Type: application/json\' -d \'{"index": 3, "option_text": "French"}\'',"","# Scroll down:","curl -X POST '{SERVICE_URL}/scroll' \\"," -H 'Content-Type: application/json' -d '{\"direction\": \"down\"}'","","# Scroll a specific container (e.g. [4]):","curl -X POST '{SERVICE_URL}/scroll' \\",' -H \'Content-Type: application/json\' -d \'{"direction": "down", "index": 4}\'',"```","","### Step 3: Verify","```bash","curl '{SERVICE_URL}/take_screenshot'","```","","### Remove visual highlights (optional, for clean screenshots)","```bash","curl '{SERVICE_URL}/remove_highlights'","```","","## CSS Selector-Based Functions (Alternative)","","You can also use CSS selectors directly for precise targeting:","```bash","curl -X POST '{SERVICE_URL}/click_element' \\"," -H 'Content-Type: application/json' -d '{\"selector\": \"button.submit\"}'","","curl -X POST '{SERVICE_URL}/fill_input' \\",' -H \'Content-Type: application/json\' -d \'{"selector": "#email", "value": "user@example.com"}\'',"```","","## How to call functions","","All functions are available as HTTP endpoints. Replace `{SERVICE_URL}` with the actual service URL.","","- **GET** for functions with no required parameters","- **POST** with JSON body for functions with parameters",""].join("\n"),o=["## Available Functions",""],i=Object.entries(e).filter(([e,t])=>t?.__schema__&&"get_skill_md"!==e);for(const[e,t]of i){const n=t.__schema__;o.push(`### \`${e}\``),o.push(""),o.push(n.description),o.push("");const r=n.parameters?.properties,i=n.parameters?.required??[];if(r&&Object.keys(r).length>0){o.push("**Parameters:**"),o.push(""),o.push("| Parameter | Type | Required | Description |"),o.push("|-----------|------|----------|-------------|");for(const[e,t]of Object.entries(r)){const n=i.includes(e);let r=t.type??"any";t.enum&&(r=t.enum.map(e=>`"${e}"`).join(" | ")),t.items&&(r=`${t.items.type}[]`),o.push(`| \`${e}\` | ${r} | ${n?"Yes":"No"} | ${t.description??""} |`)}if(o.push(""),i.length>0){const t={};for(const e of i){const n=r[e];t[e]="string"===n?.type?`<${e}>`:"number"===n?.type?"0":`<${e}>`}o.push("**Example:**"),o.push("```bash"),o.push(`curl -X POST '{SERVICE_URL}/${e}' \\`),o.push(" -H 'Content-Type: application/json' \\"),o.push(` -d '${JSON.stringify(t)}'`),o.push("```")}else o.push("**Example:**"),o.push("```bash"),o.push(`curl '{SERVICE_URL}/${e}'`),o.push("```")}else o.push("**Parameters:** None"),o.push(""),o.push("**Example:**"),o.push("```bash"),o.push(`curl '{SERVICE_URL}/${e}'`),o.push("```");o.push("")}const s=["## Tips","","- **Start with `get_browser_state`** — it's the best way to understand what's on the page and what you can interact with.","- **Prefer index-based interaction** (`click_element_by_index`, `input_text`, `select_option`) over CSS selectors — indices are more reliable across dynamic pages.","- **After each action, call `get_browser_state` again** — element indices change when the DOM updates.","- **Use `take_screenshot`** to visually verify the page state. Call `remove_highlights` first for a clean view.","- **Use `execute_script`** for anything not covered by the built-in functions — it runs arbitrary JavaScript.","- **Use `scroll`** with an element index to scroll inside a specific container (e.g. a chat window, sidebar).","- **Use `get_page_info` with `include_logs=true`** to check for JavaScript errors or debug output.","- **Use `get_react_tree`** if the page uses React — it gives you component names, props, and state.","- All POST endpoints accept JSON body with the parameter names as keys.",""].join("\n");return[n,r,o.join("\n"),s].join("\n")}function wrapFn(e){const t=e.__schema__,n=t?.parameters?.properties?Object.keys(t.parameters.properties):[];if(0===n.length)return e;const r=n.join(", "),o=new Function("fn",`return async function(${r}) { return fn(${r}); }`)(e);return t&&(o.__schema__=t),o}navigate.__schema__={name:"navigate",description:"Navigate the browser to a new URL. For same-origin URLs, the debugger auto-reconnects. Cross-origin navigation will disconnect the debugger.",parameters:{type:"object",properties:{url:{type:"string",description:"The URL to navigate to."}},required:["url"]}},goBack.__schema__={name:"goBack",description:"Navigate back in browser history. The debugger auto-reconnects for same-origin pages.",parameters:{type:"object",properties:{}}},goForward.__schema__={name:"goForward",description:"Navigate forward in browser history. The debugger auto-reconnects for same-origin pages.",parameters:{type:"object",properties:{}}},reload.__schema__={name:"reload",description:"Reload the current page. The debugger auto-reconnects after reload using soft page replacement.",parameters:{type:"object",properties:{}}},getReactTree.__schema__={name:"getReactTree",description:"Inspect the React component tree starting from a DOM element. Returns component names, props, state (including hooks), and children hierarchy.",parameters:{type:"object",properties:{selector:{type:"string",description:'CSS selector of the React root element. Default: "#root".'},max_depth:{type:"number",description:"Maximum depth to traverse the component tree. Default: 5."}}}};var domTree=(e={doHighlightElements:!0,focusHighlightIndex:-1,viewportExpansion:0,debugMode:!1,interactiveBlacklist:[],interactiveWhitelist:[],highlightOpacity:.1,highlightLabelOpacity:.5})=>{const{interactiveBlacklist:t,interactiveWhitelist:n,highlightOpacity:r,highlightLabelOpacity:o}=e,{doHighlightElements:i,focusHighlightIndex:s,viewportExpansion:c,debugMode:a}=e;let l=0;const d=new WeakMap;const h={boundingRects:new WeakMap,clientRects:new WeakMap,computedStyles:new WeakMap,clearCache:()=>{h.boundingRects=new WeakMap,h.clientRects=new WeakMap,h.computedStyles=new WeakMap}};function u(e){if(!e)return null;if(h.boundingRects.has(e))return h.boundingRects.get(e);const t=e.getBoundingClientRect();return t&&h.boundingRects.set(e,t),t}function _(e){if(!e)return null;if(h.computedStyles.has(e))return h.computedStyles.get(e);const t=window.getComputedStyle(e);return t&&h.computedStyles.set(e,t),t}const p={},f={current:0},m="playwright-highlight-container";function g(e,t,n=null){if(!e)return t;const i=[];let s=null,c=20,a=16,l=null;try{let d=document.getElementById(m);d||(d=document.createElement("div"),d.id=m,d.style.position="fixed",d.style.pointerEvents="none",d.style.top="0",d.style.left="0",d.style.width="100%",d.style.height="100%",d.style.zIndex="2147483640",d.style.backgroundColor="transparent",document.body.appendChild(d));const h=e.getClientRects();if(!h||0===h.length)return t;const u=["#FF0000","#00FF00","#0000FF","#FFA500","#800080","#008080","#FF69B4","#4B0082","#FF4500","#2E8B57","#DC143C","#4682B4"];let _=u[t%u.length];const p=_+Math.floor(255*r).toString(16).padStart(2,"0");_+=Math.floor(255*o).toString(16).padStart(2,"0");let f={x:0,y:0};if(n){const e=n.getBoundingClientRect();f.x=e.left,f.y=e.top}const g=document.createDocumentFragment();for(const e of h){if(0===e.width||0===e.height)continue;const t=document.createElement("div");t.style.position="fixed",t.style.border=`2px solid ${_}`,t.style.backgroundColor=p,t.style.pointerEvents="none",t.style.boxSizing="border-box";const n=e.top+f.y,r=e.left+f.x;t.style.top=`${n}px`,t.style.left=`${r}px`,t.style.width=`${e.width}px`,t.style.height=`${e.height}px`,g.appendChild(t),i.push({element:t,initialRect:e})}const y=h[0];s=document.createElement("div"),s.className="playwright-highlight-label",s.style.position="fixed",s.style.background=_,s.style.color="white",s.style.padding="1px 4px",s.style.borderRadius="4px",s.style.fontSize=`${Math.min(12,Math.max(8,y.height/2))}px`,s.textContent=t.toString(),c=s.offsetWidth>0?s.offsetWidth:c,a=s.offsetHeight>0?s.offsetHeight:a;const w=y.top+f.y,b=y.left+f.x;let v=w+2,E=b+y.width-c-2;(y.width<c+4||y.height<a+4)&&(v=w-a-2,E=b+y.width-c,E<f.x&&(E=b)),v=Math.max(0,Math.min(v,window.innerHeight-a)),E=Math.max(0,Math.min(E,window.innerWidth-c)),s.style.top=`${v}px`,s.style.left=`${E}px`,g.appendChild(s);const k=(e,t)=>{let n=0;return(...r)=>{const o=performance.now();if(!(o-n<t))return n=o,e(...r)}},x=k(()=>{const t=e.getClientRects();let r={x:0,y:0};if(n){const e=n.getBoundingClientRect();r.x=e.left,r.y=e.top}if(i.forEach((e,n)=>{if(n<t.length){const o=t[n],i=o.top+r.y,s=o.left+r.x;e.element.style.top=`${i}px`,e.element.style.left=`${s}px`,e.element.style.width=`${o.width}px`,e.element.style.height=`${o.height}px`,e.element.style.display=0===o.width||0===o.height?"none":"block"}else e.element.style.display="none"}),t.length<i.length)for(let e=t.length;e<i.length;e++)i[e].element.style.display="none";if(s&&t.length>0){const e=t[0],n=e.top+r.y,o=e.left+r.x;let i=n+2,l=o+e.width-c-2;(e.width<c+4||e.height<a+4)&&(i=n-a-2,l=o+e.width-c,l<r.x&&(l=o)),i=Math.max(0,Math.min(i,window.innerHeight-a)),l=Math.max(0,Math.min(l,window.innerWidth-c)),s.style.top=`${i}px`,s.style.left=`${l}px`,s.style.display="block"}else s&&(s.style.display="none")},16);return window.addEventListener("scroll",x,!0),window.addEventListener("resize",x),l=()=>{window.removeEventListener("scroll",x,!0),window.removeEventListener("resize",x),i.forEach(e=>e.element.remove()),s&&s.remove()},d.appendChild(g),t+1}finally{l&&(window._highlightCleanupFunctions=window._highlightCleanupFunctions||[]).push(l)}}function y(e){if(!e||e.nodeType!==Node.ELEMENT_NODE)return null;const t=_(e);if(!t)return null;const n=t.display;if("inline"===n||"inline-block"===n)return null;const r=t.overflowX,o=t.overflowY,i="auto"===r||"scroll"===r,s="auto"===o||"scroll"===o;if(!i&&!s)return null;const c=e.scrollWidth-e.clientWidth,a=e.scrollHeight-e.clientHeight;if(c<4&&a<4)return null;if(!s&&c<4)return null;if(!i&&a<4)return null;const l=e.scrollTop,h=e.scrollLeft,u={top:l,right:e.scrollWidth-e.clientWidth-e.scrollLeft,bottom:e.scrollHeight-e.clientHeight-e.scrollTop,left:h};return function(e,t){e&&e.nodeType===Node.ELEMENT_NODE&&d.set(e,{...d.get(e),...t})}(e,{scrollable:!0,scrollData:u}),u}function w(e){try{if(-1===c){const t=e.parentElement;if(!t)return!1;try{return t.checkVisibility({checkOpacity:!0,checkVisibilityCSS:!0})}catch(e){const n=window.getComputedStyle(t);return"none"!==n.display&&"hidden"!==n.visibility&&"0"!==n.opacity}}const t=document.createRange();t.selectNodeContents(e);const n=t.getClientRects();if(!n||0===n.length)return!1;let r=!1,o=!1;for(const e of n)if(e.width>0&&e.height>0&&(r=!0,!(e.bottom<-c||e.top>window.innerHeight+c||e.right<-c||e.left>window.innerWidth+c))){o=!0;break}if(!r||!o)return!1;const i=e.parentElement;if(!i)return!1;try{return i.checkVisibility({checkOpacity:!0,checkVisibilityCSS:!0})}catch(e){const t=window.getComputedStyle(i);return"none"!==t.display&&"hidden"!==t.visibility&&"0"!==t.opacity}}catch(e){return console.warn("Error checking text node visibility:",e),!1}}function b(e){const t=_(e);return e.offsetWidth>0&&e.offsetHeight>0&&"hidden"!==t?.visibility&&"none"!==t?.display}function v(e){if(!e||e.nodeType!==Node.ELEMENT_NODE)return!1;if(t.includes(e))return!1;if(n.includes(e))return!0;const r=e.tagName.toLowerCase(),o=_(e),i=new Set(["pointer","move","text","grab","grabbing","cell","copy","alias","all-scroll","col-resize","context-menu","crosshair","e-resize","ew-resize","help","n-resize","ne-resize","nesw-resize","ns-resize","nw-resize","nwse-resize","row-resize","s-resize","se-resize","sw-resize","vertical-text","w-resize","zoom-in","zoom-out"]),s=new Set(["not-allowed","no-drop","wait","progress","initial","inherit"]);let c=function(e){return"html"!==e.tagName.toLowerCase()&&!(!o?.cursor||!i.has(o.cursor))}(e);if(c)return!0;const a=new Set(["a","button","input","select","textarea","details","summary","label","option","optgroup","fieldset","legend"]),l=new Set(["disabled","readonly"]);if(a.has(r)){if(o?.cursor&&s.has(o.cursor))return!1;for(const t of l)if(e.hasAttribute(t)||"true"===e.getAttribute(t)||""===e.getAttribute(t))return!1;return!e.disabled&&(!e.readOnly&&!e.inert)}const d=e.getAttribute("role"),h=e.getAttribute("aria-role");if("true"===e.getAttribute("contenteditable")||e.isContentEditable)return!0;if(e.classList&&(e.classList.contains("button")||e.classList.contains("dropdown-toggle")||e.getAttribute("data-index")||"dropdown"===e.getAttribute("data-toggle")||"true"===e.getAttribute("aria-haspopup")))return!0;const u=new Set(["button","menu","menubar","menuitem","menuitemradio","menuitemcheckbox","radio","checkbox","tab","switch","slider","spinbutton","combobox","searchbox","textbox","listbox","option","scrollbar"]);if(a.has(r)||d&&u.has(d)||h&&u.has(h))return!0;try{if("function"==typeof getEventListeners){const t=getEventListeners(e),n=["click","mousedown","mouseup","dblclick"];for(const e of n)if(t[e]&&t[e].length>0)return!0}const t=e?.ownerDocument?.defaultView?.getEventListenersForNode||window.getEventListenersForNode;if("function"==typeof t){const n=t(e),r=["click","mousedown","mouseup","keydown","keyup","submit","change","input","focus","blur"];for(const e of r)for(const t of n)if(t.type===e)return!0}const n=["onclick","onmousedown","onmouseup","ondblclick"];for(const t of n)if(e.hasAttribute(t)||"function"==typeof e[t])return!0}catch(e){}return!!y(e)}function E(e){if(-1===c)return!0;const t=function(e){if(!e)return null;if(h.clientRects.has(e))return h.clientRects.get(e);const t=e.getClientRects();return t&&h.clientRects.set(e,t),t}(e);if(!t||0===t.length)return!1;let n=!1;for(const e of t)if(e.width>0&&e.height>0&&!(e.bottom<-c||e.top>window.innerHeight+c||e.right<-c||e.left>window.innerWidth+c)){n=!0;break}if(!n)return!1;if(e.ownerDocument!==window.document)return!0;let r=Array.from(t).find(e=>e.width>0&&e.height>0);if(!r)return!1;const o=e.getRootNode();if(o instanceof ShadowRoot){const t=r.left+r.width/2,n=r.top+r.height/2;try{const r=o.elementFromPoint(t,n);if(!r)return!1;let i=r;for(;i&&i!==o;){if(i===e)return!0;i=i.parentElement}return!1}catch(e){return!0}}return[{x:r.left+r.width/2,y:r.top+r.height/2},{x:r.left+5,y:r.top+5},{x:r.right-5,y:r.bottom-5}].some(({x:t,y:n})=>{try{const r=document.elementFromPoint(t,n);if(!r)return!1;let o=r;for(;o&&o!==document.documentElement;){if(o===e)return!0;o=o.parentElement}return!1}catch(e){return!0}})}const k=new Set(["a","button","input","select","textarea","summary","details","label","option"]),x=new Set(["button","link","menuitem","menuitemradio","menuitemcheckbox","radio","checkbox","tab","switch","slider","spinbutton","combobox","searchbox","textbox","listbox","option","scrollbar"]);function S(e){if(!e||e.nodeType!==Node.ELEMENT_NODE)return!1;const t=e.tagName.toLowerCase(),n=e.getAttribute("role");if("iframe"===t)return!0;if(k.has(t))return!0;if(n&&x.has(n))return!0;if(e.isContentEditable||"true"===e.getAttribute("contenteditable"))return!0;if(e.hasAttribute("data-testid")||e.hasAttribute("data-cy")||e.hasAttribute("data-test"))return!0;if(e.hasAttribute("onclick")||"function"==typeof e.onclick)return!0;try{const t=e?.ownerDocument?.defaultView?.getEventListenersForNode||window.getEventListenersForNode;if("function"==typeof t){const n=t(e),r=["click","mousedown","mouseup","keydown","keyup","submit","change","input","focus","blur"];for(const e of r)for(const t of n)if(t.type===e)return!0}if(["onmousedown","onmouseup","onkeydown","onkeyup","onsubmit","onchange","oninput","onfocus","onblur"].some(t=>e.hasAttribute(t)))return!0}catch(e){}return!!function(e){if(!e||e.nodeType!==Node.ELEMENT_NODE)return!1;if(!b(e))return!1;const t=e.hasAttribute("role")||e.hasAttribute("tabindex")||e.hasAttribute("onclick")||"function"==typeof e.onclick,n=/\b(btn|clickable|menu|item|entry|link)\b/i.test(e.className||""),r=Boolean(e.closest('button,a,[role="button"],.menu,.dropdown,.list,.toolbar')),o=[...e.children].some(b),i=e.parentElement&&e.parentElement.isSameNode(document.body);return(v(e)||t||n)&&o&&r&&!i}(e)}function T(e,t,n,r){if(!e.isInteractive)return!1;let o=!1;return o=!r||!!S(t),!(!o||(e.isInViewport=function(e,t){if(-1===t)return!0;const n=e.getClientRects();if(!n||0===n.length){const n=u(e);return!(!n||0===n.width||0===n.height||n.bottom<-t||n.top>window.innerHeight+t||n.right<-t||n.left>window.innerWidth+t)}for(const e of n)if(0!==e.width&&0!==e.height&&!(e.bottom<-t||e.top>window.innerHeight+t||e.right<-t||e.left>window.innerWidth+t))return!0;return!1}(t,c),!e.isInViewport&&-1!==c||(e.highlightIndex=l++,!i)))&&(s>=0?s===e.highlightIndex&&g(t,e.highlightIndex,n):g(t,e.highlightIndex,n),!0)}const C=function e(t,n=null,r=!1){if(!t||t.id===m||t.nodeType!==Node.ELEMENT_NODE&&t.nodeType!==Node.TEXT_NODE)return null;if(!t||t.id===m)return null;if("true"===t.dataset?.browserUseIgnore||"true"===t.dataset?.pageAgentIgnore)return null;if(t.getAttribute&&"true"===t.getAttribute("aria-hidden"))return null;if(t===document.body){const r={tagName:"body",attributes:{},xpath:"/body",children:[]};for(const o of t.childNodes){const t=e(o,n,!1);t&&r.children.push(t)}const o=""+f.current++;return p[o]=r,o}if(t.nodeType!==Node.ELEMENT_NODE&&t.nodeType!==Node.TEXT_NODE)return null;if(t.nodeType===Node.TEXT_NODE){const e=t.textContent?.trim();if(!e)return null;const n=t.parentElement;if(!n||"script"===n.tagName.toLowerCase())return null;const r=""+f.current++;return p[r]={type:"TEXT_NODE",text:e,isVisible:w(t)},r}if(t.nodeType===Node.ELEMENT_NODE&&!function(e){if(!e||!e.tagName)return!1;const t=new Set(["body","div","main","article","section","nav","header","footer"]),n=e.tagName.toLowerCase();return!!t.has(n)||!new Set(["svg","script","style","link","meta","noscript","template"]).has(n)}(t))return null;if(-1!==c&&!t.shadowRoot){const e=u(t),n=_(t),r=n&&("fixed"===n.position||"sticky"===n.position),o=t.offsetWidth>0||t.offsetHeight>0;if(!e||!r&&!o&&(e.bottom<-c||e.top>window.innerHeight+c||e.right<-c||e.left>window.innerWidth+c))return null}const o={tagName:t.tagName.toLowerCase(),attributes:{},children:[]};if(function(e){if(!e||e.nodeType!==Node.ELEMENT_NODE)return!1;const t=e.tagName.toLowerCase();return!!new Set(["a","button","input","select","textarea","details","summary","label"]).has(t)||(e.hasAttribute("onclick")||e.hasAttribute("role")||e.hasAttribute("tabindex")||e.hasAttribute("aria-")||e.hasAttribute("data-action")||"true"===e.getAttribute("contenteditable"))}(t)||"iframe"===t.tagName.toLowerCase()||"body"===t.tagName.toLowerCase()){const e=t.getAttributeNames?.()||[];for(const n of e){const e=t.getAttribute(n);o.attributes[n]=e}"input"!==t.tagName.toLowerCase()||"checkbox"!==t.type&&"radio"!==t.type||(o.attributes.checked=t.checked?"true":"false")}let i=!1;if(t.nodeType===Node.ELEMENT_NODE&&(o.isVisible=b(t),o.isVisible)){o.isTopElement=E(t);const e=t.getAttribute("role"),s="menu"===e||"menubar"===e||"listbox"===e;if((o.isTopElement||s)&&(o.isInteractive=v(t),i=T(o,t,n,r),o.ref=t,o.isInteractive&&0===Object.keys(o.attributes).length)){const e=t.getAttributeNames?.()||[];for(const n of e){const e=t.getAttribute(n);o.attributes[n]=e}}}if(t.tagName){const s=t.tagName.toLowerCase();if("iframe"===s)try{const n=t.contentDocument||t.contentWindow?.document;if(n)for(const r of n.childNodes){const n=e(r,t,!1);n&&o.children.push(n)}}catch(e){console.warn("Unable to access iframe:",e)}else if(t.isContentEditable||"true"===t.getAttribute("contenteditable")||"tinymce"===t.id||t.classList.contains("mce-content-body")||"body"===s&&t.getAttribute("data-id")?.startsWith("mce_"))for(const r of t.childNodes){const t=e(r,n,i);t&&o.children.push(t)}else{if(t.shadowRoot){o.shadowRoot=!0;for(const r of t.shadowRoot.childNodes){const t=e(r,n,i);t&&o.children.push(t)}}for(const s of t.childNodes){const t=e(s,n,i||r);t&&o.children.push(t)}}}if("a"===o.tagName&&0===o.children.length&&!o.attributes.href){const e=u(t);if(!(e&&e.width>0&&e.height>0||t.offsetWidth>0||t.offsetHeight>0))return null}o.extra=d.get(t)||null;const s=""+f.current++;return p[s]=o,s}(document.body);return h.clearCache(),{rootId:C,map:p}};const DEFAULT_VIEWPORT_EXPANSION=-1;function resolveViewportExpansion(e){return e??DEFAULT_VIEWPORT_EXPANSION}const newElementsCache=new WeakMap;function getFlatTree(e){const t=resolveViewportExpansion(e.viewportExpansion),n=[];for(const t of e.interactiveBlacklist||[])"function"==typeof t?n.push(t()):n.push(t);const r=[];for(const t of e.interactiveWhitelist||[])"function"==typeof t?r.push(t()):r.push(t);const o=domTree({doHighlightElements:!0,debugMode:!0,focusHighlightIndex:-1,viewportExpansion:t,interactiveBlacklist:n,interactiveWhitelist:r,highlightOpacity:e.highlightOpacity??0,highlightLabelOpacity:e.highlightLabelOpacity??.1});for(const e in o.map){const t=o.map[e];if(t.isInteractive&&t.ref){const e=t.ref;newElementsCache.has(e)||(newElementsCache.set(e,window.location.href),t.isNew=!0)}}return o}const globRegexCache=new Map;function globToRegex(e){let t=globRegexCache.get(e);if(!t){const n=e.replace(/[.+^${}()|[\]\\]/g,"\\$&");t=new RegExp(`^${n.replace(/\*/g,".*")}$`),globRegexCache.set(e,t)}return t}function matchAttributes(e,t){const n={};for(const r of t)if(r.includes("*")){const t=globToRegex(r);for(const r of Object.keys(e))t.test(r)&&e[r].trim()&&(n[r]=e[r].trim())}else{const t=e[r];t&&t.trim()&&(n[r]=t.trim())}return n}function flatTreeToString(e,t){const n=[...t||[],"title","type","checked","name","role","value","placeholder","data-date-format","alt","aria-label","aria-expanded","data-state","aria-checked","id","for","target","aria-haspopup","aria-controls","aria-owns","contenteditable"],r=t=>{const n=e.map[t];if(!n)return null;if("TEXT_NODE"===n.type){const e=n;return{type:"text",text:e.text,isVisible:e.isVisible,parent:null,children:[]}}{const e=n,t=[];if(e.children)for(const n of e.children){const e=r(n);e&&t.push(e)}return{type:"element",tagName:e.tagName,attributes:e.attributes??{},isVisible:e.isVisible??!1,isInteractive:e.isInteractive??!1,isTopElement:e.isTopElement??!1,isNew:e.isNew??!1,highlightIndex:e.highlightIndex,parent:null,children:t,extra:e.extra??{}}}},o=(e,t=null)=>{e.parent=t;for(const t of e.children)o(t,e)},i=r(e.rootId);if(!i)return"";o(i);const s=(e,t,r)=>{let o=t;const i="\t".repeat(t);if("element"===e.type){if(void 0!==e.highlightIndex){o+=1;const t=getAllTextTillNextClickableElement(e);let s="";if(n.length>0&&e.attributes){const r=matchAttributes(e.attributes,n),o=Object.keys(r);if(o.length>1){const e=new Set,t={};for(const n of o){const o=r[n];o.length>5&&(o in t?e.add(n):t[o]=n)}for(const t of e)delete r[t]}r.role===e.tagName&&delete r.role;const i=["aria-label","placeholder","title"];for(const e of i)r[e]&&r[e].toLowerCase().trim()===t.toLowerCase().trim()&&delete r[e];Object.keys(r).length>0&&(s=Object.entries(r).map(([e,t])=>`${e}=${((e,t)=>e.length>t?e.substring(0,t)+"...":e)(t,20)}`).join(" "))}let c=`${i}${e.isNew?`*[${e.highlightIndex}]`:`[${e.highlightIndex}]`}<${e.tagName??""}`;if(s&&(c+=` ${s}`),e.extra&&e.extra.scrollable){let t="";e.extra.scrollData?.left&&(t+=`left=${e.extra.scrollData.left}, `),e.extra.scrollData?.top&&(t+=`top=${e.extra.scrollData.top}, `),e.extra.scrollData?.right&&(t+=`right=${e.extra.scrollData.right}, `),e.extra.scrollData?.bottom&&(t+=`bottom=${e.extra.scrollData.bottom}`),c+=` data-scrollable="${t}"`}if(t){s||(c+=" "),c+=`>${t.trim()}`}else s||(c+=" ");c+=" />",r.push(c)}for(const t of e.children)s(t,o,r)}else if("text"===e.type){if((e=>{let t=e.parent;for(;t;){if("element"===t.type&&void 0!==t.highlightIndex)return!0;t=t.parent}return!1})(e))return;e.parent&&"element"===e.parent.type&&e.parent.isVisible&&e.parent.isTopElement&&r.push(`${i}${e.text??""}`)}},c=[];return s(i,0,c),c.join("\n")}const getAllTextTillNextClickableElement=(e,t=-1)=>{const n=[],r=(o,i)=>{if(!(-1!==t&&i>t||"element"===o.type&&o!==e&&void 0!==o.highlightIndex))if("text"===o.type&&o.text)n.push(o.text);else if("element"===o.type)for(const e of o.children)r(e,i+1)};return r(e,0),n.join("\n").trim()};function getSelectorMap(e){const t=new Map,n=Object.keys(e.map);for(const r of n){const n=e.map[r];n.isInteractive&&"number"==typeof n.highlightIndex&&t.set(n.highlightIndex,n)}return t}function getElementTextMap(e){const t=e.split("\n").map(e=>e.trim()).filter(e=>e.length>0),n=new Map;for(const e of t){const t=/^\[(\d+)\]<[^>]+>([^<]*)/.exec(e);if(t){const r=parseInt(t[1],10);n.set(r,e)}}return n}function cleanUpHighlights(){const e=window._highlightCleanupFunctions||[];for(const t of e)"function"==typeof t&&t();window._highlightCleanupFunctions=[]}async function waitFor(e){await new Promise(t=>setTimeout(t,1e3*e))}function getElementByIndex(e,t){const n=e.get(t);if(!n)throw new Error(`No interactive element found at index ${t}`);const r=n.ref;if(!r)throw new Error(`Element at index ${t} does not have a reference`);if(!(r instanceof HTMLElement))throw new Error(`Element at index ${t} is not an HTMLElement`);return r}let lastClickedElement=null;function blurLastClickedElement(){lastClickedElement&&(lastClickedElement.blur(),lastClickedElement.dispatchEvent(new MouseEvent("mouseout",{bubbles:!0,cancelable:!0})),lastClickedElement=null)}async function scrollIntoViewIfNeeded(e){const t=e.getBoundingClientRect();t.top>=0&&t.bottom<=window.innerHeight&&t.left>=0&&t.right<=window.innerWidth||(e.scrollIntoView({behavior:"smooth",block:"center",inline:"nearest"}),await waitFor(.4))}async function movePointerToElement(e){const t=e.getBoundingClientRect(),n=t.left+t.width/2,r=t.top+t.height/2;window.dispatchEvent(new CustomEvent("HyphaDebugger::MovePointerTo",{detail:{x:n,y:r}})),await waitFor(.3)}async function clickElement(e){blurLastClickedElement(),lastClickedElement=e,await scrollIntoViewIfNeeded(e),await movePointerToElement(e),window.dispatchEvent(new CustomEvent("HyphaDebugger::ClickPointer")),await waitFor(.05),e.dispatchEvent(new MouseEvent("mouseenter",{bubbles:!0,cancelable:!0})),e.dispatchEvent(new MouseEvent("mouseover",{bubbles:!0,cancelable:!0})),e.dispatchEvent(new MouseEvent("mousedown",{bubbles:!0,cancelable:!0})),e.focus(),e.dispatchEvent(new MouseEvent("mouseup",{bubbles:!0,cancelable:!0})),e.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0})),await waitFor(.2)}let _nativeInputValueSetter=null,_nativeTextAreaValueSetter=null;function getNativeInputValueSetter(){return _nativeInputValueSetter||(_nativeInputValueSetter=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,"value").set),_nativeInputValueSetter}function getNativeTextAreaValueSetter(){return _nativeTextAreaValueSetter||(_nativeTextAreaValueSetter=Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype,"value").set),_nativeTextAreaValueSetter}async function inputTextElement(e,t){const n=e.isContentEditable;if(!(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||n))throw new Error("Element is not an input, textarea, or contenteditable");await clickElement(e),n?(e.dispatchEvent(new InputEvent("beforeinput",{bubbles:!0,cancelable:!0,inputType:"deleteContent"}))&&(e.innerText="",e.dispatchEvent(new InputEvent("input",{bubbles:!0,inputType:"deleteContent"}))),e.dispatchEvent(new InputEvent("beforeinput",{bubbles:!0,cancelable:!0,inputType:"insertText",data:t}))&&(e.innerText=t,e.dispatchEvent(new InputEvent("input",{bubbles:!0,inputType:"insertText",data:t}))),e.dispatchEvent(new Event("change",{bubbles:!0})),e.blur()):e instanceof HTMLTextAreaElement?getNativeTextAreaValueSetter().call(e,t):getNativeInputValueSetter().call(e,t),n||e.dispatchEvent(new Event("input",{bubbles:!0})),await waitFor(.1),blurLastClickedElement()}async function selectOptionElement(e,t){if(!(e instanceof HTMLSelectElement))throw new Error("Element is not a select element");await scrollIntoViewIfNeeded(e);const n=e.getBoundingClientRect();window.dispatchEvent(new CustomEvent("HyphaDebugger::MovePointerTo",{detail:{x:n.left+n.width/2,y:n.top+n.height/2}})),await waitFor(.3),window.dispatchEvent(new CustomEvent("HyphaDebugger::ClickPointer"));const r=Array.from(e.options).find(e=>e.textContent?.trim()===t.trim());if(!r)throw new Error(`Option with text "${t}" not found in select element`);e.value=r.value,e.dispatchEvent(new Event("change",{bubbles:!0})),await waitFor(.1)}async function scrollVertically(e,t,n){if(n){let e=n,r=!1,o=null,i=0,s=0;const c=t;for(;e&&s<10;){const t=window.getComputedStyle(e),n=/(auto|scroll|overlay)/.test(t.overflowY),a=e.scrollHeight>e.clientHeight;if(n&&a){const t=e.scrollTop,n=e.scrollHeight-e.clientHeight;let s=c/3;s=s>0?Math.min(s,n-t):Math.max(s,-t),e.scrollTop=t+s;const a=e.scrollTop-t;if(Math.abs(a)>.5){r=!0,o=e,i=a;break}}if(e===document.body||e===document.documentElement)break;e=e.parentElement,s++}return r?`Scrolled container (${o?.tagName}) by ${i}px`:`No scrollable container found for element (${n.tagName})`}const r=t,o=e=>e&&/(auto|scroll|overlay)/.test(getComputedStyle(e).overflowY)&&e.scrollHeight>e.clientHeight&&(e=>e.clientHeight>=.5*window.innerHeight)(e);let i=document.activeElement;for(;i&&!o(i)&&i!==document.body;)i=i.parentElement;if(i=o(i)?i:Array.from(document.querySelectorAll("*")).find(o)||document.scrollingElement||document.documentElement,i===document.scrollingElement||i===document.documentElement||i===document.body){const e=window.scrollY;window.scrollBy(0,r);const t=window.scrollY,n=t-e;if(Math.abs(n)<1)return r>0?"Already at the bottom of the page.":"Already at the top of the page.";const o=document.documentElement.scrollHeight-window.innerHeight;return r>0&&t>=o-1?`Scrolled page by ${n}px. Reached the bottom.`:r<0&&t<=1?`Scrolled page by ${n}px. Reached the top.`:`Scrolled page by ${n}px.`}{const e=i.scrollTop,t=i.scrollHeight-i.clientHeight;i.scrollBy({top:r,behavior:"smooth"}),await waitFor(.1);const n=i.scrollTop,o=n-e;if(Math.abs(o)<1)return r>0?`Already at the bottom of container (${i.tagName}).`:`Already at the top of container (${i.tagName}).`;const s=r<0&&n<=1;return r>0&&n>=t-1?`Scrolled container (${i.tagName}) by ${o}px. Reached the bottom.`:s?`Scrolled container (${i.tagName}) by ${o}px. Reached the top.`:`Scrolled container (${i.tagName}) by ${o}px.`}}async function scrollHorizontally(e,t,n){if(n){let r=n,o=!1,i=null,s=0,c=0;const a=e?t:-t;for(;r&&c<10;){const e=window.getComputedStyle(r),t=/(auto|scroll|overlay)/.test(e.overflowX),n=r.scrollWidth>r.clientWidth;if(t&&n){const e=r.scrollLeft,t=r.scrollWidth-r.clientWidth;let n=a/3;n=n>0?Math.min(n,t-e):Math.max(n,-e),r.scrollLeft=e+n;const c=r.scrollLeft-e;if(Math.abs(c)>.5){o=!0,i=r,s=c;break}}if(r===document.body||r===document.documentElement)break;r=r.parentElement,c++}return o?`Scrolled container (${i?.tagName}) horizontally by ${s}px`:`No horizontally scrollable container found for element (${n.tagName})`}const r=e?t:-t,o=e=>e&&/(auto|scroll|overlay)/.test(getComputedStyle(e).overflowX)&&e.scrollWidth>e.clientWidth&&(e=>e.clientWidth>=.5*window.innerWidth)(e);let i=document.activeElement;for(;i&&!o(i)&&i!==document.body;)i=i.parentElement;if(i=o(i)?i:Array.from(document.querySelectorAll("*")).find(o)||document.scrollingElement||document.documentElement,i===document.scrollingElement||i===document.documentElement||i===document.body){const e=window.scrollX,t=document.documentElement.scrollWidth-window.innerWidth;window.scrollBy(r,0);const n=window.scrollX,o=n-e;if(Math.abs(o)<1)return r>0?"Already at the right edge of the page.":"Already at the left edge of the page.";return r>0&&n>=t-1?`Scrolled page by ${o}px. Reached the right edge.`:r<0&&n<=1?`Scrolled page by ${o}px. Reached the left edge.`:`Scrolled page horizontally by ${o}px.`}{const e=i.scrollLeft,t=i.scrollWidth-i.clientWidth;i.scrollBy({left:r,behavior:"smooth"}),await waitFor(.1);const n=i.scrollLeft,o=n-e;if(Math.abs(o)<1)return r>0?`Already at the right edge of container (${i.tagName}).`:`Already at the left edge of container (${i.tagName}).`;const s=r<0&&n<=1;return r>0&&n>=t-1?`Scrolled container (${i.tagName}) by ${o}px. Reached the right edge.`:s?`Scrolled container (${i.tagName}) by ${o}px. Reached the left edge.`:`Scrolled container (${i.tagName}) horizontally by ${o}px.`}}function getPageScrollInfo(){const e=window.innerWidth,t=window.innerHeight,n=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth||0),r=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight||0),o=window.scrollX||window.pageXOffset||document.documentElement.scrollLeft||0,i=window.scrollY||window.pageYOffset||document.documentElement.scrollTop||0,s=Math.max(0,r-(window.innerHeight+i)),c=Math.max(0,n-(window.innerWidth+o));return{viewport_width:e,viewport_height:t,page_width:n,page_height:r,scroll_x:o,scroll_y:i,pixels_above:i,pixels_below:s,pages_above:t>0?i/t:0,pages_below:t>0?s/t:0,total_pages:t>0?r/t:0,current_page_position:i/Math.max(1,r-t),pixels_left:o,pixels_right:c}}class PageController{constructor(e={}){this.flatTree=null,this.selectorMap=new Map,this.elementTextMap=new Map,this.simplifiedHTML="",this.isIndexed=!1,this.config=e}async getBrowserState(){const e=window.location.href,t=document.title,n=getPageScrollInfo(),r=resolveViewportExpansion(this.config.viewportExpansion);await this.updateTree();const o=this.simplifiedHTML;return{url:e,title:t,header:`${`Current Page: [${t}](${e})`}\n${`Page info: ${n.viewport_width}x${n.viewport_height}px viewport, ${n.page_width}x${n.page_height}px total, ${n.pages_above.toFixed(1)} pages above, ${n.pages_below.toFixed(1)} pages below, at ${(100*n.current_page_position).toFixed(0)}%`}\n\n${-1===r?"Interactive elements (full page):":"Interactive elements (viewport):"}\n\n${n.pixels_above>4&&-1!==r?`... ${n.pixels_above} pixels above - scroll to see more ...`:"[Start of page]"}`,content:o,footer:n.pixels_below>4&&-1!==r?`... ${n.pixels_below} pixels below - scroll to see more ...`:"[End of page]",element_count:this.selectorMap.size}}async updateTree(){return cleanUpHighlights(),this.flatTree=getFlatTree(this.config),this.simplifiedHTML=flatTreeToString(this.flatTree,this.config.includeAttributes),this.selectorMap.clear(),this.selectorMap=getSelectorMap(this.flatTree),this.elementTextMap.clear(),this.elementTextMap=getElementTextMap(this.simplifiedHTML),this.isIndexed=!0,this.simplifiedHTML}async cleanUpHighlights(){cleanUpHighlights()}assertIndexed(){if(!this.isIndexed)throw new Error("DOM tree not indexed yet. Call get_browser_state first.")}cleanUpAfterAction(){cleanUpHighlights()}async clickElement(e){try{this.assertIndexed();const t=getElementByIndex(this.selectorMap,e),n=this.elementTextMap.get(e);return this.cleanUpAfterAction(),await clickElement(t),t instanceof HTMLAnchorElement&&"_blank"===t.target?{success:!0,message:`Clicked element (${n??e}). Link opened in a new tab.`}:{success:!0,message:`Clicked element (${n??e}).`}}catch(e){return{success:!1,message:`Failed to click element: ${e}`}}}async inputText(e,t){try{this.assertIndexed();const n=getElementByIndex(this.selectorMap,e),r=this.elementTextMap.get(e);return this.cleanUpAfterAction(),await inputTextElement(n,t),{success:!0,message:`Input text "${t}" into element (${r??e}).`}}catch(e){return{success:!1,message:`Failed to input text: ${e}`}}}async selectOption(e,t){try{this.assertIndexed();const n=getElementByIndex(this.selectorMap,e),r=this.elementTextMap.get(e);return this.cleanUpAfterAction(),await selectOptionElement(n,t),{success:!0,message:`Selected option "${t}" in element (${r??e}).`}}catch(e){return{success:!1,message:`Failed to select option: ${e}`}}}async scroll(e){try{this.assertIndexed(),this.cleanUpAfterAction();const{direction:t,amount:n,index:r}=e,o=void 0!==r?getElementByIndex(this.selectorMap,r):null;let i;if("left"===t||"right"===t){const e=n??.8*window.innerWidth;i=await scrollHorizontally("right"===t,e,o)}else{const e=n??.8*window.innerHeight,r="down"===t?e:-e;i=await scrollVertically("down"===t,r,o)}return{success:!0,message:i}}catch(e){return{success:!1,message:`Failed to scroll: ${e}`}}}dispose(){cleanUpHighlights(),this.flatTree=null,this.selectorMap.clear(),this.elementTextMap.clear(),this.simplifiedHTML="",this.isIndexed=!1}}let controller=null;function getController(){return controller||(controller=new PageController({viewportExpansion:-1,highlightOpacity:.1,highlightLabelOpacity:.5})),controller}async function getBrowserState(e){const t=getController();return void 0!==e&&(t.config.viewportExpansion=e?0:-1),t.getBrowserState()}async function clickElementByIndex(e){return getController().clickElement(e)}async function inputText(e,t){return getController().inputText(e,t)}async function selectOption(e,t){return getController().selectOption(e,t)}async function scroll(e,t,n){return getController().scroll({direction:e,amount:t,index:n})}async function removeHighlights(){return getController().cleanUpHighlights(),{success:!0,message:"Highlights removed."}}function disposeController(){controller&&(controller.dispose(),controller=null)}function randomHex(e=8){const t=new Uint8Array(e);return crypto.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}getBrowserState.__schema__={name:"getBrowserState",description:"Get the current page state with all interactive elements indexed as [0], [1], [2], etc. Returns a simplified HTML representation optimized for LLM consumption. Interactive elements (buttons, links, inputs, scrollable areas) are detected via smart heuristics (CSS cursor, ARIA roles, event listeners, tag names). Use the returned indices with click_element_by_index, input_text, select_option, or scroll. Call this first to understand the page before performing any actions.",parameters:{type:"object",properties:{viewport_only:{type:"boolean",description:"If true, only return elements visible in the current viewport. Default: false (full page)."}}}},clickElementByIndex.__schema__={name:"clickElementByIndex",description:"Click an interactive element by its numeric index from get_browser_state output. Simulates a full mouse event sequence (hover, mousedown, focus, mouseup, click) to trigger all event listeners including React/Vue handlers.",parameters:{type:"object",properties:{index:{type:"number",description:"The element index from get_browser_state (e.g. 0 for [0], 5 for [5])."}},required:["index"]}},inputText.__schema__={name:"inputText",description:"Type text into an input, textarea, or contenteditable element by its index. Replaces existing content. Works with React controlled components, contenteditable editors (LinkedIn, Quill), and native inputs.",parameters:{type:"object",properties:{index:{type:"number",description:"The element index from get_browser_state."},text:{type:"string",description:"The text to type into the element."}},required:["index","text"]}},selectOption.__schema__={name:"selectOption",description:"Select a dropdown option in a <select> element by its index and the visible option text.",parameters:{type:"object",properties:{index:{type:"number",description:"The <select> element index from get_browser_state."},option_text:{type:"string",description:"The visible text of the option to select (case-sensitive, trimmed)."}},required:["index","option_text"]}},scroll.__schema__={name:"scroll",description:"Scroll the page or a specific scrollable container. If index is provided, scrolls the nearest scrollable ancestor of that element. Otherwise scrolls the page or the largest scrollable container.",parameters:{type:"object",properties:{direction:{type:"string",enum:["up","down","left","right"],description:"Scroll direction."},amount:{type:"number",description:"Scroll amount in pixels. Default: ~80% of viewport height (vertical) or width (horizontal)."},index:{type:"number",description:"Optional element index. If provided, scrolls the nearest scrollable ancestor of this element."}},required:["direction"]}},removeHighlights.__schema__={name:"removeHighlights",description:"Remove all visual element index labels/highlights from the page. Useful after taking a screenshot if you want a clean view.",parameters:{type:"object",properties:{}}};const STORAGE_KEY="__hypha_debugger_config__";class HyphaDebugger{constructor(e){this.overlay=null,this.cursor=null,this.server=null,this.serviceInfo=null,this.boundBeforeUnload=null,this.cleanupInterceptor=null;const t=e.require_token??!1;let n=e.service_id??"web-debugger";e.service_id||(n=`web-debugger-${randomHex(16)}`);const r=e.visibility??(t?"protected":"unlisted");this.config={server_url:e.server_url,workspace:e.workspace??"",token:e.token??"",service_id:n,service_name:e.service_name??"Web Debugger",show_ui:e.show_ui??!0,visibility:r,require_token:t}}async start(){installConsoleCapture();const e=window;if(e.__HYPHA_DEBUGGER__?.instance)return console.warn("[hypha-debugger] Already running, returning existing session."),e.__HYPHA_DEBUGGER__.session;this.config.show_ui&&(this.overlay=new DebugOverlay,this.overlay.setStatus("disconnected"),this.overlay.setInfo({Status:"Connecting..."}),this.cursor=new AICursor);try{const t=this.getConnectToServer(),n={server_url:this.config.server_url};this.config.workspace&&(n.workspace=this.config.workspace),this.config.token&&(n.token=this.config.token);try{this.server=await t(n)}catch(e){if(!this.config.workspace)throw e;console.warn(`[hypha-debugger] Failed to rejoin workspace "${this.config.workspace}", getting a fresh one:`,e.message??e),this.server=await t({server_url:this.config.server_url})}this.serviceInfo=await this.server.registerService(this.buildServiceDefinition());const r=await this.updateSession();return this.overlay&&this.overlay.addLog("Service registered","result"),e.__HYPHA_DEBUGGER__=e.__HYPHA_DEBUGGER__??{},e.__HYPHA_DEBUGGER__.instance=this,this.saveConfigToStorage(),this.boundBeforeUnload=()=>this.saveConfigToStorage(),window.addEventListener("beforeunload",this.boundBeforeUnload),this.cleanupInterceptor=installNavigationInterceptor(),r}catch(e){throw console.error("[hypha-debugger] Failed to start:",e),this.overlay&&(this.overlay.setStatus("error"),this.overlay.setInfo({Status:"Error",Error:e.message??String(e)})),e}}async destroy(){this.boundBeforeUnload&&(window.removeEventListener("beforeunload",this.boundBeforeUnload),this.boundBeforeUnload=null),this.cleanupInterceptor&&(this.cleanupInterceptor(),this.cleanupInterceptor=null);try{this.serviceInfo&&this.server&&await this.server.unregisterService(this.serviceInfo.id)}catch{}try{sessionStorage.removeItem(STORAGE_KEY)}catch{}disposeController(),this.cursor?.destroy(),this.cursor=null,this.overlay?.destroy(),this.overlay=null;const e=window;e.__HYPHA_DEBUGGER__&&(delete e.__HYPHA_DEBUGGER__.instance,delete e.__HYPHA_DEBUGGER__.session)}saveConfigToStorage(){try{const e={server_url:this.config.server_url,workspace:this.server?.config?.workspace??this.config.workspace,service_id:this.config.service_id,service_name:this.config.service_name,show_ui:this.config.show_ui,visibility:this.config.visibility,require_token:this.config.require_token,script_url:this.detectScriptUrl()};sessionStorage.setItem(STORAGE_KEY,JSON.stringify(e))}catch{}}detectScriptUrl(){try{const e=document.querySelectorAll("script[src]");for(const t of Array.from(e))if(t.src&&t.src.includes("hypha-debugger"))return t.src}catch{}return"https://cdn.jsdelivr.net/npm/hypha-debugger/dist/hypha-debugger.min.js"}async updateSession(e){const t=this.serviceInfo?.id??this.config.service_id,n=this.buildServiceUrl(t),r=this.server.config?.workspace??"",o=this.config.require_token?await this.server.generateToken({expires_in:86400}):"";this.overlay&&(this.overlay.setStatus("connected"),this.overlay.setInfo({Status:"Connected",Server:this.config.server_url,...e}),this.overlay.setInstructions(this.buildInstructionBlock(n,o))),console.log(`[hypha-debugger] Service URL: ${n}`),o?(console.log(`[hypha-debugger] Token: ${o}`),console.log(`[hypha-debugger] Test:\n curl '${n}/get_page_info' -H 'Authorization: Bearer ${o}'`)):console.log(`[hypha-debugger] Test:\n curl '${n}/get_page_info'`);const i={service_id:t,workspace:r,server:this.server,service_url:n,token:o,destroy:()=>this.destroy()},s=window;return s.__HYPHA_DEBUGGER__=s.__HYPHA_DEBUGGER__??{},s.__HYPHA_DEBUGGER__.session=i,i}buildServiceUrl(e){const t=this.config.server_url.replace(/\/+$/,""),n=e.indexOf("/");if(-1!==n){const r=e.substring(0,n),o=e.substring(n+1),i=o.indexOf(":");return`${t}/${r}/services/${-1!==i?o.substring(i+1):o}`}return`${t}/services/${e}`}getHyphaModule(){if(__webpack_exports__connectToServer)return hyphaRpc;if(__webpack_exports__connectToServer)return hyphaRpcWebsocket;const e=window;if(e.hyphaWebsocketClient?.connectToServer)return e.hyphaWebsocketClient;throw new Error('hypha-rpc not found. Install it via npm or load it via: <script src="https://cdn.jsdelivr.net/npm/hypha-rpc@0.20.97/dist/hypha-rpc-websocket.min.js"><\/script>')}getConnectToServer(){return this.getHyphaModule().connectToServer}buildServiceDefinition(){return{id:this.config.service_id,name:this.config.service_name,type:"debugger",description:"Remote web page debugger. Allows inspecting DOM, taking screenshots, executing JavaScript, and interacting with the page.",config:{visibility:this.config.visibility},get_page_info:this.wrapFn(getPageInfo,"get_page_info"),get_html:this.wrapFn(getHtml,"get_html"),query_dom:this.wrapFn(queryDom,"query_dom"),click_element:this.wrapFn(clickElement$1,"click_element"),fill_input:this.wrapFn(fillInput,"fill_input"),scroll_to:this.wrapFn(scrollTo,"scroll_to"),take_screenshot:this.wrapFn(takeScreenshot,"take_screenshot"),execute_script:this.wrapFn(executeScript,"execute_script"),navigate:this.wrapFn(navigate,"navigate"),get_react_tree:this.wrapFn(getReactTree,"get_react_tree"),get_browser_state:this.wrapFn(getBrowserState,"get_browser_state"),click_element_by_index:this.wrapFn(clickElementByIndex,"click_element_by_index"),input_text:this.wrapFn(inputText,"input_text"),select_option:this.wrapFn(selectOption,"select_option"),scroll:this.wrapFn(scroll,"scroll"),remove_highlights:this.wrapFn(removeHighlights,"remove_highlights"),get_skill_md:this.wrapFn(this.createGetSkillMd(),"get_skill_md")}}createGetSkillMd(){const e=()=>{const e={},t={get_page_info:getPageInfo,get_html:getHtml,query_dom:queryDom,click_element:clickElement$1,fill_input:fillInput,scroll_to:scrollTo,take_screenshot:takeScreenshot,execute_script:executeScript,navigate:navigate,get_react_tree:getReactTree,get_browser_state:getBrowserState,click_element_by_index:clickElementByIndex,input_text:inputText,select_option:selectOption,scroll:scroll,remove_highlights:removeHighlights};for(const[n,r]of Object.entries(t))r.__schema__&&(e[n]=r);return!this.serviceInfo||this.buildServiceUrl(this.serviceInfo.id??this.config.service_id),generateSkillMd(e)};return e.__schema__={name:"getSkillMd",description:"Get the SKILL.md document describing all available debugger functions, their parameters, and usage examples. Follows the agentskills.io specification.",parameters:{type:"object",properties:{}}},e}buildInstructionBlock(e,t){const n=t?' -H "Authorization: Bearer $TOKEN"':"",r=["# Hypha Remote Debugger — Web Page","# A debugger is attached to a live web page.","# You can remotely inspect, interact with, and control this page via the HTTP API below.","#","# RECOMMENDED WORKFLOW (index-based, most reliable):","# 1. get_browser_state → see all interactive elements as [0], [1], [2], ...","# 2. click_element_by_index / input_text / select_option / scroll → act by index","# 3. take_screenshot → verify the result visually","#","# Also available: get_page_info, get_html, query_dom, click_element, fill_input,","# scroll_to, execute_script, navigate, get_react_tree, remove_highlights","#","# POST endpoints accept JSON body with parameter names as keys.","",`SERVICE_URL="${e}"`];return t&&r.push(`TOKEN="${t}"`),r.push("","# 1. Get interactive elements (smart DOM analysis with indexed elements):",`curl "$SERVICE_URL/get_browser_state"${n}`,"","# 2. Click element by index (e.g. click [3]):",`curl -X POST "$SERVICE_URL/click_element_by_index"${n} -H "Content-Type: application/json" -d '{"index": 3}'`,"","# 3. Type into an input by index:",`curl -X POST "$SERVICE_URL/input_text"${n} -H "Content-Type: application/json" -d '{"index": 5, "text": "hello"}'`,"","# Take a screenshot:",`curl "$SERVICE_URL/take_screenshot"${n}`,"","# Execute JavaScript remotely:",`curl -X POST "$SERVICE_URL/execute_script"${n} -H "Content-Type: application/json" -d '{"code": "document.title"}'`,"","# Full API docs:",`curl "$SERVICE_URL/get_skill_md"${n}`),r.join("\n")}wrapFn(e,t){const n=this,r=async(...r)=>{n.overlay?.addLog(`${t}(${n.summarizeArgs(r)})`,"call");try{const o=await e(...r);return o&&"object"==typeof o&&"error"in o?n.overlay?.addLog(`${t}: ${o.error}`,"error"):n.overlay?.addLog(`${t} -> OK`,"result"),o}catch(e){throw n.overlay?.addLog(`${t}: ${e.message}`,"error"),e}};return e.__schema__&&(r.__schema__=e.__schema__),wrapFn(r)}summarizeArgs(e){return 0===e.length?"":e.map(e=>"string"==typeof e?e.length>40?e.slice(0,40)+"...":e:"object"==typeof e&&null!==e?"{...}":String(e)).join(", ")}}async function startDebugger(e){return new HyphaDebugger(e).start()}function autoStart(){if("undefined"==typeof window||"undefined"==typeof document)return;if(window.__HYPHA_DEBUGGER__?.instance)return;try{const e=sessionStorage.getItem("__hypha_debugger_config__");if(e){const t=JSON.parse(e);if(t.server_url)return console.log("[hypha-debugger] Reconnecting from saved session..."),void startDebugger(t).catch(e=>{console.error("[hypha-debugger] Auto-reconnect failed:",e)})}}catch{}const e=document.querySelectorAll("script[src]");let t=null;for(const n of Array.from(e))if(n.src&&n.src.includes("hypha-debugger")){t=n;break}if(t?.hasAttribute("data-manual"))return;const n={server_url:t?.getAttribute("data-server-url")??"https://hypha.aicell.io"};t?.getAttribute("data-workspace")&&(n.workspace=t.getAttribute("data-workspace")),t?.getAttribute("data-token")&&(n.token=t.getAttribute("data-token")),t?.getAttribute("data-service-id")&&(n.service_id=t.getAttribute("data-service-id")),t?.hasAttribute("data-no-ui")&&(n.show_ui=!1),t?.hasAttribute("data-require-token")&&(n.require_token=!0),startDebugger(n).catch(e=>{console.error("[hypha-debugger] Auto-start failed:",e)})}"undefined"!=typeof window&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",autoStart):autoStart()),exports.AICursor=AICursor,exports.HyphaDebugger=HyphaDebugger,exports.PageController=PageController,exports.clickElement=clickElement$1,exports.clickElementByIndex=clickElementByIndex,exports.disposeController=disposeController,exports.executeScript=executeScript,exports.fillInput=fillInput,exports.generateSkillMd=generateSkillMd,exports.getBrowserState=getBrowserState,exports.getComputedStyles=getComputedStyles,exports.getConsoleLogs=getConsoleLogs,exports.getElementBounds=getElementBounds,exports.getHtml=getHtml,exports.getPageInfo=getPageInfo,exports.getReactTree=getReactTree,exports.goBack=goBack,exports.goForward=goForward,exports.inputText=inputText,exports.installConsoleCapture=installConsoleCapture,exports.installNavigationInterceptor=installNavigationInterceptor,exports.navigate=navigate,exports.queryDom=queryDom,exports.reload=reload,exports.removeHighlights=removeHighlights,exports.scroll=scroll,exports.scrollTo=scrollTo,exports.selectOption=selectOption,exports.softReplace=softReplace,exports.startDebugger=startDebugger,exports.takeScreenshot=takeScreenshot,exports.wrapFn=wrapFn});
|
|
59
59
|
//# sourceMappingURL=hypha-debugger.min.js.map
|