@mochabug/adapt-web 1.0.1-rc.15 → 1.0.1-rc.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -436,6 +436,16 @@ All three approaches compose — use `theme` for colors, CSS variables for fine-
436
436
  | `--mb-adapt-cap-spinner-thickness` | `3px` | |
437
437
  | `--mb-adapt-cap-font` | `inherit` | |
438
438
 
439
+ ### Z-index / stacking
440
+
441
+ | Variable | Default | Description |
442
+ |---|---|---|
443
+ | `--mb-adapt-z-base` | `0` | Base z-index offset — added to all internal z-index values |
444
+
445
+ Set `--mb-adapt-z-base` to shift all internal z-index values. Useful when embedding inside modals or drawers that have their own stacking context. Example: `--mb-adapt-z-base: 10000` lifts all layers by 10000.
446
+
447
+ Internal stacking order from low to high: separators (1), resize handles (10), minimized tabs (100), floating panels (100000+), status/cap (200000), confirm dialog (300000), drop targets (999998), drag ghost (999999). All values are offset by `--mb-adapt-z-base`.
448
+
439
449
  </details>
440
450
 
441
451
  ---
package/dist/README.md CHANGED
@@ -6,7 +6,7 @@ Embed Adapt automations in any website.
6
6
  npm install @mochabug/adapt-web
7
7
  ```
8
8
 
9
- **CDN base:** `https://cdn.mochabug.com/adapt/web/1.0.1-rc.15/`
9
+ **CDN base:** `https://cdn.mochabug.com/adapt/web/1.0.1-rc.17/`
10
10
 
11
11
  | Bundle | File | Includes |
12
12
  |--------|------|----------|
@@ -20,8 +20,8 @@ npm install @mochabug/adapt-web
20
20
  Bundles merge into a single `MbAdapt` global, so you can combine them. For example, headless + Cap for automations that need proof-of-work but no UI:
21
21
 
22
22
  ```html
23
- <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.15/adapt-core.min.js"></script>
24
- <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.15/adapt-web.cap.min.js"></script>
23
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.17/adapt-core.min.js"></script>
24
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.17/adapt-web.cap.min.js"></script>
25
25
  <script>
26
26
  // MbAdapt has exports from both scripts
27
27
  var client = MbAdapt.createAdaptClient(
@@ -43,12 +43,12 @@ Preload the script and load the stylesheet in `<head>` to eliminate flash of uns
43
43
 
44
44
  ```html
45
45
  <head>
46
- <link rel="preload" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.15/adapt-web.min.js" as="script">
47
- <link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.15/styles.css">
46
+ <link rel="preload" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.17/adapt-web.min.js" as="script">
47
+ <link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.17/styles.css">
48
48
  </head>
49
49
  <body>
50
50
  <adapt-automation automation-id="YOUR_ID" requires-challenge style="height: 600px"></adapt-automation>
51
- <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.15/adapt-web.min.js"></script>
51
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.17/adapt-web.min.js"></script>
52
52
  </body>
53
53
  ```
54
54
 
@@ -56,12 +56,12 @@ No challenges? Use the core bundle and drop `requires-challenge`:
56
56
 
57
57
  ```html
58
58
  <head>
59
- <link rel="preload" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.15/adapt-web.core.min.js" as="script">
60
- <link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.15/styles.css">
59
+ <link rel="preload" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.17/adapt-web.core.min.js" as="script">
60
+ <link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.17/styles.css">
61
61
  </head>
62
62
  <body>
63
63
  <adapt-automation automation-id="YOUR_ID" style="height: 600px"></adapt-automation>
64
- <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.15/adapt-web.core.min.js"></script>
64
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.17/adapt-web.core.min.js"></script>
65
65
  </body>
66
66
  ```
67
67
 
@@ -71,14 +71,14 @@ Just the element and script. CSS is auto-injected at runtime.
71
71
 
72
72
  ```html
73
73
  <adapt-automation automation-id="YOUR_ID" requires-challenge style="height: 600px"></adapt-automation>
74
- <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.15/adapt-web.min.js"></script>
74
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.17/adapt-web.min.js"></script>
75
75
  ```
76
76
 
77
77
  Without challenges:
78
78
 
79
79
  ```html
80
80
  <adapt-automation automation-id="YOUR_ID" style="height: 600px"></adapt-automation>
81
- <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.15/adapt-web.core.min.js"></script>
81
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.17/adapt-web.core.min.js"></script>
82
82
  ```
83
83
 
84
84
  ### ESM
@@ -160,12 +160,12 @@ Requires a `client` JS property — set it after the element is in the DOM.
160
160
 
161
161
  ```html
162
162
  <head>
163
- <link rel="preload" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.15/adapt-web.cap.min.js" as="script">
164
- <link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.15/styles.css">
163
+ <link rel="preload" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.17/adapt-web.cap.min.js" as="script">
164
+ <link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.17/styles.css">
165
165
  </head>
166
166
  <body>
167
167
  <adapt-cap automation-id="YOUR_ID"></adapt-cap>
168
- <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.15/adapt-web.cap.min.js"></script>
168
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.17/adapt-web.cap.min.js"></script>
169
169
  <script>
170
170
  var el = document.querySelector('adapt-cap');
171
171
  el.client = MbAdapt.createConnectClient({ id: 'YOUR_ID' });
@@ -180,7 +180,7 @@ Requires a `client` JS property — set it after the element is in the DOM.
180
180
 
181
181
  ```html
182
182
  <adapt-cap automation-id="YOUR_ID"></adapt-cap>
183
- <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.15/adapt-web.cap.min.js"></script>
183
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.17/adapt-web.cap.min.js"></script>
184
184
  <script>
185
185
  var el = document.querySelector('adapt-cap');
186
186
  el.client = MbAdapt.createConnectClient({ id: 'YOUR_ID' });
@@ -436,6 +436,16 @@ All three approaches compose — use `theme` for colors, CSS variables for fine-
436
436
  | `--mb-adapt-cap-spinner-thickness` | `3px` | |
437
437
  | `--mb-adapt-cap-font` | `inherit` | |
438
438
 
439
+ ### Z-index / stacking
440
+
441
+ | Variable | Default | Description |
442
+ |---|---|---|
443
+ | `--mb-adapt-z-base` | `0` | Base z-index offset — added to all internal z-index values |
444
+
445
+ Set `--mb-adapt-z-base` to shift all internal z-index values. Useful when embedding inside modals or drawers that have their own stacking context. Example: `--mb-adapt-z-base: 10000` lifts all layers by 10000.
446
+
447
+ Internal stacking order from low to high: separators (1), resize handles (10), minimized tabs (100), floating panels (100000+), status/cap (200000), confirm dialog (300000), drop targets (999998), drag ghost (999999). All values are offset by `--mb-adapt-z-base`.
448
+
439
449
  </details>
440
450
 
441
451
  ---
@@ -1 +1 @@
1
- import{AdaptWebClient}from"./index.js";const OBSERVED_ATTRIBUTES=["automation-id","session-token","auth-token","transmitter","challenge-token","requires-challenge","inherit-token","fork-display-mode","side-by-side-split","dark-mode","auto-resizing","allow-floating","allow-docking","allow-dialog-docking","allow-minimize","allow-maximize","floating-auto-resize","confirm-on-close","persist"],BaseElement=typeof HTMLElement<"u"?HTMLElement:class{};class AdaptAutomationElement extends BaseElement{constructor(){super();this._client=null}static get observedAttributes(){return OBSERVED_ATTRIBUTES}get theme(){return this._theme}set theme(v){this._theme=v,this._client?.setTheme(v)}get automationId(){return this.getAttribute("automation-id")}set automationId(v){v===null?this.removeAttribute("automation-id"):this.setAttribute("automation-id",v)}get darkMode(){return this.hasAttribute("dark-mode")}set darkMode(v){v?this.setAttribute("dark-mode",""):this.removeAttribute("dark-mode")}get autoResizing(){return this.hasAttribute("auto-resizing")}set autoResizing(v){v?this.setAttribute("auto-resizing",""):this.removeAttribute("auto-resizing")}get allowFloating(){return!this.hasAttribute("allow-floating")||this.getAttribute("allow-floating")!=="false"}set allowFloating(v){v?this.removeAttribute("allow-floating"):this.setAttribute("allow-floating","false")}get allowDocking(){return!this.hasAttribute("allow-docking")||this.getAttribute("allow-docking")!=="false"}set allowDocking(v){v?this.removeAttribute("allow-docking"):this.setAttribute("allow-docking","false")}get allowDialogDocking(){return!this.hasAttribute("allow-dialog-docking")||this.getAttribute("allow-dialog-docking")!=="false"}set allowDialogDocking(v){v?this.removeAttribute("allow-dialog-docking"):this.setAttribute("allow-dialog-docking","false")}get allowMinimize(){return!this.hasAttribute("allow-minimize")||this.getAttribute("allow-minimize")!=="false"}set allowMinimize(v){v?this.removeAttribute("allow-minimize"):this.setAttribute("allow-minimize","false")}get allowMaximize(){return!this.hasAttribute("allow-maximize")||this.getAttribute("allow-maximize")!=="false"}set allowMaximize(v){v?this.removeAttribute("allow-maximize"):this.setAttribute("allow-maximize","false")}get floatingAutoResize(){return this.hasAttribute("floating-auto-resize")}set floatingAutoResize(v){v?this.setAttribute("floating-auto-resize",""):this.removeAttribute("floating-auto-resize")}get confirmOnClose(){return this.hasAttribute("confirm-on-close")}set confirmOnClose(v){v?this.setAttribute("confirm-on-close",""):this.removeAttribute("confirm-on-close")}get forkDisplayMode(){return this.getAttribute("fork-display-mode")==="dialog"?"dialog":"side-by-side"}set forkDisplayMode(v){this.setAttribute("fork-display-mode",v)}get persist(){return this.hasAttribute("persist")}set persist(v){v?this.setAttribute("persist",""):this.removeAttribute("persist")}async newSession(){this._client&&await this._client.newSession()}connectedCallback(){queueMicrotask(()=>this._tryInit())}disconnectedCallback(){this._destroyClient()}attributeChangedCallback(name,oldValue,newValue){if(oldValue!==newValue){if(name==="automation-id"||name==="persist"){this._destroyClient(),queueMicrotask(()=>this._tryInit());return}if(this._client)switch(name){case"fork-display-mode":this._client.setForkDisplayMode(this.forkDisplayMode);break;case"dark-mode":this._client.setDarkMode(this.darkMode);break;case"auto-resizing":this._client.setAutoResizing(this.autoResizing);break;case"allow-floating":this._client.setAllowFloating(this.allowFloating);break;case"allow-docking":this._client.setAllowDocking(this.allowDocking);break;case"allow-dialog-docking":this._client.setAllowDialogDocking(this.allowDialogDocking);break;case"allow-minimize":this._client.setAllowMinimize(this.allowMinimize);break;case"allow-maximize":this._client.setAllowMaximize(this.allowMaximize);break;case"floating-auto-resize":this._client.setFloatingAutoResize(this.floatingAutoResize);break;case"confirm-on-close":this._client.setConfirmOnClose(this.confirmOnClose);break}}}_tryInit(){if(this._client||!this.isConnected)return;const automationId=this.automationId;if(!automationId)return;const sessionToken=this.getAttribute("session-token"),authToken=this.getAttribute("auth-token"),transmitter=this.getAttribute("transmitter"),challengeToken=this.getAttribute("challenge-token"),requiresChallenge=this.hasAttribute("requires-challenge"),inheritToken=this.getAttribute("inherit-token"),sideBySideSplitAttr=this.getAttribute("side-by-side-split");let forkDisplay;this.forkDisplayMode==="dialog"?forkDisplay={mode:"dialog"}:forkDisplay={mode:"side-by-side",...sideBySideSplitAttr!==null&&{split:Number(sideBySideSplitAttr)}};const options={container:this,automationId,forkDisplay,darkMode:this.darkMode,autoResizing:this.autoResizing,onSession:(status,fork)=>{this.onSessionCallback?.(status,fork),this.dispatchEvent(new CustomEvent("adapt-session",{detail:{status,fork},bubbles:!0}))},onOutput:output=>{this.onOutputCallback?.(output),this.dispatchEvent(new CustomEvent("adapt-output",{detail:{output},bubbles:!0}))},onForkActive:active=>{this.onForkActiveCallback?.(active),this.dispatchEvent(new CustomEvent("adapt-fork-active",{detail:{active},bubbles:!0}))}};this.allowFloating||(options.allowFloating=!1),this.allowDocking||(options.allowDocking=!1),this.allowDialogDocking||(options.allowDialogDocking=!1),this.allowMinimize||(options.allowMinimize=!1),this.allowMaximize||(options.allowMaximize=!1),this.floatingAutoResize&&(options.floatingAutoResize=!0),this.confirmOnClose&&(options.confirmOnClose=!0),sessionToken&&(options.sessionToken=sessionToken),authToken&&(options.authToken=authToken),transmitter&&(options.transmitter=transmitter),challengeToken&&(options.challengeToken=challengeToken),requiresChallenge&&(options.requiresChallenge=!0),inheritToken&&(options.inheritToken=inheritToken),this.signals!==void 0&&(options.signals=this.signals),this.capWidgetOptions!==void 0&&(options.capWidgetOptions=this.capWidgetOptions),this.inheritFrom!==void 0&&(options.inheritFrom=this.inheritFrom),this.classNames!==void 0&&(options.classNames=this.classNames),this.styles!==void 0&&(options.styles=this.styles),this.text!==void 0&&(options.text=this.text),this._theme!==void 0&&(options.theme=this._theme),this.persistOptions!==void 0?options.persist=this.persistOptions:this.persist&&(options.persist=!0),this._client=new AdaptWebClient(options)}_destroyClient(){this._client&&(this._client.destroy(),this._client=null)}}if(typeof customElements<"u"&&!customElements.get("adapt-automation")){customElements.define("adapt-automation",AdaptAutomationElement);const styleId="adapt-element-display";if(!document.getElementById(styleId)){const s=document.createElement("style");s.id=styleId,s.textContent="adapt-automation, adapt-cap { display: block; }",document.head.appendChild(s)}}export{AdaptAutomationElement};
1
+ import{AdaptWebClient}from"./index.js";const OBSERVED_ATTRIBUTES=["automation-id","session-token","auth-token","transmitter","challenge-token","requires-challenge","inherit-token","fork-display-mode","side-by-side-split","dark-mode","auto-resizing","allow-floating","allow-docking","allow-dialog-docking","allow-minimize","allow-maximize","floating-auto-resize","confirm-on-close","persist"],BaseElement=typeof HTMLElement<"u"?HTMLElement:class{};class AdaptAutomationElement extends BaseElement{constructor(){super();this._client=null}static get observedAttributes(){return OBSERVED_ATTRIBUTES}get theme(){return this._theme}set theme(v){this._theme=v,this._client?.setTheme(v)}get automationId(){return this.getAttribute("automation-id")}set automationId(v){v===null?this.removeAttribute("automation-id"):this.setAttribute("automation-id",v)}get darkMode(){return this.hasAttribute("dark-mode")}set darkMode(v){v?this.setAttribute("dark-mode",""):this.removeAttribute("dark-mode")}get autoResizing(){return this.hasAttribute("auto-resizing")}set autoResizing(v){v?this.setAttribute("auto-resizing",""):this.removeAttribute("auto-resizing")}get allowFloating(){return!this.hasAttribute("allow-floating")||this.getAttribute("allow-floating")!=="false"}set allowFloating(v){v?this.removeAttribute("allow-floating"):this.setAttribute("allow-floating","false")}get allowDocking(){return!this.hasAttribute("allow-docking")||this.getAttribute("allow-docking")!=="false"}set allowDocking(v){v?this.removeAttribute("allow-docking"):this.setAttribute("allow-docking","false")}get allowDialogDocking(){return!this.hasAttribute("allow-dialog-docking")||this.getAttribute("allow-dialog-docking")!=="false"}set allowDialogDocking(v){v?this.removeAttribute("allow-dialog-docking"):this.setAttribute("allow-dialog-docking","false")}get allowMinimize(){return!this.hasAttribute("allow-minimize")||this.getAttribute("allow-minimize")!=="false"}set allowMinimize(v){v?this.removeAttribute("allow-minimize"):this.setAttribute("allow-minimize","false")}get allowMaximize(){return!this.hasAttribute("allow-maximize")||this.getAttribute("allow-maximize")!=="false"}set allowMaximize(v){v?this.removeAttribute("allow-maximize"):this.setAttribute("allow-maximize","false")}get floatingAutoResize(){return this.hasAttribute("floating-auto-resize")}set floatingAutoResize(v){v?this.setAttribute("floating-auto-resize",""):this.removeAttribute("floating-auto-resize")}get confirmOnClose(){return this.hasAttribute("confirm-on-close")}set confirmOnClose(v){v?this.setAttribute("confirm-on-close",""):this.removeAttribute("confirm-on-close")}get forkDisplayMode(){return this.getAttribute("fork-display-mode")==="dialog"?"dialog":"side-by-side"}set forkDisplayMode(v){this.setAttribute("fork-display-mode",v)}get persist(){return this.hasAttribute("persist")}set persist(v){v?this.setAttribute("persist",""):this.removeAttribute("persist")}async newSession(){this._client&&await this._client.newSession()}connectedCallback(){queueMicrotask(()=>this._tryInit())}disconnectedCallback(){this._destroyClient()}attributeChangedCallback(name,oldValue,newValue){if(oldValue!==newValue){if(name==="automation-id"||name==="persist"){this._destroyClient(),queueMicrotask(()=>this._tryInit());return}if(this._client)switch(name){case"fork-display-mode":this._client.setForkDisplayMode(this.forkDisplayMode);break;case"dark-mode":this._client.setDarkMode(this.darkMode);break;case"auto-resizing":this._client.setAutoResizing(this.autoResizing);break;case"allow-floating":this._client.setAllowFloating(this.allowFloating);break;case"allow-docking":this._client.setAllowDocking(this.allowDocking);break;case"allow-dialog-docking":this._client.setAllowDialogDocking(this.allowDialogDocking);break;case"allow-minimize":this._client.setAllowMinimize(this.allowMinimize);break;case"allow-maximize":this._client.setAllowMaximize(this.allowMaximize);break;case"floating-auto-resize":this._client.setFloatingAutoResize(this.floatingAutoResize);break;case"confirm-on-close":this._client.setConfirmOnClose(this.confirmOnClose);break}}}_tryInit(){if(this._client||!this.isConnected)return;const automationId=this.automationId;if(!automationId)return;const sessionToken=this.getAttribute("session-token"),authToken=this.getAttribute("auth-token"),transmitter=this.getAttribute("transmitter"),challengeToken=this.getAttribute("challenge-token"),requiresChallenge=this.hasAttribute("requires-challenge"),inheritToken=this.getAttribute("inherit-token"),sideBySideSplitAttr=this.getAttribute("side-by-side-split");let forkDisplay;this.forkDisplayMode==="dialog"?forkDisplay={mode:"dialog"}:forkDisplay={mode:"side-by-side",...sideBySideSplitAttr!==null&&{split:Number(sideBySideSplitAttr)}};const options={container:this,automationId,forkDisplay,darkMode:this.darkMode,autoResizing:this.autoResizing,onSession:(status,fork)=>{this.onSessionCallback?.(status,fork),this.dispatchEvent(new CustomEvent("adapt-session",{detail:{status,fork},bubbles:!0}))},onOutput:output=>{this.onOutputCallback?.(output),this.dispatchEvent(new CustomEvent("adapt-output",{detail:{output},bubbles:!0}))},onForkActive:active=>{this.onForkActiveCallback?.(active),this.dispatchEvent(new CustomEvent("adapt-fork-active",{detail:{active},bubbles:!0}))},onError:error=>{this.onErrorCallback?.(error),this.dispatchEvent(new CustomEvent("adapt-error",{detail:{error},bubbles:!0}))}};this.allowFloating||(options.allowFloating=!1),this.allowDocking||(options.allowDocking=!1),this.allowDialogDocking||(options.allowDialogDocking=!1),this.allowMinimize||(options.allowMinimize=!1),this.allowMaximize||(options.allowMaximize=!1),this.floatingAutoResize&&(options.floatingAutoResize=!0),this.confirmOnClose&&(options.confirmOnClose=!0),sessionToken&&(options.sessionToken=sessionToken),authToken&&(options.authToken=authToken),transmitter&&(options.transmitter=transmitter),challengeToken&&(options.challengeToken=challengeToken),requiresChallenge&&(options.requiresChallenge=!0),inheritToken&&(options.inheritToken=inheritToken),this.signals!==void 0&&(options.signals=this.signals),this.capWidgetOptions!==void 0&&(options.capWidgetOptions=this.capWidgetOptions),this.inheritFrom!==void 0&&(options.inheritFrom=this.inheritFrom),this.classNames!==void 0&&(options.classNames=this.classNames),this.styles!==void 0&&(options.styles=this.styles),this.text!==void 0&&(options.text=this.text),this._theme!==void 0&&(options.theme=this._theme),this.persistOptions!==void 0?options.persist=this.persistOptions:this.persist&&(options.persist=!0),this._client=new AdaptWebClient(options)}_destroyClient(){this._client&&(this._client.destroy(),this._client=null)}}if(typeof customElements<"u"&&!customElements.get("adapt-automation")){customElements.define("adapt-automation",AdaptAutomationElement);const styleId="adapt-element-display";if(!document.getElementById(styleId)){const s=document.createElement("style");s.id=styleId,s.textContent="adapt-automation, adapt-cap { display: block; }",document.head.appendChild(s)}}export{AdaptAutomationElement};
@@ -1 +1 @@
1
- typeof window<"u"&&!window.CAP_CUSTOM_WASM_URL&&(window.CAP_CUSTOM_WASM_URL=new URL("https://cdn.mochabug.com/adapt/web/1.0.1-rc.15/cap_wasm.js",window.location.href).href);import{timestampDate}from"@bufbuild/protobuf/wkt";let currentClient=null,currentAutomationId=null;const verificationTokens=new Map;async function createChallenge(client,id){const response=await client.createChallenge({id});return{count:response.count,size:response.size,difficulty:response.difficulty,expires:response.expires?timestampDate(response.expires):new Date,token:response.token,verificationToken:response.verificationToken}}async function redeemChallenge(client,id,verificationToken,solutions){const response=await client.redeemChallenge({id,verificationToken,solutions});return{token:response.token,expires:response.expires?timestampDate(response.expires):new Date}}typeof window<"u"&&(window.CAP_CUSTOM_FETCH=async(url,options)=>{const urlStr=url.toString();if(urlStr.endsWith("/challenge")){if(!currentClient||!currentAutomationId)return new Response(JSON.stringify({error:"Cap adapter not initialized"}),{status:500,headers:{"Content-Type":"application/json"}});try{const challengeInfo=await createChallenge(currentClient,currentAutomationId);return verificationTokens.set(currentAutomationId,challengeInfo.verificationToken),new Response(JSON.stringify({challenge:{c:challengeInfo.count,s:challengeInfo.size,d:challengeInfo.difficulty},token:challengeInfo.token,expires:challengeInfo.expires.toISOString()}),{status:200,headers:{"Content-Type":"application/json"}})}catch(error){return new Response(JSON.stringify({error:String(error)}),{status:500,headers:{"Content-Type":"application/json"}})}}if(urlStr.endsWith("/redeem")){if(!currentClient||!currentAutomationId)return new Response(JSON.stringify({error:"Cap adapter not initialized"}),{status:500,headers:{"Content-Type":"application/json"}});const verificationToken=verificationTokens.get(currentAutomationId);if(!verificationToken)return new Response(JSON.stringify({error:"No verification token found - challenge must be created first"}),{status:400,headers:{"Content-Type":"application/json"}});try{const solutions=((options?.body?JSON.parse(options.body):{}).solutions||[]).map(s=>BigInt(s)),redeemed=await redeemChallenge(currentClient,currentAutomationId,verificationToken,solutions);return verificationTokens.delete(currentAutomationId),new Response(JSON.stringify({success:!0,token:redeemed.token,expires:redeemed.expires.toISOString()}),{status:200,headers:{"Content-Type":"application/json"}})}catch(error){return new Response(JSON.stringify({error:String(error)}),{status:500,headers:{"Content-Type":"application/json"}})}}return fetch(url,options)});function setupCapAdapter(client,automationId){currentClient=client,currentAutomationId=automationId}function cleanupCapAdapter(){currentAutomationId&&verificationTokens.delete(currentAutomationId),currentClient=null,currentAutomationId=null}export{cleanupCapAdapter,createChallenge,redeemChallenge,setupCapAdapter};
1
+ typeof window<"u"&&!window.CAP_CUSTOM_WASM_URL&&(window.CAP_CUSTOM_WASM_URL=new URL("https://cdn.mochabug.com/adapt/web/1.0.1-rc.17/cap_wasm.js",window.location.href).href);import{timestampDate}from"@bufbuild/protobuf/wkt";let currentClient=null,currentAutomationId=null;const verificationTokens=new Map;async function createChallenge(client,id){const response=await client.createChallenge({id});return{count:response.count,size:response.size,difficulty:response.difficulty,expires:response.expires?timestampDate(response.expires):new Date,token:response.token,verificationToken:response.verificationToken}}async function redeemChallenge(client,id,verificationToken,solutions){const response=await client.redeemChallenge({id,verificationToken,solutions});return{token:response.token,expires:response.expires?timestampDate(response.expires):new Date}}typeof window<"u"&&(window.CAP_CUSTOM_FETCH=async(url,options)=>{const urlStr=url.toString();if(urlStr.endsWith("/challenge")){if(!currentClient||!currentAutomationId)return new Response(JSON.stringify({error:"Cap adapter not initialized"}),{status:500,headers:{"Content-Type":"application/json"}});try{const challengeInfo=await createChallenge(currentClient,currentAutomationId);return verificationTokens.set(currentAutomationId,challengeInfo.verificationToken),new Response(JSON.stringify({challenge:{c:challengeInfo.count,s:challengeInfo.size,d:challengeInfo.difficulty},token:challengeInfo.token,expires:challengeInfo.expires.toISOString()}),{status:200,headers:{"Content-Type":"application/json"}})}catch(error){return new Response(JSON.stringify({error:String(error)}),{status:500,headers:{"Content-Type":"application/json"}})}}if(urlStr.endsWith("/redeem")){if(!currentClient||!currentAutomationId)return new Response(JSON.stringify({error:"Cap adapter not initialized"}),{status:500,headers:{"Content-Type":"application/json"}});const verificationToken=verificationTokens.get(currentAutomationId);if(!verificationToken)return new Response(JSON.stringify({error:"No verification token found - challenge must be created first"}),{status:400,headers:{"Content-Type":"application/json"}});try{const solutions=((options?.body?JSON.parse(options.body):{}).solutions||[]).map(s=>BigInt(s)),redeemed=await redeemChallenge(currentClient,currentAutomationId,verificationToken,solutions);return verificationTokens.delete(currentAutomationId),new Response(JSON.stringify({success:!0,token:redeemed.token,expires:redeemed.expires.toISOString()}),{status:200,headers:{"Content-Type":"application/json"}})}catch(error){return new Response(JSON.stringify({error:String(error)}),{status:500,headers:{"Content-Type":"application/json"}})}}return fetch(url,options)});function setupCapAdapter(client,automationId){currentClient=client,currentAutomationId=automationId}function cleanupCapAdapter(){currentAutomationId&&verificationTokens.delete(currentAutomationId),currentClient=null,currentAutomationId=null}export{cleanupCapAdapter,createChallenge,redeemChallenge,setupCapAdapter};
@@ -31,6 +31,7 @@ const PANEL_MANAGER_CSS=`/* ====================================================
31
31
  --_status-text: var(--mb-adapt-status-text, #374151);
32
32
  --_drag-ghost-shadow: var(--mb-adapt-drag-ghost-shadow, 0 4px 12px rgba(0, 0, 0, 0.15));
33
33
  --_border-radius: var(--mb-adapt-border-radius, 8px);
34
+ --_z-base: var(--mb-adapt-z-base, 0);
34
35
  --mb-adapt-responsive-breakpoint: 768;
35
36
  --mb-adapt-responsive-hysteresis: 40;
36
37
 
@@ -165,7 +166,7 @@ const PANEL_MANAGER_CSS=`/* ====================================================
165
166
  background: var(--_fork-separator);
166
167
  transition: background 0.15s;
167
168
  position: relative;
168
- z-index: 1;
169
+ z-index: calc(1 + var(--_z-base));
169
170
  touch-action: none;
170
171
  }
171
172
 
@@ -349,7 +350,7 @@ const PANEL_MANAGER_CSS=`/* ====================================================
349
350
  /* \u2500\u2500 Floating overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
350
351
  .mb-floating-overlay {
351
352
  position: fixed;
352
- z-index: 100000;
353
+ z-index: calc(100000 + var(--_z-base));
353
354
  box-shadow: var(--_floating-shadow);
354
355
  border: var(--_floating-border);
355
356
  backdrop-filter: var(--_floating-backdrop);
@@ -400,7 +401,7 @@ const PANEL_MANAGER_CSS=`/* ====================================================
400
401
  /* \u2500\u2500 Resize handles \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
401
402
  .mb-resize-handle {
402
403
  position: absolute;
403
- z-index: 10;
404
+ z-index: calc(10 + var(--_z-base));
404
405
  touch-action: none;
405
406
  }
406
407
 
@@ -442,7 +443,7 @@ const PANEL_MANAGER_CSS=`/* ====================================================
442
443
  display: flex;
443
444
  align-items: center;
444
445
  justify-content: center;
445
- z-index: 200000;
446
+ z-index: calc(200000 + var(--_z-base));
446
447
  background: transparent;
447
448
  pointer-events: none;
448
449
  }
@@ -515,7 +516,7 @@ const PANEL_MANAGER_CSS=`/* ====================================================
515
516
  flex-direction: row;
516
517
  align-items: center;
517
518
  justify-content: center;
518
- z-index: 300000;
519
+ z-index: calc(300000 + var(--_z-base));
519
520
  background: rgba(0, 0, 0, 0.4);
520
521
  height: auto;
521
522
  min-height: 0;
@@ -592,7 +593,7 @@ const PANEL_MANAGER_CSS=`/* ====================================================
592
593
  align-items: center;
593
594
  justify-content: center;
594
595
  pointer-events: none;
595
- z-index: 200000;
596
+ z-index: calc(200000 + var(--_z-base));
596
597
  }
597
598
 
598
599
  .mb-adapt-cap > * {
@@ -664,7 +665,7 @@ cap-widget::part(attribution) {
664
665
  display: none;
665
666
  height: var(--_toolbar-height);
666
667
  flex-shrink: 0;
667
- z-index: 100;
668
+ z-index: calc(100 + var(--_z-base));
668
669
  align-items: stretch;
669
670
  background: var(--_fork-tab-bg);
670
671
  border-bottom: 1px solid var(--_fork-separator);
@@ -737,7 +738,7 @@ cap-widget::part(attribution) {
737
738
  .mb-drag-ghost {
738
739
  position: fixed;
739
740
  pointer-events: none;
740
- z-index: 999999;
741
+ z-index: calc(999999 + var(--_z-base));
741
742
  padding: 4px 10px;
742
743
  background: var(--_fork-tab-bg);
743
744
  color: var(--_fork-tab-color);
@@ -767,7 +768,7 @@ cap-widget::part(attribution) {
767
768
  .mb-drop-overlay {
768
769
  position: fixed;
769
770
  pointer-events: none;
770
- z-index: 999998;
771
+ z-index: calc(999998 + var(--_z-base));
771
772
  display: none;
772
773
  box-sizing: border-box;
773
774
  border-radius: 6px;
package/dist/esm/index.js CHANGED
@@ -1 +1 @@
1
- import{Code,configure,ConnectError,createAdaptClient,resetConfig}from"@mochabug/adapt-core";import{createConnectClient}from"@mochabug/adapt-core/connect";import{PanelManager}from"./panel-manager.js";import{FloatingToolbar,ForkGroupActions,IframePanelComponent,injectPanelManagerStyles,MinimizeManager}from"./panel-setup.js";import{resolveTheme}from"./theme.js";import{resolveTheme as resolveTheme2}from"./theme.js";import{AdaptAutomationElement}from"./AdaptAutomationElement.js";import{FloatingToolbar as FloatingToolbar2,ForkGroupActions as ForkGroupActions2,IframePanelComponent as IframePanelComponent2,MinimizeManager as MinimizeManager2}from"./panel-setup.js";import{PanelManager as PanelManager2}from"./panel-manager.js";function clearPersistedState(automationId,storage="both",persistKey){const key=`mb_adapt_${persistKey??automationId}`;(storage==="session"||storage==="both")&&sessionStorage.removeItem(key),(storage==="local"||storage==="both")&&localStorage.removeItem(key)}const MAIN_PANEL_ID="main",FORK_GROUP_ID="fork-group",DEFAULT_RESPONSIVE_BREAKPOINT=768,DEFAULT_RESPONSIVE_HYSTERESIS=40,_AdaptWebClient=class _AdaptWebClient{constructor(options){this.rootElement=null;this.panelManager=null;this.mainUrl=null;this.sessionToken=null;this.forks=new Map;this.mainRetentionPolicy="retain";this.mainCloseTimer=null;this.components=new Map;this.floatingAutoResized=new Set;this.beforeUnloadHandler=null;this.resizeObserver=null;this._autoMaximizedByResize=!1;this.destroyed=!1;this.removingPanelProgrammatically=!1;this.lastForkActive=null;this.messageHandler=null;this.minimizedTabsContainer=null;this.lastReportedContentHeight=0;this.forkPanelHeights=new Map;this.statusMessageElement=null;this.capWidgetInstance=null;this.minimizeManager=null;this.forkGroupActions=new Map;this.floatingToolbars=new Map;this.options=options;const fd=options.forkDisplay??{mode:"side-by-side"};this.forkDisplay=fd,this.darkMode=options.darkMode??!1,this.autoResizing=options.autoResizing??!1,this.allowFloating=options.allowFloating??!0,this.allowDocking=options.allowDocking??!0,this.allowDialogDocking=options.allowDialogDocking??!0,this.allowMinimize=options.allowMinimize??!0,this.allowMaximize=options.allowMaximize??!0,this.floatingAutoResize=options.floatingAutoResize??!1,this.confirmOnClose=options.confirmOnClose??!1,this.theme=options.theme;const container=typeof options.container=="string"?document.getElementById(options.container):options.container;if(!container)throw new Error(`Container with id '${options.container}' not found`);this.container=container;const rawClient=createConnectClient({id:options.automationId});this.client=createAdaptClient(rawClient,options.automationId),injectPanelManagerStyles(),this.createRootElement(),this.createPanelManager(),this.wireBeforeTabClose(),this.setupMessageListener(),this.init().catch(error=>{this.showErrorStatus(error)})}static registerCapWidget(cls){_AdaptWebClient._capWidgetClass=cls}get responsiveBreakpoint(){if(!this.rootElement)return DEFAULT_RESPONSIVE_BREAKPOINT;const v=getComputedStyle(this.rootElement).getPropertyValue("--mb-adapt-responsive-breakpoint").trim(),n=Number(v);return n>0?n:DEFAULT_RESPONSIVE_BREAKPOINT}get responsiveHysteresis(){if(!this.rootElement)return DEFAULT_RESPONSIVE_HYSTERESIS;const v=getComputedStyle(this.rootElement).getPropertyValue("--mb-adapt-responsive-hysteresis").trim(),n=Number(v);return n>=0?n:DEFAULT_RESPONSIVE_HYSTERESIS}onComponentCreated(panelId,component){this.components.set(panelId,component)}onComponentDisposed(panelId){this.components.delete(panelId)}getDarkMode(){return this.darkMode}getClassNames(){return this.options.classNames}createPanelManager(){if(!this.rootElement)return;this.minimizeManager=new MinimizeManager,this.minimizeManager.setAllowDocking(this.allowDocking),this.minimizedTabsContainer=document.createElement("div"),this.minimizedTabsContainer.className="mb-adapt-minimized-tabs",this.rootElement.appendChild(this.minimizedTabsContainer),this.panelManager=new PanelManager({container:this.rootElement,onGroupCreatedByDrag:group=>{group.dragConstraint="merge-only",this.allowDocking||(group.dockingBlocked=!0),this.allowDialogDocking||(group.dialogDockingBlocked=!0),this.setupForkGroupActions(group)}});const mainGroup=this.panelManager.addGroup({id:"main-group"});this.panelManager.setMainGroup(mainGroup),mainGroup.locked="no-drop-target",mainGroup.setHeaderHidden(!0),mainGroup.element.setAttribute("data-main-group","true");const mainComponent=new IframePanelComponent(this);mainComponent.init(MAIN_PANEL_ID,{}),this.panelManager.addPanel({id:MAIN_PANEL_ID,element:mainComponent.element,groupId:mainGroup.id}),this.minimizeManager.init(this.minimizedTabsContainer,this.panelManager),this.minimizeManager.onBarVisibilityChanged(()=>{this.reapplyAutoResizeHeight()}),this.resizeObserver=new ResizeObserver(entries=>{const cr=entries[0]?.contentRect;cr&&this.onContainerResize(cr.width,cr.height)}),this.resizeObserver.observe(this.rootElement)}getOrigin(url){try{return new URL(url).origin}catch{return null}}isValidMessageOrigin(origin){if(this.mainUrl){const mainOrigin=this.getOrigin(this.mainUrl);if(mainOrigin&&origin===mainOrigin)return!0}for(const fork of this.forks.values()){const forkOrigin=this.getOrigin(fork.url);if(forkOrigin&&origin===forkOrigin)return!0}return!1}findComponentBySource(source){for(const[panelId,component]of this.components)if(component.contentWindow===source)return{panelId,component};return null}setupMessageListener(){this.messageHandler=event=>{if(!this.isValidMessageOrigin(event.origin))return;const data=event.data;if(!data||typeof data!="object")return;const source=event.source,found=this.findComponentBySource(source);if(!found)return;const{panelId,component}=found,isMainPanel=panelId===MAIN_PANEL_ID;if(data.type==="adapt-init"&&typeof data.resize=="boolean"){component.resizeCapable=data.resize,isMainPanel&&!data.resize&&this.rootElement&&(this.rootElement.style.height="");const targetOrigin=component.getOrigin();if(targetOrigin){let effective;if(isMainPanel)effective=this.autoResizing&&data.resize;else{const group=this.panelManager?.getPanel(panelId)?.group,inFloating=group?!!this.panelManager?.findOverlayContaining(group.id):!1;effective=data.resize&&(inFloating&&this.floatingAutoResize||!inFloating&&this.autoResizing)}component.postMessage({type:"adapt-autoResizing",autoResizing:effective},targetOrigin),component.postMessage({type:"adapt-darkMode",darkMode:this.darkMode},targetOrigin)}return}if(data.type==="adapt-resize"){const{height}=data;if(typeof height!="number"||!Number.isFinite(height)||height<1)return;if(isMainPanel)this.lastReportedContentHeight=height,component.resizeCapable&&this.autoResizing&&this.rootElement&&this.applyBestAutoResizeHeight();else{this.forkPanelHeights.set(panelId,height);const group=this.panelManager?.getPanel(panelId)?.group;if(group&&group.activePanel?.id===panelId){const inFloating=!!this.panelManager?.findOverlayContaining(group.id);!inFloating&&component.resizeCapable&&this.autoResizing&&this.rootElement&&this.applyBestAutoResizeHeight(),inFloating&&this.floatingAutoResize&&(this.floatingAutoResized.has(group.id)||(this.floatingAutoResized.add(group.id),this.resizeOverlayForGroup(group)))}}return}},window.addEventListener("message",this.messageHandler)}postToComponent(component,message){const origin=component.getOrigin();origin&&component.postMessage(message,origin)}setDarkMode(darkMode){if(this.darkMode===darkMode)return;this.darkMode=darkMode,this.rootElement?.classList.toggle("mb-adapt--dark",darkMode),this.capWidgetInstance?.setDarkMode(darkMode),this.applyTheme();const msg={type:"adapt-darkMode",darkMode};for(const c of this.components.values())this.postToComponent(c,msg)}setTheme(theme){if(this.theme=theme,this.clearThemeVars(),theme?.mode!==void 0){const dark=theme.mode==="dark";if(this.darkMode!==dark){this.setDarkMode(dark);return}}this.applyTheme()}clearThemeVars(){if(!(!this.rootElement||!this._appliedThemeVars)){for(const key of this._appliedThemeVars)this.rootElement.style.removeProperty(key);this._appliedThemeVars=void 0}}applyTheme(){if(!this.rootElement||!this.theme)return;const vars=resolveTheme(this.theme);for(const[key,value]of Object.entries(vars))this.rootElement.style.setProperty(key,value);this._appliedThemeVars=Object.keys(vars)}setAutoResizing(autoResizing){if(this.autoResizing===autoResizing)return;this.autoResizing=autoResizing;const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent?.resizeCapable&&this.postToComponent(mainComponent,{type:"adapt-autoResizing",autoResizing});for(const[panelId,component]of this.components){if(panelId===MAIN_PANEL_ID||!component.resizeCapable)continue;const group=this.panelManager?.getPanel(panelId)?.group;group&&this.panelManager?.findOverlayContaining(group.id)||this.postToComponent(component,{type:"adapt-autoResizing",autoResizing})}!autoResizing&&this.rootElement&&(this.rootElement.style.height="")}setAllowFloating(allow){if(this.allowFloating!==allow){this.allowFloating=allow;for(const actions of this.forkGroupActions.values())actions.setAllowFloating(allow)}}setAllowDocking(allow){if(this.allowDocking!==allow){if(this.allowDocking=allow,this.minimizeManager?.setAllowDocking(allow),this.panelManager)for(const group of this.getAllForkGroups())group.dockingBlocked=!allow;for(const toolbar of this.floatingToolbars.values())toolbar.setAllowDocking(allow)}}setAllowDialogDocking(allow){if(this.allowDialogDocking!==allow&&(this.allowDialogDocking=allow,this.panelManager))for(const group of this.getAllForkGroups())group.dialogDockingBlocked=!allow}setAllowMinimize(allow){if(this.allowMinimize!==allow){this.allowMinimize=allow;for(const actions of this.forkGroupActions.values())actions.setAllowMinimize(allow);for(const toolbar of this.floatingToolbars.values())toolbar.setAllowMinimize(allow)}}setAllowMaximize(allow){if(this.allowMaximize!==allow){this.allowMaximize=allow;for(const actions of this.forkGroupActions.values())actions.setAllowMaximize(allow);for(const toolbar of this.floatingToolbars.values())toolbar.setAllowMaximize(allow)}}setFloatingAutoResize(enabled){if(this.floatingAutoResize!==enabled){this.floatingAutoResize=enabled,this.floatingAutoResized.clear();for(const[panelId,component]of this.components){if(panelId===MAIN_PANEL_ID||!component.resizeCapable)continue;const group=this.panelManager?.getPanel(panelId)?.group,effective=(group?!!this.panelManager?.findOverlayContaining(group.id):!1)?enabled&&component.resizeCapable:this.autoResizing&&component.resizeCapable;this.postToComponent(component,{type:"adapt-autoResizing",autoResizing:effective})}}}getAllForkGroups(){if(!this.panelManager)return[];const seen=new Set,groups=[],add=g=>{g.id==="main-group"||seen.has(g.id)||(seen.add(g.id),groups.push(g))},forkGroup=this.panelManager.getGroup(FORK_GROUP_ID);forkGroup&&add(forkGroup);for(const g of this.panelManager.getDockedGroups())add(g);for(const[,overlay]of this.panelManager.getFloatingOverlays())for(const g of overlay.getAllGroups())add(g);return groups}applyAutoResizeHeight(contentHeight){if(!this.rootElement)return;const chrome=this.minimizedTabsContainer?.offsetHeight??0;this.rootElement.style.height=`${Math.ceil(contentHeight)+chrome}px`}applyBestAutoResizeHeight(){if(!this.autoResizing||!this.rootElement)return;let maxHeight=0;if(this.components.get(MAIN_PANEL_ID)?.resizeCapable&&this.lastReportedContentHeight>0){const mainGroup=this.panelManager?.getMainGroup();if(mainGroup?mainGroup.element.offsetHeight>0:!0){const headerH=mainGroup?.headerElement?.offsetHeight??0;maxHeight=this.lastReportedContentHeight+headerH}}for(const group of this.getAllForkGroups()){if(this.panelManager?.findOverlayContaining(group.id)||group.element.offsetHeight<=0)continue;const active=group.activePanel;if(active){const h=this.forkPanelHeights.get(active.id)??0,headerH=group.headerElement?.offsetHeight??0,total=h+headerH;total>maxHeight&&(maxHeight=total)}}maxHeight>0&&this.applyAutoResizeHeight(maxHeight)}reapplyAutoResizeHeight(){this.applyBestAutoResizeHeight()}setForkDisplayMode(mode){this.forkDisplay.mode!==mode&&(mode==="side-by-side"?this.forkDisplay={mode:"side-by-side"}:this.forkDisplay={mode:"dialog"},this.forks.size>0&&this.panelManager&&this.rebuildForkGroup(),this.emitForkActive(),this.saveState())}createRootElement(){this.rootElement=document.createElement("div"),this.rootElement.className=this.options.classNames?.root||"mb-adapt",this.darkMode&&this.rootElement.classList.add("mb-adapt--dark"),this.options.styles&&Object.assign(this.rootElement.style,this.options.styles),this.applyTheme(),this.container.appendChild(this.rootElement)}onUrl(msg){if(this.destroyed)return;const fork=msg.fork||"";if(msg.stopped){this.handleStoppedMessage(fork),this.saveState();return}if(msg.done){this.handleDoneMessage(fork,msg.retentionPolicy),this.saveState();return}msg.url&&(fork?this.handleForkUrl(msg.url,msg.token,fork,msg.source,msg.retentionPolicy):this.handleMainUrl(msg.url,msg.token,msg.source,msg.retentionPolicy),this.saveState())}handleMainUrl(url,token,_source,retentionPolicy){this.mainCloseTimer&&(clearTimeout(this.mainCloseTimer),this.mainCloseTimer=null);const wasMainEmpty=!this.mainUrl;if(this.removeStatusMessage(),this.mainUrl=url,this.mainToken=token,this.mainRetentionPolicy=this.resolveRetention(retentionPolicy),this.panelManager?.isMainGroupCollapsed()&&this.panelManager.expandMainGroup(),wasMainEmpty){const maximizedGroupId=this.getMaximizedDockedGroupId();if(maximizedGroupId){const actions=this.forkGroupActions.get(maximizedGroupId);actions&&actions.clearMaximized()}}const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&(mainComponent.update({url,token}),mainComponent.show())}handleForkUrl(url,token,fork,source,retentionPolicy){if(!this.panelManager)return;const resolved=this.resolveRetention(retentionPolicy),existing=this.forks.get(fork);if(existing){existing.closeTimer&&(clearTimeout(existing.closeTimer),existing.closeTimer=null),existing.url=url,existing.token=token,existing.source=source,existing.retentionPolicy=resolved,existing.completed=!1,existing.recyclable=!1;const component2=this.components.get(existing.panelId);component2&&component2.update({url,token});return}const recyclable=this.findRecyclablePanel(source);if(recyclable){const{forkKey:oldFork,state:rState}=recyclable;rState.closeTimer&&(clearTimeout(rState.closeTimer),rState.closeTimer=null),this.forks.delete(oldFork),rState.url=url,rState.token=token,rState.fork=fork,rState.source=source,rState.retentionPolicy=resolved,rState.completed=!1,rState.recyclable=!1,this.forks.set(fork,rState);const component2=this.components.get(rState.panelId);component2&&component2.update({url,token});return}const panelId=`fork-${fork}`;this.ensureForkGroup(),!this.mainUrl&&this.panelManager&&!this.panelManager.isMainGroupCollapsed()&&this.panelManager.collapseMainGroup();const component=new IframePanelComponent(this);component.init(panelId,{url,token}),this.panelManager.addPanel({id:panelId,element:component.element,groupId:FORK_GROUP_ID}),this.forks.set(fork,{panelId,url,token,fork,source,completed:!1,recyclable:!1,retentionPolicy:resolved,closeTimer:null}),this.emitForkActive()}ensureForkGroup(){if(!this.panelManager||this.panelManager.getGroup(FORK_GROUP_ID))return;const cw=this.rootElement?.offsetWidth??800,ch=this.rootElement?.offsetHeight??600;if(this.forkDisplay.mode==="dialog"){const isSmall=cw<this.responsiveBreakpoint,vw=window.innerWidth,vh=window.innerHeight,fw=isSmall?Math.min(cw*.95,Math.max(200,vw-20)):Math.min(720,cw*.9),fh=isSmall?Math.min(ch*.9,Math.max(200,vh-20)):Math.min(ch*.8,600),group=this.panelManager.addGroup({id:FORK_GROUP_ID,floating:{width:fw,height:fh,x:Math.max(0,(vw-fw)/2),y:Math.max(0,(vh-fh)/2)}});group.dragConstraint="merge-only",this.allowDocking||(group.dockingBlocked=!0),this.allowDialogDocking||(group.dialogDockingBlocked=!0),this.setupForkGroupActions(group),isSmall&&(this.panelManager.getFloatingOverlay(FORK_GROUP_ID)?.maximize(),this._autoMaximizedByResize=!0)}else{const split=this.forkDisplay.mode==="side-by-side"?this.forkDisplay.split:void 0,initialWidth=split!==void 0?cw*(1-split/100):void 0,group=this.panelManager.addGroup({id:FORK_GROUP_ID,direction:"right",initialSize:initialWidth});if(group.dragConstraint="merge-only",this.allowDocking||(group.dockingBlocked=!0),this.allowDialogDocking||(group.dialogDockingBlocked=!0),this.setupForkGroupActions(group),cw<this.responsiveBreakpoint){const fa=this.forkGroupActions.get(group.id);fa?(fa.setMaximized(),fa.setAutoMaximizedByResize(!0)):this.panelManager.maximizeDockedGroup(group),this._autoMaximizedByResize=!0}}}setupForkGroupActions(group){if(!this.panelManager||!this.minimizeManager)return;const actions=new ForkGroupActions(group,this.minimizeManager,this.panelManager,()=>{if(this.setupFloatingToolbar(group),group.location==="grid"&&!this.mainUrl&&this.panelManager&&!this.panelManager.isMainGroupCollapsed()&&this.panelManager.collapseMainGroup(),group.location==="floating"&&this.floatingAutoResized.delete(group.id),this.updateAutoResizeForGroup(group),group.location==="grid"){const currentWidth=this.rootElement?.offsetWidth??0;if(currentWidth>0&&currentWidth<this.responsiveBreakpoint){const fa=this.forkGroupActions.get(group.id);fa&&!fa.isMaximized&&(fa.setMaximized(),this._autoMaximizedByResize=!0,fa.setAutoMaximizedByResize(!0))}}},{allowFloating:this.allowFloating,allowMinimize:this.allowMinimize,allowMaximize:this.allowMaximize});actions.setBeforeClose(()=>this.confirmCloseGroup(group)),actions.onMaximizeChanged(maximized=>{maximized||(this._autoMaximizedByResize=!1,actions.setAutoMaximizedByResize(!1))}),group.setHeaderActions(actions.element),this.forkGroupActions.set(group.id,actions),group.onActivePanelChanged(()=>{this.autoResizing&&this.rootElement&&this.applyBestAutoResizeHeight()}),this.setupFloatingToolbar(group)}updateAutoResizeForGroup(group){const inFloating=this.panelManager?!!this.panelManager.findOverlayContaining(group.id):!1;for(const panel of group.panels){const component=this.components.get(panel.id);if(!component?.resizeCapable)continue;const effective=inFloating?this.floatingAutoResize:this.autoResizing;this.postToComponent(component,{type:"adapt-autoResizing",autoResizing:effective})}}setupFloatingToolbar(group){if(!this.panelManager||!this.minimizeManager)return;const overlay=this.panelManager.findOverlayContaining(group.id);if(overlay)if(group.onPanelCountChanged(()=>overlay.updateTotalTabCount()),overlay.hasToolbar)overlay.repositionToolbar();else{const toolbar=new FloatingToolbar(overlay,this.panelManager,this.minimizeManager,{allowDocking:this.allowDocking,allowMinimize:this.allowMinimize,allowMaximize:this.allowMaximize});toolbar.setBeforeClose(()=>this.confirmCloseGroup(overlay.group)),overlay.setToolbar(toolbar.element),this.floatingToolbars.set(overlay.group.id,toolbar),overlay.updateTotalTabCount()}}resolveRetention(policy){return policy?policy.case:"retain"}findRecyclablePanel(source){let anyRecyclable=null;for(const[forkKey,state]of this.forks)if(state.recyclable){if(source&&state.source===source)return{forkKey,state};anyRecyclable||(anyRecyclable={forkKey,state})}return anyRecyclable}handleMainDone(retentionPolicy){switch(retentionPolicy?this.resolveRetention(retentionPolicy):this.mainRetentionPolicy){case"close":this.scheduleMainClose(retentionPolicy?.case==="close"?retentionPolicy.timeoutSeconds:void 0);break;case"recycle":break;default:break}}scheduleForkClose(fork,state,timeoutSeconds){const doClose=()=>{state.closeTimer=null,this.removingPanelProgrammatically=!0;try{if(this.panelManager){const component=this.components.get(state.panelId);component&&component.dispose(),this.panelManager.removePanel(state.panelId)}this.forks.delete(fork),this.removeForkGroupIfEmpty()}finally{this.removingPanelProgrammatically=!1}this.emitForkActive(),this.saveState()};timeoutSeconds&&timeoutSeconds>0?state.closeTimer=setTimeout(doClose,timeoutSeconds*1e3):doClose()}scheduleMainClose(timeoutSeconds){const doClose=()=>{this.mainCloseTimer=null,this.mainUrl=null,this.mainToken=void 0;const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&mainComponent.hide(),this.panelManager&&!this.panelManager.isMainGroupCollapsed()&&this.panelManager.collapseMainGroup(),this.saveState()};timeoutSeconds&&timeoutSeconds>0?this.mainCloseTimer=setTimeout(doClose,timeoutSeconds*1e3):doClose()}restoreFork(pf){if(!this.panelManager)return;const panelId=`fork-${pf.fork}`;this.ensureForkGroup(),!this.mainUrl&&this.panelManager&&!this.panelManager.isMainGroupCollapsed()&&this.panelManager.collapseMainGroup();const component=new IframePanelComponent(this);component.init(panelId,{url:pf.url,token:pf.token}),this.panelManager.addPanel({id:panelId,element:component.element,groupId:FORK_GROUP_ID}),this.forks.set(pf.fork,{panelId,url:pf.url,token:pf.token,fork:pf.fork,source:pf.source,completed:!1,recyclable:pf.retentionPolicy==="recycle",retentionPolicy:pf.retentionPolicy,closeTimer:null}),this.emitForkActive()}clearAllForks(){this.removingPanelProgrammatically=!0;try{if(this.panelManager)for(const state of this.forks.values()){state.closeTimer&&(clearTimeout(state.closeTimer),state.closeTimer=null);const component=this.components.get(state.panelId);component&&component.dispose(),this.panelManager.removePanel(state.panelId)}this.forks.clear(),this.removeForkGroupIfEmpty()}finally{this.removingPanelProgrammatically=!1}}rebuildForkGroup(){if(!this.panelManager)return;const group=this.panelManager.getGroup(FORK_GROUP_ID);if(group)if(this.forkDisplay.mode==="dialog"){const cw=this.rootElement?.offsetWidth??800,ch=this.rootElement?.offsetHeight??600,fw=Math.min(720,cw*.9),fh=Math.min(ch*.8,600);this.panelManager.addFloatingGroup(group,{width:fw,height:fh,x:(window.innerWidth-fw)/2,y:(window.innerHeight-fh)/2}),this.setupFloatingToolbar(group)}else{const split=this.forkDisplay.mode==="side-by-side"?this.forkDisplay.split:void 0,initialWidth=split!==void 0?(this.rootElement?.offsetWidth??800)*(1-split/100):void 0;this.panelManager.dockGroup(FORK_GROUP_ID,"right",initialWidth)}}handleSessionComplete(){this.clearAllForks(),this.emitForkActive()}handleDoneMessage(fork,retentionPolicy){if(!fork){this.handleMainDone(retentionPolicy);return}const state=this.forks.get(fork);if(!state)return;switch(retentionPolicy?this.resolveRetention(retentionPolicy):state.retentionPolicy){case"close":state.completed=!0,this.scheduleForkClose(fork,state,retentionPolicy?.case==="close"?retentionPolicy.timeoutSeconds:void 0);break;case"recycle":state.completed=!0,state.recyclable=!0;break;default:state.completed=!0;break}}handleStoppedMessage(fork){if(!fork){this.mainCloseTimer&&(clearTimeout(this.mainCloseTimer),this.mainCloseTimer=null),this.mainUrl=null,this.mainToken=void 0;const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&mainComponent.hide(),this.showStatusMessage(this.options.text?.stopped??"This session has been stopped","stopped");return}const state=this.forks.get(fork);if(state){state.closeTimer&&(clearTimeout(state.closeTimer),state.closeTimer=null),this.removingPanelProgrammatically=!0;try{if(this.panelManager){const component=this.components.get(state.panelId);component&&component.dispose(),this.panelManager.removePanel(state.panelId)}this.forks.delete(fork),this.removeForkGroupIfEmpty()}finally{this.removingPanelProgrammatically=!1}this.emitForkActive()}}removeForkGroupIfEmpty(){if(!this.panelManager)return;const g=this.panelManager.getGroup(FORK_GROUP_ID);g&&g.size===0&&(this.panelManager.removeGroup(FORK_GROUP_ID),this._autoMaximizedByResize=!1,this.forkGroupActions.delete(FORK_GROUP_ID),this.floatingToolbars.delete(FORK_GROUP_ID),this.floatingAutoResized.delete(FORK_GROUP_ID)),this.minimizeManager?.removeGroup(FORK_GROUP_ID)}getMaximizedDockedGroupId(){for(const[groupId,actions]of this.forkGroupActions)if(actions.isMaximized)return groupId}emitForkActive(){if(!this.options.onForkActive)return;const active=this.forks.size>0;active!==this.lastForkActive&&(this.lastForkActive=active,this.options.onForkActive(active))}parseInheritToken(){const inheritFrom=this.options.inheritFrom;return inheritFrom?"hash"in inheritFrom?this.parseFromHash(inheritFrom.hash):this.parseFromParam(inheritFrom.param):null}parseFromHash(key){const hash=window.location.hash.slice(1);if(!hash)return null;const params=new URLSearchParams(hash),token=params.get(key);if(!token)return null;params.delete(key);const newHash=params.toString(),newUrl=window.location.pathname+window.location.search+(newHash?"#"+newHash:"");return history.replaceState(null,"",newUrl),decodeURIComponent(token)}parseFromParam(key){const params=new URLSearchParams(window.location.search),token=params.get(key);if(!token)return null;params.delete(key);const newSearch=params.toString(),newUrl=window.location.pathname+(newSearch?"?"+newSearch:"")+window.location.hash;return history.replaceState(null,"",newUrl),decodeURIComponent(token)}async init(){this.panelManager?.onDidRemovePanel(panel=>{if(!this.removingPanelProgrammatically){for(const[fork,state]of this.forks)if(state.panelId===panel.id){state.closeTimer&&(clearTimeout(state.closeTimer),state.closeTimer=null);const component=this.components.get(state.panelId);component&&component.dispose(),this.sessionToken&&this.client.stop(this.sessionToken,fork).catch(()=>{}),this.forks.delete(fork);break}this.emitForkActive()}});const handlers={onUrl:msg=>this.onUrl(msg),onSession:sessionJson=>{sessionJson.status==="STATUS_COMPLETED"&&!sessionJson.fork&&this.handleSessionComplete(),!sessionJson.fork&&(sessionJson.status==="STATUS_COMPLETED"||sessionJson.status==="STATUS_STOPPED"||sessionJson.status==="STATUS_ERRORED")&&(this.clearState(),this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null)),this.options.onSession&&this.options.onSession(sessionJson.status||"STATUS_UNSPECIFIED",sessionJson.fork)}};if(this.options.onOutput&&(handlers.onOutput=this.options.onOutput),handlers.onError=error=>{this.showErrorStatus(error),this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null)},!this.options.sessionToken&&this.resolvePersistOptions()&&await this.tryRestoreSession(handlers)!=="none"){this.updateBeforeUnloadGuard();return}if(this.options.sessionToken)this.sessionToken=this.options.sessionToken,await this.client.subscribe(this.sessionToken,handlers);else{const urlToken=this.parseInheritToken(),inheritToken=urlToken||this.options.inheritToken;if(this.options.inheritFrom&&!urlToken){const source="hash"in this.options.inheritFrom?`hash key '${this.options.inheritFrom.hash}'`:`param '${this.options.inheritFrom.param}'`;console.error(`[AdaptWebClient] No inherit token found in URL ${source}`);return}let challengeToken=this.options.challengeToken;if(this.options.requiresChallenge&&!challengeToken&&!inheritToken&&(challengeToken=await this.showCapWidgetAndSolve(),!challengeToken)){console.error("[AdaptWebClient] Failed to solve challenge");return}let result;if(inheritToken)result=await this.client.runInherit(inheritToken,handlers);else{const runOptions={...handlers};this.options.transmitter!==void 0&&(runOptions.transmitter=this.options.transmitter),this.options.signals!==void 0&&(runOptions.signals=this.options.signals),this.options.authToken!==void 0&&(runOptions.authToken=this.options.authToken),challengeToken!==void 0&&(runOptions.challengeToken=challengeToken),result=await this.client.run(runOptions)}this.sessionToken=result.sessionToken,this.sessionExpiresAt=result.expiresAt,this.saveState()}this.updateBeforeUnloadGuard()}async showCapWidgetAndSolve(){const CapWidgetClass=_AdaptWebClient._capWidgetClass;if(!CapWidgetClass)throw new Error("Cap.js not loaded. Import '@mochabug/adapt-web/cap' or use the full UMD bundle.");return new Promise(resolve=>{this.capWidgetInstance=new CapWidgetClass({container:this.rootElement,automationId:this.options.automationId,client:this.client.raw,...this.options.capWidgetOptions?.workerCount!==void 0&&{workerCount:this.options.capWidgetOptions.workerCount},...this.options.capWidgetOptions?.i18n&&{i18n:this.options.capWidgetOptions.i18n},onSolve:token=>{this.capWidgetInstance=null,resolve(token)},onError:error=>{console.error("[AdaptWebClient] Cap.js error:",error),this.capWidgetInstance=null,resolve(void 0)}}),this.darkMode&&this.capWidgetInstance.setDarkMode(!0)})}resolvePersistOptions(){const p=this.options.persist;if(!p)return null;if(p===!0)return{storage:"session",ttl:3600};const result={storage:p.storage??"session",ttl:p.ttl??3600};return p.key!==void 0&&(result.key=p.key),result}getStorageKey(){return`mb_adapt_${this.resolvePersistOptions()?.key??this.options.automationId}`}getStorage(){const opts=this.resolvePersistOptions();return opts?opts.storage==="local"?localStorage:sessionStorage:null}saveState(){const storage=this.getStorage();if(!storage||!this.sessionToken)return;const opts=this.resolvePersistOptions(),state={v:3,token:this.sessionToken,expiresAt:this.sessionExpiresAt?this.sessionExpiresAt.toISOString():null,savedAt:Date.now(),ttl:opts.ttl,mainUrl:this.mainUrl,mainToken:this.mainToken,forks:Array.from(this.forks.values()).filter(f=>!f.completed||f.recyclable).map(f=>{const pf={url:f.url,token:f.token,fork:f.fork,retentionPolicy:f.retentionPolicy};return f.source!==void 0&&(pf.source=f.source),pf}),forkDisplayMode:this.forkDisplay.mode,layout:this.panelManager?.serializeLayout()};if(this.minimizeManager){const minimizedIds=this.minimizeManager.getMinimizedGroupIds();minimizedIds.length>0&&(state.minimizedGroups=minimizedIds.map(gid=>{const entry=this.minimizeManager.getEntry(gid),persisted={groupId:gid,mode:entry?.mode??"floating"};return entry?.savedPosition&&(persisted.savedPosition={...entry.savedPosition}),persisted}))}const maxDockedId=this.getMaximizedDockedGroupId();maxDockedId&&(state.maximizedDockedGroupId=maxDockedId),storage.setItem(this.getStorageKey(),JSON.stringify(state))}loadState(){const storage=this.getStorage();if(!storage)return null;const raw=storage.getItem(this.getStorageKey());if(!raw)return null;let state;try{state=JSON.parse(raw)}catch{return this.clearState(),null}if(state.v!==3)return this.clearState(),null;const now=Date.now(),leeway=3e4;if(now-state.savedAt>state.ttl*1e3+leeway)return this.clearState(),null;if(state.expiresAt){const expires=new Date(state.expiresAt).getTime();if(now>expires+leeway)return this.clearState(),null}return state}clearState(){const storage=this.getStorage();storage&&storage.removeItem(this.getStorageKey())}async tryRestoreSession(handlers){const state=this.loadState();if(!state)return"none";const isStale=Date.now()-state.savedAt>1e4;if(this.sessionToken=state.token,this.sessionExpiresAt=state.expiresAt?new Date(state.expiresAt):void 0,this.mainUrl=state.mainUrl,this.mainToken=state.mainToken,state.forkDisplayMode&&(state.forkDisplayMode==="side-by-side"?this.forkDisplay={mode:"side-by-side"}:this.forkDisplay={mode:"dialog"}),this.mainUrl){const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&mainComponent.update({url:this.mainUrl,token:this.mainToken})}for(const pf of state.forks)this.restoreFork(pf);if(state.layout&&this.panelManager){for(const fg of state.layout.floatingGroups){const overlay=this.panelManager.getFloatingOverlay(fg.groupId);overlay&&(overlay.setFullBounds(fg.bounds),fg.isMaximized&&(overlay.maximize(),this.floatingToolbars.get(fg.groupId)?.syncMaximizedState()))}state.layout.mainLayout&&this.panelManager.restoreLayoutFlex(state.layout.mainLayout)}if(state.minimizedGroups&&this.minimizeManager&&this.panelManager)for(const mg of state.minimizedGroups){const group=this.panelManager.getGroup(mg.groupId);if(group&&!this.minimizeManager.isMinimized(mg.groupId))if(mg.mode==="floating"){const overlay=this.panelManager.getFloatingOverlay(mg.groupId);overlay&&this.minimizeManager.minimize(mg.groupId,overlay,group)}else mg.mode==="docked"&&this.minimizeManager.minimizeDocked(mg.groupId,group,this.panelManager)}if(state.maximizedDockedGroupId&&this.panelManager){const actions=this.forkGroupActions.get(state.maximizedDockedGroupId);actions&&actions.setMaximized()}isStale||handlers.onSession?.({status:"STATUS_RUNNING"}),this.saveState();let subscribeFailed=!1,errorWasSilenced=!1;const originalOnError=handlers.onError,wrappedHandlers={...handlers,onError:error=>{subscribeFailed=!0;const currentState=this.loadState();!currentState||Date.now()-currentState.savedAt>1e4?(errorWasSilenced=!0,this.clearState()):originalOnError?.(error)}};try{await this.client.subscribe(state.token,wrappedHandlers)}catch{subscribeFailed=!0,isStale?(errorWasSilenced=!0,this.clearState()):this.showErrorStatus(new Error("Session restore failed"))}return subscribeFailed?(await this.client.unsubscribe(),this.sessionToken=null,this.sessionExpiresAt=void 0,this.mainUrl=null,this.mainToken=void 0,this.clearAllForks(),this.components.get(MAIN_PANEL_ID)?.hide(),errorWasSilenced?"none":"failed"):"restored"}async newSession(){this.clearState(),this.mainCloseTimer&&(clearTimeout(this.mainCloseTimer),this.mainCloseTimer=null),this.mainRetentionPolicy="retain",this.sessionToken&&this.client.stop(this.sessionToken).catch(()=>{}),await this.client.unsubscribe(),this.mainUrl=null,this.mainToken=void 0,this.sessionToken=null,this.sessionExpiresAt=void 0,this.lastForkActive=null,this.updateBeforeUnloadGuard(),this.clearAllForks(),this.components.get(MAIN_PANEL_ID)?.hide(),this.removeStatusMessage();try{await this.init()}catch(error){this.showErrorStatus(error)}}resizeOverlayForGroup(group){if(!this.panelManager)return;const overlay=this.panelManager.findOverlayContaining(group.id);if(!overlay)return;const allGroups=overlay.getAllGroups();let maxHeight=0;for(const g of allGroups){const active=g.activePanel;if(active){const h=this.forkPanelHeights.get(active.id)??0;h>maxHeight&&(maxHeight=h)}}if(maxHeight>0){const headerHeight=group.headerElement?.offsetHeight??40,newHeight=Math.ceil(maxHeight)+headerHeight,bounds=overlay.getBounds(),newY=(window.innerHeight-newHeight)/2;overlay.setFullBounds({...bounds,height:newHeight,y:Math.max(0,newY)})}}onContainerResize(width,_height){if(!this.panelManager)return;const forkGroup=this.panelManager.getGroup(FORK_GROUP_ID);if(!forkGroup)return;const bp=this.responsiveBreakpoint,restoreThreshold=bp+this.responsiveHysteresis,forkActions=this.forkGroupActions.get(FORK_GROUP_ID),isDockedMaximized=forkActions?.isMaximized??!1;if(width<bp&&!this._autoMaximizedByResize){if(forkGroup.location==="floating"){const overlay=this.panelManager.getFloatingOverlay(FORK_GROUP_ID);overlay&&!overlay.isMaximized&&(overlay.maximize(),this._autoMaximizedByResize=!0)}else isDockedMaximized||(forkActions?(forkActions.setMaximized(),forkActions.setAutoMaximizedByResize(!0)):this.panelManager.maximizeDockedGroup(forkGroup),this._autoMaximizedByResize=!0);this.applyBestAutoResizeHeight()}width>=restoreThreshold&&this._autoMaximizedByResize&&(forkGroup.location==="floating"?this.panelManager.getFloatingOverlay(FORK_GROUP_ID)?.restore():forkActions?forkActions.clearMaximized():this.panelManager.restoreMaximizedDockedGroup(forkGroup),this._autoMaximizedByResize=!1,forkActions?.setAutoMaximizedByResize(!1))}setConfirmOnClose(enabled){this.confirmOnClose=enabled,this.updateBeforeUnloadGuard()}updateBeforeUnloadGuard(){const shouldGuard=this.confirmOnClose&&!!this.sessionToken&&!this.destroyed;shouldGuard&&!this.beforeUnloadHandler?(this.beforeUnloadHandler=e=>{e.preventDefault()},window.addEventListener("beforeunload",this.beforeUnloadHandler)):!shouldGuard&&this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null)}wireBeforeTabClose(){this.panelManager&&this.panelManager.setBeforeTabClose(panelId=>{if(this.removingPanelProgrammatically||!this.confirmOnClose)return!0;for(const[,state]of this.forks)if(state.panelId===panelId)return state.completed?!0:this.showConfirmDialog("This panel hasn\u2019t finished yet. Are you sure you want to close it?");return!0})}confirmCloseGroup(group){return!this.confirmOnClose||!group.panels.some(panel=>{for(const state of this.forks.values())if(state.panelId===panel.id&&!state.completed)return!0;return!1})?!0:this.showConfirmDialog("Some panels haven\u2019t finished yet. Are you sure you want to close them?")}showConfirmDialog(message){return new Promise(resolve=>{if(!this.rootElement){resolve(!0);return}const overlay=document.createElement("div");overlay.className="mb-adapt mb-adapt__confirm-overlay",this.darkMode&&overlay.classList.add("mb-adapt--dark");const card=document.createElement("div");card.className="mb-adapt__confirm-card";const text=document.createElement("p");text.className="mb-adapt__confirm-text",text.textContent=message,card.appendChild(text);const buttons=document.createElement("div");buttons.className="mb-adapt__confirm-buttons";const cancelBtn=document.createElement("button");cancelBtn.className="mb-adapt__confirm-btn mb-adapt__confirm-btn--cancel",cancelBtn.textContent="Cancel";const confirmBtn=document.createElement("button");confirmBtn.className="mb-adapt__confirm-btn mb-adapt__confirm-btn--confirm",confirmBtn.textContent="Close",buttons.appendChild(cancelBtn),buttons.appendChild(confirmBtn),card.appendChild(buttons),overlay.appendChild(card),document.body.appendChild(overlay);const cleanup=result=>{overlay.remove(),resolve(result)};cancelBtn.addEventListener("click",()=>cleanup(!1)),confirmBtn.addEventListener("click",()=>cleanup(!0)),overlay.addEventListener("click",e=>{e.target===overlay&&cleanup(!1)})})}async destroy(){this.destroyed=!0,this.mainCloseTimer&&(clearTimeout(this.mainCloseTimer),this.mainCloseTimer=null);for(const state of this.forks.values())state.closeTimer&&(clearTimeout(state.closeTimer),state.closeTimer=null);this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null),this.resizeObserver?.disconnect(),this.resizeObserver=null,this.capWidgetInstance?.destroy(),this.capWidgetInstance=null,this.minimizeManager?.dispose(),this.minimizeManager=null,this.sessionToken&&!this.loadState()&&this.client.stop(this.sessionToken).catch(()=>{}),await this.client.unsubscribe(),this.messageHandler&&window.removeEventListener("message",this.messageHandler),this.panelManager&&(this.panelManager.dispose(),this.panelManager=null),this.rootElement?.parentNode?.removeChild(this.rootElement),this.mainUrl=null,this.mainToken=void 0,this.forks.clear(),this.components.clear(),this.forkPanelHeights.clear(),this.forkGroupActions.clear(),this.floatingToolbars.clear(),this.sessionToken=null,this.lastForkActive=null,this.rootElement=null,this.messageHandler=null,this.statusMessageElement=null,this.minimizedTabsContainer=null}showStatusMessage(text,kind="error"){if(!this.rootElement)return;this.removeStatusMessage();const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&mainComponent.hide(),this.statusMessageElement=document.createElement("div"),this.statusMessageElement.className=this.options.classNames?.statusMessage??"mb-adapt__status-message";const card=document.createElement("div");card.className=this.options.classNames?.statusCard??"mb-adapt__status-card";const iconWrap=document.createElement("div");iconWrap.className=kind==="stopped"||kind==="expired"?"mb-adapt__status-icon mb-adapt__status-icon--stopped":"mb-adapt__status-icon",iconWrap.innerHTML=kind==="stopped"||kind==="expired"?'<svg viewBox="0 0 24 24" fill="none" stroke="#6b7280" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="6" width="12" height="12" rx="2"/></svg>':'<svg viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>',card.appendChild(iconWrap);const msg=document.createElement("p");msg.className="mb-adapt__status-text",msg.textContent=text,card.appendChild(msg);const btn=document.createElement("button");btn.className="mb-adapt__status-restart",btn.textContent=this.options.text?.restartButton??"Try again",btn.addEventListener("click",()=>this.newSession()),card.appendChild(btn),this.statusMessageElement.appendChild(card),this.rootElement.appendChild(this.statusMessageElement)}removeStatusMessage(){this.statusMessageElement&&(this.statusMessageElement.remove(),this.statusMessageElement=null)}showErrorStatus(error){const kind=this.isExpiredTokenError(error)?"expired":"error";this.clearState(),this.clearAllForks(),this.showStatusMessage(this.getErrorMessage(error),kind)}isExpiredTokenError(error){return error instanceof ConnectError&&error.code===Code.PermissionDenied&&error.message.toLowerCase().includes("expired")}getErrorMessage(error){const text=this.options.text,fallback=text?.error??"Something went wrong. Please try again later.";if(error instanceof ConnectError){if(this.isExpiredTokenError(error))return text?.sessionExpired??"Your session has expired.";switch(error.code){case Code.ResourceExhausted:return text?.resourceExhausted??"This automation is currently at capacity. Please try again later.";case Code.NotFound:return error.message.toLowerCase().includes("session not found")?text?.sessionNotFound??"This session has timed out or been stopped.":text?.notFound??"This automation could not be found.";case Code.PermissionDenied:case Code.Unauthenticated:return text?.permissionDenied??"You don't have permission to run this automation.";default:return fallback}}return fallback}};_AdaptWebClient._capWidgetClass=null;let AdaptWebClient=_AdaptWebClient;export{AdaptAutomationElement,AdaptWebClient,FloatingToolbar2 as FloatingToolbar,ForkGroupActions2 as ForkGroupActions,IframePanelComponent2 as IframePanelComponent,MinimizeManager2 as MinimizeManager,PanelManager2 as PanelManager,clearPersistedState,configure,createConnectClient,resetConfig,resolveTheme2 as resolveTheme};
1
+ import{Code,configure,ConnectError,createAdaptClient,resetConfig}from"@mochabug/adapt-core";import{createConnectClient}from"@mochabug/adapt-core/connect";import{PanelManager}from"./panel-manager.js";import{FloatingToolbar,ForkGroupActions,IframePanelComponent,injectPanelManagerStyles,MinimizeManager}from"./panel-setup.js";import{resolveTheme}from"./theme.js";import{resolveTheme as resolveTheme2}from"./theme.js";import{AdaptAutomationElement}from"./AdaptAutomationElement.js";import{FloatingToolbar as FloatingToolbar2,ForkGroupActions as ForkGroupActions2,IframePanelComponent as IframePanelComponent2,MinimizeManager as MinimizeManager2}from"./panel-setup.js";import{PanelManager as PanelManager2}from"./panel-manager.js";function clearPersistedState(automationId,storage="both",persistKey){const key=`mb_adapt_${persistKey??automationId}`;(storage==="session"||storage==="both")&&sessionStorage.removeItem(key),(storage==="local"||storage==="both")&&localStorage.removeItem(key)}const MAIN_PANEL_ID="main",FORK_GROUP_ID="fork-group",DEFAULT_RESPONSIVE_BREAKPOINT=768,DEFAULT_RESPONSIVE_HYSTERESIS=40,_AdaptWebClient=class _AdaptWebClient{constructor(options){this.rootElement=null;this.panelManager=null;this.mainUrl=null;this.sessionToken=null;this.forks=new Map;this.mainRetentionPolicy="retain";this.mainCloseTimer=null;this.components=new Map;this.floatingAutoResized=new Set;this.beforeUnloadHandler=null;this.resizeObserver=null;this._autoMaximizedByResize=!1;this.destroyed=!1;this.removingPanelProgrammatically=!1;this.lastForkActive=null;this.messageHandler=null;this.minimizedTabsContainer=null;this.lastReportedContentHeight=0;this.forkPanelHeights=new Map;this.statusMessageElement=null;this.capWidgetInstance=null;this.minimizeManager=null;this.forkGroupActions=new Map;this.floatingToolbars=new Map;this.options=options;const fd=options.forkDisplay??{mode:"side-by-side"};this.forkDisplay=fd,this.darkMode=options.darkMode??!1,this.autoResizing=options.autoResizing??!1,this.allowFloating=options.allowFloating??!0,this.allowDocking=options.allowDocking??!0,this.allowDialogDocking=options.allowDialogDocking??!0,this.allowMinimize=options.allowMinimize??!0,this.allowMaximize=options.allowMaximize??!0,this.floatingAutoResize=options.floatingAutoResize??!1,this.confirmOnClose=options.confirmOnClose??!1,this.theme=options.theme;const container=typeof options.container=="string"?document.getElementById(options.container):options.container;if(!container)throw new Error(`Container with id '${options.container}' not found`);this.container=container;const rawClient=createConnectClient({id:options.automationId});this.client=createAdaptClient(rawClient,options.automationId),injectPanelManagerStyles(),this.createRootElement(),this.createPanelManager(),this.wireBeforeTabClose(),this.setupMessageListener(),this.init().catch(error=>{this.showErrorStatus(error)})}static registerCapWidget(cls){_AdaptWebClient._capWidgetClass=cls}get responsiveBreakpoint(){if(!this.rootElement)return DEFAULT_RESPONSIVE_BREAKPOINT;const v=getComputedStyle(this.rootElement).getPropertyValue("--mb-adapt-responsive-breakpoint").trim(),n=Number(v);return n>0?n:DEFAULT_RESPONSIVE_BREAKPOINT}get responsiveHysteresis(){if(!this.rootElement)return DEFAULT_RESPONSIVE_HYSTERESIS;const v=getComputedStyle(this.rootElement).getPropertyValue("--mb-adapt-responsive-hysteresis").trim(),n=Number(v);return n>=0?n:DEFAULT_RESPONSIVE_HYSTERESIS}onComponentCreated(panelId,component){this.components.set(panelId,component)}onComponentDisposed(panelId){this.components.delete(panelId)}getDarkMode(){return this.darkMode}getClassNames(){return this.options.classNames}createPanelManager(){if(!this.rootElement)return;this.minimizeManager=new MinimizeManager,this.minimizeManager.setAllowDocking(this.allowDocking),this.minimizedTabsContainer=document.createElement("div"),this.minimizedTabsContainer.className="mb-adapt-minimized-tabs",this.rootElement.appendChild(this.minimizedTabsContainer),this.panelManager=new PanelManager({container:this.rootElement,onGroupCreatedByDrag:group=>{group.dragConstraint="merge-only",this.allowDocking||(group.dockingBlocked=!0),this.allowDialogDocking||(group.dialogDockingBlocked=!0),this.setupForkGroupActions(group)}});const mainGroup=this.panelManager.addGroup({id:"main-group"});this.panelManager.setMainGroup(mainGroup),mainGroup.locked="no-drop-target",mainGroup.setHeaderHidden(!0),mainGroup.element.setAttribute("data-main-group","true");const mainComponent=new IframePanelComponent(this);mainComponent.init(MAIN_PANEL_ID,{}),this.panelManager.addPanel({id:MAIN_PANEL_ID,element:mainComponent.element,groupId:mainGroup.id}),this.minimizeManager.init(this.minimizedTabsContainer,this.panelManager),this.minimizeManager.onBarVisibilityChanged(()=>{this.reapplyAutoResizeHeight()}),this.resizeObserver=new ResizeObserver(entries=>{const cr=entries[0]?.contentRect;cr&&this.onContainerResize(cr.width,cr.height)}),this.resizeObserver.observe(this.rootElement)}getOrigin(url){try{return new URL(url).origin}catch{return null}}isValidMessageOrigin(origin){if(this.mainUrl){const mainOrigin=this.getOrigin(this.mainUrl);if(mainOrigin&&origin===mainOrigin)return!0}for(const fork of this.forks.values()){const forkOrigin=this.getOrigin(fork.url);if(forkOrigin&&origin===forkOrigin)return!0}return!1}findComponentBySource(source){for(const[panelId,component]of this.components)if(component.contentWindow===source)return{panelId,component};return null}setupMessageListener(){this.messageHandler=event=>{if(!this.isValidMessageOrigin(event.origin))return;const data=event.data;if(!data||typeof data!="object")return;const source=event.source,found=this.findComponentBySource(source);if(!found)return;const{panelId,component}=found,isMainPanel=panelId===MAIN_PANEL_ID;if(data.type==="adapt-init"&&typeof data.resize=="boolean"){component.resizeCapable=data.resize,isMainPanel&&!data.resize&&this.rootElement&&(this.rootElement.style.height="");const targetOrigin=component.getOrigin();if(targetOrigin){let effective;if(isMainPanel)effective=this.autoResizing&&data.resize;else{const group=this.panelManager?.getPanel(panelId)?.group,inFloating=group?!!this.panelManager?.findOverlayContaining(group.id):!1;effective=data.resize&&(inFloating&&this.floatingAutoResize||!inFloating&&this.autoResizing)}component.postMessage({type:"adapt-autoResizing",autoResizing:effective},targetOrigin),component.postMessage({type:"adapt-darkMode",darkMode:this.darkMode},targetOrigin)}return}if(data.type==="adapt-resize"){const{height}=data;if(typeof height!="number"||!Number.isFinite(height)||height<1)return;if(isMainPanel)this.lastReportedContentHeight=height,component.resizeCapable&&this.autoResizing&&this.rootElement&&this.applyBestAutoResizeHeight();else{this.forkPanelHeights.set(panelId,height);const group=this.panelManager?.getPanel(panelId)?.group;if(group&&group.activePanel?.id===panelId){const inFloating=!!this.panelManager?.findOverlayContaining(group.id);!inFloating&&component.resizeCapable&&this.autoResizing&&this.rootElement&&this.applyBestAutoResizeHeight(),inFloating&&this.floatingAutoResize&&(this.floatingAutoResized.has(group.id)||(this.floatingAutoResized.add(group.id),this.resizeOverlayForGroup(group)))}}return}},window.addEventListener("message",this.messageHandler)}postToComponent(component,message){const origin=component.getOrigin();origin&&component.postMessage(message,origin)}setDarkMode(darkMode){if(this.darkMode===darkMode)return;this.darkMode=darkMode,this.rootElement?.classList.toggle("mb-adapt--dark",darkMode),this.capWidgetInstance?.setDarkMode(darkMode),this.applyTheme();const msg={type:"adapt-darkMode",darkMode};for(const c of this.components.values())this.postToComponent(c,msg)}setTheme(theme){if(this.theme=theme,this.clearThemeVars(),theme?.mode!==void 0){const dark=theme.mode==="dark";if(this.darkMode!==dark){this.setDarkMode(dark);return}}this.applyTheme()}clearThemeVars(){if(!(!this.rootElement||!this._appliedThemeVars)){for(const key of this._appliedThemeVars)this.rootElement.style.removeProperty(key);this._appliedThemeVars=void 0}}applyTheme(){if(!this.rootElement||!this.theme)return;const vars=resolveTheme(this.theme);for(const[key,value]of Object.entries(vars))this.rootElement.style.setProperty(key,value);this._appliedThemeVars=Object.keys(vars)}setAutoResizing(autoResizing){if(this.autoResizing===autoResizing)return;this.autoResizing=autoResizing;const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent?.resizeCapable&&this.postToComponent(mainComponent,{type:"adapt-autoResizing",autoResizing});for(const[panelId,component]of this.components){if(panelId===MAIN_PANEL_ID||!component.resizeCapable)continue;const group=this.panelManager?.getPanel(panelId)?.group;group&&this.panelManager?.findOverlayContaining(group.id)||this.postToComponent(component,{type:"adapt-autoResizing",autoResizing})}!autoResizing&&this.rootElement&&(this.rootElement.style.height="")}setAllowFloating(allow){if(this.allowFloating!==allow){this.allowFloating=allow;for(const actions of this.forkGroupActions.values())actions.setAllowFloating(allow)}}setAllowDocking(allow){if(this.allowDocking!==allow){if(this.allowDocking=allow,this.minimizeManager?.setAllowDocking(allow),this.panelManager)for(const group of this.getAllForkGroups())group.dockingBlocked=!allow;for(const toolbar of this.floatingToolbars.values())toolbar.setAllowDocking(allow)}}setAllowDialogDocking(allow){if(this.allowDialogDocking!==allow&&(this.allowDialogDocking=allow,this.panelManager))for(const group of this.getAllForkGroups())group.dialogDockingBlocked=!allow}setAllowMinimize(allow){if(this.allowMinimize!==allow){this.allowMinimize=allow;for(const actions of this.forkGroupActions.values())actions.setAllowMinimize(allow);for(const toolbar of this.floatingToolbars.values())toolbar.setAllowMinimize(allow)}}setAllowMaximize(allow){if(this.allowMaximize!==allow){this.allowMaximize=allow;for(const actions of this.forkGroupActions.values())actions.setAllowMaximize(allow);for(const toolbar of this.floatingToolbars.values())toolbar.setAllowMaximize(allow)}}setFloatingAutoResize(enabled){if(this.floatingAutoResize!==enabled){this.floatingAutoResize=enabled,this.floatingAutoResized.clear();for(const[panelId,component]of this.components){if(panelId===MAIN_PANEL_ID||!component.resizeCapable)continue;const group=this.panelManager?.getPanel(panelId)?.group,effective=(group?!!this.panelManager?.findOverlayContaining(group.id):!1)?enabled&&component.resizeCapable:this.autoResizing&&component.resizeCapable;this.postToComponent(component,{type:"adapt-autoResizing",autoResizing:effective})}}}getAllForkGroups(){if(!this.panelManager)return[];const seen=new Set,groups=[],add=g=>{g.id==="main-group"||seen.has(g.id)||(seen.add(g.id),groups.push(g))},forkGroup=this.panelManager.getGroup(FORK_GROUP_ID);forkGroup&&add(forkGroup);for(const g of this.panelManager.getDockedGroups())add(g);for(const[,overlay]of this.panelManager.getFloatingOverlays())for(const g of overlay.getAllGroups())add(g);return groups}applyAutoResizeHeight(contentHeight){if(!this.rootElement)return;const chrome=this.minimizedTabsContainer?.offsetHeight??0;this.rootElement.style.height=`${Math.ceil(contentHeight)+chrome}px`}applyBestAutoResizeHeight(){if(!this.autoResizing||!this.rootElement)return;let maxHeight=0;if(this.components.get(MAIN_PANEL_ID)?.resizeCapable&&this.lastReportedContentHeight>0){const mainGroup=this.panelManager?.getMainGroup();if(mainGroup?mainGroup.element.offsetHeight>0:!0){const headerH=mainGroup?.headerElement?.offsetHeight??0;maxHeight=this.lastReportedContentHeight+headerH}}for(const group of this.getAllForkGroups()){if(this.panelManager?.findOverlayContaining(group.id)||group.element.offsetHeight<=0)continue;const active=group.activePanel;if(active){const h=this.forkPanelHeights.get(active.id)??0,headerH=group.headerElement?.offsetHeight??0,total=h+headerH;total>maxHeight&&(maxHeight=total)}}maxHeight>0&&this.applyAutoResizeHeight(maxHeight)}reapplyAutoResizeHeight(){this.applyBestAutoResizeHeight()}setForkDisplayMode(mode){this.forkDisplay.mode!==mode&&(mode==="side-by-side"?this.forkDisplay={mode:"side-by-side"}:this.forkDisplay={mode:"dialog"},this.forks.size>0&&this.panelManager&&this.rebuildForkGroup(),this.emitForkActive(),this.saveState())}createRootElement(){this.rootElement=document.createElement("div"),this.rootElement.className=this.options.classNames?.root||"mb-adapt",this.darkMode&&this.rootElement.classList.add("mb-adapt--dark"),this.options.styles&&Object.assign(this.rootElement.style,this.options.styles),this.applyTheme(),this.container.appendChild(this.rootElement)}onUrl(msg){if(this.destroyed)return;const fork=msg.fork||"";if(msg.stopped){this.handleStoppedMessage(fork),this.saveState();return}if(msg.done){this.handleDoneMessage(fork,msg.retentionPolicy),this.saveState();return}msg.url&&(fork?this.handleForkUrl(msg.url,msg.token,fork,msg.source,msg.retentionPolicy):this.handleMainUrl(msg.url,msg.token,msg.source,msg.retentionPolicy),this.saveState())}handleMainUrl(url,token,_source,retentionPolicy){this.mainCloseTimer&&(clearTimeout(this.mainCloseTimer),this.mainCloseTimer=null);const wasMainEmpty=!this.mainUrl;if(this.removeStatusMessage(),this.mainUrl=url,this.mainToken=token,this.mainRetentionPolicy=this.resolveRetention(retentionPolicy),this.panelManager?.isMainGroupCollapsed()&&this.panelManager.expandMainGroup(),wasMainEmpty){const maximizedGroupId=this.getMaximizedDockedGroupId();if(maximizedGroupId){const actions=this.forkGroupActions.get(maximizedGroupId);actions&&actions.clearMaximized()}}const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&(mainComponent.update({url,token}),mainComponent.show())}handleForkUrl(url,token,fork,source,retentionPolicy){if(!this.panelManager)return;const resolved=this.resolveRetention(retentionPolicy),existing=this.forks.get(fork);if(existing){existing.closeTimer&&(clearTimeout(existing.closeTimer),existing.closeTimer=null),existing.url=url,existing.token=token,existing.source=source,existing.retentionPolicy=resolved,existing.completed=!1,existing.recyclable=!1;const component2=this.components.get(existing.panelId);component2&&component2.update({url,token});return}const recyclable=this.findRecyclablePanel(source);if(recyclable){const{forkKey:oldFork,state:rState}=recyclable;rState.closeTimer&&(clearTimeout(rState.closeTimer),rState.closeTimer=null),this.forks.delete(oldFork),rState.url=url,rState.token=token,rState.fork=fork,rState.source=source,rState.retentionPolicy=resolved,rState.completed=!1,rState.recyclable=!1,this.forks.set(fork,rState);const component2=this.components.get(rState.panelId);component2&&component2.update({url,token});return}const panelId=`fork-${fork}`;this.ensureForkGroup(),!this.mainUrl&&this.panelManager&&!this.panelManager.isMainGroupCollapsed()&&this.panelManager.collapseMainGroup();const component=new IframePanelComponent(this);component.init(panelId,{url,token}),this.panelManager.addPanel({id:panelId,element:component.element,groupId:FORK_GROUP_ID}),this.forks.set(fork,{panelId,url,token,fork,source,completed:!1,recyclable:!1,retentionPolicy:resolved,closeTimer:null}),this.emitForkActive()}ensureForkGroup(){if(!this.panelManager||this.panelManager.getGroup(FORK_GROUP_ID))return;const cw=this.rootElement?.offsetWidth??800,ch=this.rootElement?.offsetHeight??600;if(this.forkDisplay.mode==="dialog"){const isSmall=cw<this.responsiveBreakpoint,vw=window.innerWidth,vh=window.innerHeight,fw=isSmall?Math.min(cw*.95,Math.max(200,vw-20)):Math.min(720,cw*.9),fh=isSmall?Math.min(ch*.9,Math.max(200,vh-20)):Math.min(ch*.8,600),group=this.panelManager.addGroup({id:FORK_GROUP_ID,floating:{width:fw,height:fh,x:Math.max(0,(vw-fw)/2),y:Math.max(0,(vh-fh)/2)}});group.dragConstraint="merge-only",this.allowDocking||(group.dockingBlocked=!0),this.allowDialogDocking||(group.dialogDockingBlocked=!0),this.setupForkGroupActions(group),isSmall&&(this.panelManager.getFloatingOverlay(FORK_GROUP_ID)?.maximize(),this._autoMaximizedByResize=!0)}else{const split=this.forkDisplay.mode==="side-by-side"?this.forkDisplay.split:void 0,initialWidth=split!==void 0?cw*(1-split/100):void 0,group=this.panelManager.addGroup({id:FORK_GROUP_ID,direction:"right",initialSize:initialWidth});if(group.dragConstraint="merge-only",this.allowDocking||(group.dockingBlocked=!0),this.allowDialogDocking||(group.dialogDockingBlocked=!0),this.setupForkGroupActions(group),cw<this.responsiveBreakpoint){const fa=this.forkGroupActions.get(group.id);fa?(fa.setMaximized(),fa.setAutoMaximizedByResize(!0)):this.panelManager.maximizeDockedGroup(group),this._autoMaximizedByResize=!0}}}setupForkGroupActions(group){if(!this.panelManager||!this.minimizeManager)return;const actions=new ForkGroupActions(group,this.minimizeManager,this.panelManager,()=>{if(this.setupFloatingToolbar(group),group.location==="grid"&&!this.mainUrl&&this.panelManager&&!this.panelManager.isMainGroupCollapsed()&&this.panelManager.collapseMainGroup(),group.location==="floating"&&this.floatingAutoResized.delete(group.id),this.updateAutoResizeForGroup(group),group.location==="grid"){const currentWidth=this.rootElement?.offsetWidth??0;if(currentWidth>0&&currentWidth<this.responsiveBreakpoint){const fa=this.forkGroupActions.get(group.id);fa&&!fa.isMaximized&&(fa.setMaximized(),this._autoMaximizedByResize=!0,fa.setAutoMaximizedByResize(!0))}}},{allowFloating:this.allowFloating,allowMinimize:this.allowMinimize,allowMaximize:this.allowMaximize});actions.setBeforeClose(()=>this.confirmCloseGroup(group)),actions.onMaximizeChanged(maximized=>{maximized||(this._autoMaximizedByResize=!1,actions.setAutoMaximizedByResize(!1))}),group.setHeaderActions(actions.element),this.forkGroupActions.set(group.id,actions),group.onActivePanelChanged(()=>{this.autoResizing&&this.rootElement&&this.applyBestAutoResizeHeight()}),this.setupFloatingToolbar(group)}updateAutoResizeForGroup(group){const inFloating=this.panelManager?!!this.panelManager.findOverlayContaining(group.id):!1;for(const panel of group.panels){const component=this.components.get(panel.id);if(!component?.resizeCapable)continue;const effective=inFloating?this.floatingAutoResize:this.autoResizing;this.postToComponent(component,{type:"adapt-autoResizing",autoResizing:effective})}}setupFloatingToolbar(group){if(!this.panelManager||!this.minimizeManager)return;const overlay=this.panelManager.findOverlayContaining(group.id);if(overlay)if(group.onPanelCountChanged(()=>overlay.updateTotalTabCount()),overlay.hasToolbar)overlay.repositionToolbar();else{const toolbar=new FloatingToolbar(overlay,this.panelManager,this.minimizeManager,{allowDocking:this.allowDocking,allowMinimize:this.allowMinimize,allowMaximize:this.allowMaximize});toolbar.setBeforeClose(()=>this.confirmCloseGroup(overlay.group)),overlay.setToolbar(toolbar.element),this.floatingToolbars.set(overlay.group.id,toolbar),overlay.updateTotalTabCount()}}resolveRetention(policy){return policy?policy.case:"retain"}findRecyclablePanel(source){let anyRecyclable=null;for(const[forkKey,state]of this.forks)if(state.recyclable){if(source&&state.source===source)return{forkKey,state};anyRecyclable||(anyRecyclable={forkKey,state})}return anyRecyclable}handleMainDone(retentionPolicy){switch(retentionPolicy?this.resolveRetention(retentionPolicy):this.mainRetentionPolicy){case"close":this.scheduleMainClose(retentionPolicy?.case==="close"?retentionPolicy.timeoutSeconds:void 0);break;case"recycle":break;default:break}}scheduleForkClose(fork,state,timeoutSeconds){const doClose=()=>{state.closeTimer=null,this.removingPanelProgrammatically=!0;try{if(this.panelManager){const component=this.components.get(state.panelId);component&&component.dispose(),this.panelManager.removePanel(state.panelId)}this.forks.delete(fork),this.removeForkGroupIfEmpty()}finally{this.removingPanelProgrammatically=!1}this.emitForkActive(),this.saveState()};timeoutSeconds&&timeoutSeconds>0?state.closeTimer=setTimeout(doClose,timeoutSeconds*1e3):doClose()}scheduleMainClose(timeoutSeconds){const doClose=()=>{this.mainCloseTimer=null,this.mainUrl=null,this.mainToken=void 0;const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&mainComponent.hide(),this.panelManager&&!this.panelManager.isMainGroupCollapsed()&&this.panelManager.collapseMainGroup(),this.saveState()};timeoutSeconds&&timeoutSeconds>0?this.mainCloseTimer=setTimeout(doClose,timeoutSeconds*1e3):doClose()}restoreFork(pf){if(!this.panelManager)return;const panelId=`fork-${pf.fork}`;this.ensureForkGroup(),!this.mainUrl&&this.panelManager&&!this.panelManager.isMainGroupCollapsed()&&this.panelManager.collapseMainGroup();const component=new IframePanelComponent(this);component.init(panelId,{url:pf.url,token:pf.token}),this.panelManager.addPanel({id:panelId,element:component.element,groupId:FORK_GROUP_ID}),this.forks.set(pf.fork,{panelId,url:pf.url,token:pf.token,fork:pf.fork,source:pf.source,completed:!1,recyclable:pf.retentionPolicy==="recycle",retentionPolicy:pf.retentionPolicy,closeTimer:null}),this.emitForkActive()}clearAllForks(){this.removingPanelProgrammatically=!0;try{if(this.panelManager)for(const state of this.forks.values()){state.closeTimer&&(clearTimeout(state.closeTimer),state.closeTimer=null);const component=this.components.get(state.panelId);component&&component.dispose(),this.panelManager.removePanel(state.panelId)}this.forks.clear(),this.removeForkGroupIfEmpty()}finally{this.removingPanelProgrammatically=!1}}rebuildForkGroup(){if(!this.panelManager)return;const group=this.panelManager.getGroup(FORK_GROUP_ID);if(group)if(this.forkDisplay.mode==="dialog"){const cw=this.rootElement?.offsetWidth??800,ch=this.rootElement?.offsetHeight??600,fw=Math.min(720,cw*.9),fh=Math.min(ch*.8,600);this.panelManager.addFloatingGroup(group,{width:fw,height:fh,x:(window.innerWidth-fw)/2,y:(window.innerHeight-fh)/2}),this.setupFloatingToolbar(group)}else{const split=this.forkDisplay.mode==="side-by-side"?this.forkDisplay.split:void 0,initialWidth=split!==void 0?(this.rootElement?.offsetWidth??800)*(1-split/100):void 0;this.panelManager.dockGroup(FORK_GROUP_ID,"right",initialWidth)}}handleSessionComplete(){this.clearAllForks(),this.emitForkActive()}handleDoneMessage(fork,retentionPolicy){if(!fork){this.handleMainDone(retentionPolicy);return}const state=this.forks.get(fork);if(!state)return;switch(retentionPolicy?this.resolveRetention(retentionPolicy):state.retentionPolicy){case"close":state.completed=!0,this.scheduleForkClose(fork,state,retentionPolicy?.case==="close"?retentionPolicy.timeoutSeconds:void 0);break;case"recycle":state.completed=!0,state.recyclable=!0;break;default:state.completed=!0;break}}handleStoppedMessage(fork){if(!fork){this.mainCloseTimer&&(clearTimeout(this.mainCloseTimer),this.mainCloseTimer=null),this.mainUrl=null,this.mainToken=void 0;const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&mainComponent.hide(),this.showStatusMessage(this.options.text?.stopped??"This session has been stopped","stopped");return}const state=this.forks.get(fork);if(state){state.closeTimer&&(clearTimeout(state.closeTimer),state.closeTimer=null),this.removingPanelProgrammatically=!0;try{if(this.panelManager){const component=this.components.get(state.panelId);component&&component.dispose(),this.panelManager.removePanel(state.panelId)}this.forks.delete(fork),this.removeForkGroupIfEmpty()}finally{this.removingPanelProgrammatically=!1}this.emitForkActive()}}removeForkGroupIfEmpty(){if(!this.panelManager)return;const g=this.panelManager.getGroup(FORK_GROUP_ID);g&&g.size===0&&(this.panelManager.removeGroup(FORK_GROUP_ID),this._autoMaximizedByResize=!1,this.forkGroupActions.delete(FORK_GROUP_ID),this.floatingToolbars.delete(FORK_GROUP_ID),this.floatingAutoResized.delete(FORK_GROUP_ID)),this.minimizeManager?.removeGroup(FORK_GROUP_ID)}getMaximizedDockedGroupId(){for(const[groupId,actions]of this.forkGroupActions)if(actions.isMaximized)return groupId}emitForkActive(){if(!this.options.onForkActive)return;const active=this.forks.size>0;active!==this.lastForkActive&&(this.lastForkActive=active,this.options.onForkActive(active))}parseInheritToken(){const inheritFrom=this.options.inheritFrom;return inheritFrom?"hash"in inheritFrom?this.parseFromHash(inheritFrom.hash):this.parseFromParam(inheritFrom.param):null}parseFromHash(key){const hash=window.location.hash.slice(1);if(!hash)return null;const params=new URLSearchParams(hash),token=params.get(key);if(!token)return null;params.delete(key);const newHash=params.toString(),newUrl=window.location.pathname+window.location.search+(newHash?"#"+newHash:"");return history.replaceState(null,"",newUrl),decodeURIComponent(token)}parseFromParam(key){const params=new URLSearchParams(window.location.search),token=params.get(key);if(!token)return null;params.delete(key);const newSearch=params.toString(),newUrl=window.location.pathname+(newSearch?"?"+newSearch:"")+window.location.hash;return history.replaceState(null,"",newUrl),decodeURIComponent(token)}async init(){this.panelManager?.onDidRemovePanel(panel=>{if(!this.removingPanelProgrammatically){for(const[fork,state]of this.forks)if(state.panelId===panel.id){state.closeTimer&&(clearTimeout(state.closeTimer),state.closeTimer=null);const component=this.components.get(state.panelId);component&&component.dispose(),this.sessionToken&&this.client.stop(this.sessionToken,fork).catch(()=>{}),this.forks.delete(fork);break}this.emitForkActive()}});const handlers={onUrl:msg=>this.onUrl(msg),onSession:sessionJson=>{sessionJson.status==="STATUS_COMPLETED"&&!sessionJson.fork&&this.handleSessionComplete(),!sessionJson.fork&&(sessionJson.status==="STATUS_COMPLETED"||sessionJson.status==="STATUS_STOPPED"||sessionJson.status==="STATUS_ERRORED")&&(this.clearState(),this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null)),this.options.onSession&&this.options.onSession(sessionJson.status||"STATUS_UNSPECIFIED",sessionJson.fork)}};if(this.options.onOutput&&(handlers.onOutput=this.options.onOutput),handlers.onError=error=>{this.showErrorStatus(error),this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null)},!this.options.sessionToken&&this.resolvePersistOptions()&&await this.tryRestoreSession(handlers)!=="none"){this.updateBeforeUnloadGuard();return}if(this.options.sessionToken)this.sessionToken=this.options.sessionToken,await this.client.subscribe(this.sessionToken,handlers);else{const urlToken=this.parseInheritToken(),inheritToken=urlToken||this.options.inheritToken;if(this.options.inheritFrom&&!urlToken){const source="hash"in this.options.inheritFrom?`hash key '${this.options.inheritFrom.hash}'`:`param '${this.options.inheritFrom.param}'`;console.error(`[AdaptWebClient] No inherit token found in URL ${source}`);return}let challengeToken=this.options.challengeToken;if(this.options.requiresChallenge&&!challengeToken&&!inheritToken&&(challengeToken=await this.showCapWidgetAndSolve(),!challengeToken)){console.error("[AdaptWebClient] Failed to solve challenge");return}let result;if(inheritToken)result=await this.client.runInherit(inheritToken,handlers);else{const runOptions={...handlers};this.options.transmitter!==void 0&&(runOptions.transmitter=this.options.transmitter),this.options.signals!==void 0&&(runOptions.signals=this.options.signals),this.options.authToken!==void 0&&(runOptions.authToken=this.options.authToken),challengeToken!==void 0&&(runOptions.challengeToken=challengeToken),result=await this.client.run(runOptions)}this.sessionToken=result.sessionToken,this.sessionExpiresAt=result.expiresAt,this.saveState()}this.updateBeforeUnloadGuard()}async showCapWidgetAndSolve(){const CapWidgetClass=_AdaptWebClient._capWidgetClass;if(!CapWidgetClass)throw new Error("Cap.js not loaded. Import '@mochabug/adapt-web/cap' or use the full UMD bundle.");return new Promise(resolve=>{this.capWidgetInstance=new CapWidgetClass({container:this.rootElement,automationId:this.options.automationId,client:this.client.raw,...this.options.capWidgetOptions?.workerCount!==void 0&&{workerCount:this.options.capWidgetOptions.workerCount},...this.options.capWidgetOptions?.i18n&&{i18n:this.options.capWidgetOptions.i18n},onSolve:token=>{this.capWidgetInstance=null,resolve(token)},onError:error=>{console.error("[AdaptWebClient] Cap.js error:",error),this.capWidgetInstance=null,resolve(void 0)}}),this.darkMode&&this.capWidgetInstance.setDarkMode(!0)})}resolvePersistOptions(){const p=this.options.persist;if(!p)return null;if(p===!0)return{storage:"session",ttl:3600};const result={storage:p.storage??"session",ttl:p.ttl??3600};return p.key!==void 0&&(result.key=p.key),result}getStorageKey(){return`mb_adapt_${this.resolvePersistOptions()?.key??this.options.automationId}`}getStorage(){const opts=this.resolvePersistOptions();return opts?opts.storage==="local"?localStorage:sessionStorage:null}saveState(){const storage=this.getStorage();if(!storage||!this.sessionToken)return;const opts=this.resolvePersistOptions(),state={v:3,token:this.sessionToken,expiresAt:this.sessionExpiresAt?this.sessionExpiresAt.toISOString():null,savedAt:Date.now(),ttl:opts.ttl,mainUrl:this.mainUrl,mainToken:this.mainToken,forks:Array.from(this.forks.values()).filter(f=>!f.completed||f.recyclable).map(f=>{const pf={url:f.url,token:f.token,fork:f.fork,retentionPolicy:f.retentionPolicy};return f.source!==void 0&&(pf.source=f.source),pf}),forkDisplayMode:this.forkDisplay.mode,layout:this.panelManager?.serializeLayout()};if(this.minimizeManager){const minimizedIds=this.minimizeManager.getMinimizedGroupIds();minimizedIds.length>0&&(state.minimizedGroups=minimizedIds.map(gid=>{const entry=this.minimizeManager.getEntry(gid),persisted={groupId:gid,mode:entry?.mode??"floating"};return entry?.savedPosition&&(persisted.savedPosition={...entry.savedPosition}),persisted}))}const maxDockedId=this.getMaximizedDockedGroupId();maxDockedId&&(state.maximizedDockedGroupId=maxDockedId),storage.setItem(this.getStorageKey(),JSON.stringify(state))}loadState(){const storage=this.getStorage();if(!storage)return null;const raw=storage.getItem(this.getStorageKey());if(!raw)return null;let state;try{state=JSON.parse(raw)}catch{return this.clearState(),null}if(state.v!==3)return this.clearState(),null;const now=Date.now(),leeway=3e4;if(now-state.savedAt>state.ttl*1e3+leeway)return this.clearState(),null;if(state.expiresAt){const expires=new Date(state.expiresAt).getTime();if(now>expires+leeway)return this.clearState(),null}return state}clearState(){const storage=this.getStorage();storage&&storage.removeItem(this.getStorageKey())}async tryRestoreSession(handlers){const state=this.loadState();if(!state)return"none";const isStale=Date.now()-state.savedAt>1e4;if(this.sessionToken=state.token,this.sessionExpiresAt=state.expiresAt?new Date(state.expiresAt):void 0,this.mainUrl=state.mainUrl,this.mainToken=state.mainToken,state.forkDisplayMode&&(state.forkDisplayMode==="side-by-side"?this.forkDisplay={mode:"side-by-side"}:this.forkDisplay={mode:"dialog"}),this.mainUrl){const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&mainComponent.update({url:this.mainUrl,token:this.mainToken})}for(const pf of state.forks)this.restoreFork(pf);if(state.layout&&this.panelManager){for(const fg of state.layout.floatingGroups){const overlay=this.panelManager.getFloatingOverlay(fg.groupId);overlay&&(overlay.setFullBounds(fg.bounds),fg.isMaximized&&(overlay.maximize(),this.floatingToolbars.get(fg.groupId)?.syncMaximizedState()))}state.layout.mainLayout&&this.panelManager.restoreLayoutFlex(state.layout.mainLayout)}if(state.minimizedGroups&&this.minimizeManager&&this.panelManager)for(const mg of state.minimizedGroups){const group=this.panelManager.getGroup(mg.groupId);if(group&&!this.minimizeManager.isMinimized(mg.groupId))if(mg.mode==="floating"){const overlay=this.panelManager.getFloatingOverlay(mg.groupId);overlay&&this.minimizeManager.minimize(mg.groupId,overlay,group)}else mg.mode==="docked"&&this.minimizeManager.minimizeDocked(mg.groupId,group,this.panelManager)}if(state.maximizedDockedGroupId&&this.panelManager){const actions=this.forkGroupActions.get(state.maximizedDockedGroupId);actions&&actions.setMaximized()}isStale||handlers.onSession?.({status:"STATUS_RUNNING"}),this.saveState();let subscribeFailed=!1,errorWasSilenced=!1;const originalOnError=handlers.onError,wrappedHandlers={...handlers,onError:error=>{subscribeFailed=!0;const currentState=this.loadState();!currentState||Date.now()-currentState.savedAt>1e4?(errorWasSilenced=!0,this.clearState()):originalOnError?.(error)}};try{await this.client.subscribe(state.token,wrappedHandlers)}catch{subscribeFailed=!0,isStale?(errorWasSilenced=!0,this.clearState()):this.showErrorStatus(new Error("Session restore failed"))}return subscribeFailed?(await this.client.unsubscribe(),this.sessionToken=null,this.sessionExpiresAt=void 0,this.mainUrl=null,this.mainToken=void 0,this.clearAllForks(),this.components.get(MAIN_PANEL_ID)?.hide(),errorWasSilenced?"none":"failed"):"restored"}async newSession(){this.clearState(),this.mainCloseTimer&&(clearTimeout(this.mainCloseTimer),this.mainCloseTimer=null),this.mainRetentionPolicy="retain",this.sessionToken&&this.client.stop(this.sessionToken).catch(()=>{}),await this.client.unsubscribe(),this.mainUrl=null,this.mainToken=void 0,this.sessionToken=null,this.sessionExpiresAt=void 0,this.lastForkActive=null,this.updateBeforeUnloadGuard(),this.clearAllForks(),this.components.get(MAIN_PANEL_ID)?.hide(),this.removeStatusMessage();try{await this.init()}catch(error){this.showErrorStatus(error)}}resizeOverlayForGroup(group){if(!this.panelManager)return;const overlay=this.panelManager.findOverlayContaining(group.id);if(!overlay)return;const allGroups=overlay.getAllGroups();let maxHeight=0;for(const g of allGroups){const active=g.activePanel;if(active){const h=this.forkPanelHeights.get(active.id)??0;h>maxHeight&&(maxHeight=h)}}if(maxHeight>0){const headerHeight=group.headerElement?.offsetHeight??40,newHeight=Math.ceil(maxHeight)+headerHeight,bounds=overlay.getBounds(),newY=(window.innerHeight-newHeight)/2;overlay.setFullBounds({...bounds,height:newHeight,y:Math.max(0,newY)})}}onContainerResize(width,_height){if(!this.panelManager)return;const forkGroup=this.panelManager.getGroup(FORK_GROUP_ID);if(!forkGroup)return;const bp=this.responsiveBreakpoint,restoreThreshold=bp+this.responsiveHysteresis,forkActions=this.forkGroupActions.get(FORK_GROUP_ID),isDockedMaximized=forkActions?.isMaximized??!1;if(width<bp&&!this._autoMaximizedByResize){if(forkGroup.location==="floating"){const overlay=this.panelManager.getFloatingOverlay(FORK_GROUP_ID);overlay&&!overlay.isMaximized&&(overlay.maximize(),this._autoMaximizedByResize=!0)}else isDockedMaximized||(forkActions?(forkActions.setMaximized(),forkActions.setAutoMaximizedByResize(!0)):this.panelManager.maximizeDockedGroup(forkGroup),this._autoMaximizedByResize=!0);this.applyBestAutoResizeHeight()}width>=restoreThreshold&&this._autoMaximizedByResize&&(forkGroup.location==="floating"?this.panelManager.getFloatingOverlay(FORK_GROUP_ID)?.restore():forkActions?forkActions.clearMaximized():this.panelManager.restoreMaximizedDockedGroup(forkGroup),this._autoMaximizedByResize=!1,forkActions?.setAutoMaximizedByResize(!1))}setConfirmOnClose(enabled){this.confirmOnClose=enabled,this.updateBeforeUnloadGuard()}updateBeforeUnloadGuard(){const shouldGuard=this.confirmOnClose&&!!this.sessionToken&&!this.destroyed;shouldGuard&&!this.beforeUnloadHandler?(this.beforeUnloadHandler=e=>{e.preventDefault()},window.addEventListener("beforeunload",this.beforeUnloadHandler)):!shouldGuard&&this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null)}wireBeforeTabClose(){this.panelManager&&this.panelManager.setBeforeTabClose(panelId=>{if(this.removingPanelProgrammatically||!this.confirmOnClose)return!0;for(const[,state]of this.forks)if(state.panelId===panelId)return state.completed?!0:this.showConfirmDialog("This panel hasn\u2019t finished yet. Are you sure you want to close it?");return!0})}confirmCloseGroup(group){return!this.confirmOnClose||!group.panels.some(panel=>{for(const state of this.forks.values())if(state.panelId===panel.id&&!state.completed)return!0;return!1})?!0:this.showConfirmDialog("Some panels haven\u2019t finished yet. Are you sure you want to close them?")}showConfirmDialog(message){return new Promise(resolve=>{if(!this.rootElement){resolve(!0);return}const overlay=document.createElement("div");overlay.className="mb-adapt mb-adapt__confirm-overlay",this.darkMode&&overlay.classList.add("mb-adapt--dark");const card=document.createElement("div");card.className="mb-adapt__confirm-card";const text=document.createElement("p");text.className="mb-adapt__confirm-text",text.textContent=message,card.appendChild(text);const buttons=document.createElement("div");buttons.className="mb-adapt__confirm-buttons";const cancelBtn=document.createElement("button");cancelBtn.className="mb-adapt__confirm-btn mb-adapt__confirm-btn--cancel",cancelBtn.textContent="Cancel";const confirmBtn=document.createElement("button");confirmBtn.className="mb-adapt__confirm-btn mb-adapt__confirm-btn--confirm",confirmBtn.textContent="Close",buttons.appendChild(cancelBtn),buttons.appendChild(confirmBtn),card.appendChild(buttons),overlay.appendChild(card),document.body.appendChild(overlay);const cleanup=result=>{overlay.remove(),resolve(result)};cancelBtn.addEventListener("click",()=>cleanup(!1)),confirmBtn.addEventListener("click",()=>cleanup(!0)),overlay.addEventListener("click",e=>{e.target===overlay&&cleanup(!1)})})}async destroy(){this.destroyed=!0,this.mainCloseTimer&&(clearTimeout(this.mainCloseTimer),this.mainCloseTimer=null);for(const state of this.forks.values())state.closeTimer&&(clearTimeout(state.closeTimer),state.closeTimer=null);this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null),this.resizeObserver?.disconnect(),this.resizeObserver=null,this.capWidgetInstance?.destroy(),this.capWidgetInstance=null,this.minimizeManager?.dispose(),this.minimizeManager=null,this.sessionToken&&!this.loadState()&&this.client.stop(this.sessionToken).catch(()=>{}),await this.client.unsubscribe(),this.messageHandler&&window.removeEventListener("message",this.messageHandler),this.panelManager&&(this.panelManager.dispose(),this.panelManager=null),this.rootElement?.parentNode?.removeChild(this.rootElement),this.mainUrl=null,this.mainToken=void 0,this.forks.clear(),this.components.clear(),this.forkPanelHeights.clear(),this.forkGroupActions.clear(),this.floatingToolbars.clear(),this.sessionToken=null,this.lastForkActive=null,this.rootElement=null,this.messageHandler=null,this.statusMessageElement=null,this.minimizedTabsContainer=null}showStatusMessage(text,kind="error"){if(!this.rootElement)return;this.removeStatusMessage();const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&mainComponent.hide(),this.statusMessageElement=document.createElement("div"),this.statusMessageElement.className=this.options.classNames?.statusMessage??"mb-adapt__status-message";const card=document.createElement("div");card.className=this.options.classNames?.statusCard??"mb-adapt__status-card";const iconWrap=document.createElement("div");iconWrap.className=kind==="stopped"||kind==="expired"?"mb-adapt__status-icon mb-adapt__status-icon--stopped":"mb-adapt__status-icon",iconWrap.innerHTML=kind==="stopped"||kind==="expired"?'<svg viewBox="0 0 24 24" fill="none" stroke="#6b7280" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="6" width="12" height="12" rx="2"/></svg>':'<svg viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>',card.appendChild(iconWrap);const msg=document.createElement("p");msg.className="mb-adapt__status-text",msg.textContent=text,card.appendChild(msg);const btn=document.createElement("button");btn.className="mb-adapt__status-restart",btn.textContent=this.options.text?.restartButton??"Try again",btn.addEventListener("click",()=>this.newSession()),card.appendChild(btn),this.statusMessageElement.appendChild(card),this.rootElement.appendChild(this.statusMessageElement)}removeStatusMessage(){this.statusMessageElement&&(this.statusMessageElement.remove(),this.statusMessageElement=null)}showErrorStatus(error){const adaptError=this.classifyError(error),overlayKind=adaptError.kind==="expired"?"expired":"error";this.clearState(),this.clearAllForks(),this.showStatusMessage(adaptError.message,overlayKind),this.options.onError?.(adaptError)}isExpiredTokenError(error){return error instanceof ConnectError&&error.code===Code.PermissionDenied&&error.message.toLowerCase().includes("expired")}getErrorMessage(error){const text=this.options.text,fallback=text?.error??"Something went wrong. Please try again later.";if(error instanceof ConnectError){if(this.isExpiredTokenError(error))return text?.sessionExpired??"Your session has expired.";switch(error.code){case Code.ResourceExhausted:return text?.resourceExhausted??"This automation is currently at capacity. Please try again later.";case Code.NotFound:return error.message.toLowerCase().includes("session not found")?text?.sessionNotFound??"This session has timed out or been stopped.":text?.notFound??"This automation could not be found.";case Code.PermissionDenied:case Code.Unauthenticated:return text?.permissionDenied??"You don't have permission to run this automation.";default:return fallback}}return fallback}classifyError(error){const message=this.getErrorMessage(error);if(error instanceof ConnectError){if(this.isExpiredTokenError(error))return{kind:"expired",message,retriable:!1,cause:error};switch(error.code){case Code.ResourceExhausted:return{kind:"capacity",message,retriable:!0,cause:error};case Code.NotFound:return error.message.toLowerCase().includes("session not found")?{kind:"session_not_found",message,retriable:!1,cause:error}:{kind:"not_found",message,retriable:!1,cause:error};case Code.PermissionDenied:case Code.Unauthenticated:return{kind:"auth",message,retriable:!0,cause:error};default:return{kind:"error",message,retriable:!1,cause:error}}}return{kind:"error",message,retriable:!1,cause:error}}};_AdaptWebClient._capWidgetClass=null;let AdaptWebClient=_AdaptWebClient;export{AdaptAutomationElement,AdaptWebClient,FloatingToolbar2 as FloatingToolbar,ForkGroupActions2 as ForkGroupActions,IframePanelComponent2 as IframePanelComponent,MinimizeManager2 as MinimizeManager,PanelManager2 as PanelManager,clearPersistedState,configure,createConnectClient,resetConfig,resolveTheme2 as resolveTheme};