@mochabug/adapt-web 1.0.1-rc.28 → 1.0.1-rc.29

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
@@ -108,6 +108,8 @@ import '@mochabug/adapt-web/styles.css';
108
108
  | `inherit-token` | Join an existing session |
109
109
  | `challenge-token` | Pre-solved challenge token |
110
110
  | `transmitter` | Transmitter ID |
111
+ | `inherit-from` | JSON object: `{"hash":"mb_session"}` or `{"param":"token"}` |
112
+ | `signals` | JSON object of initial signal values |
111
113
  | `fork-display-mode` | `side-by-side` (default) or `dialog` |
112
114
  | `side-by-side-split` | Split percentage, e.g. `60` |
113
115
  | `dark-mode` | Enable dark mode |
@@ -119,21 +121,45 @@ import '@mochabug/adapt-web/styles.css';
119
121
  | `persist` | Persist session across page refreshes |
120
122
  | `confirm-on-close` | Show a confirmation dialog before the user leaves the page while a session is active |
121
123
 
124
+ Initial JSON options can be written directly on the element:
125
+
126
+ ```html
127
+ <adapt-automation
128
+ automation-id="YOUR_ID"
129
+ inherit-from='{"hash":"mb_session"}'
130
+ signals='{"key":"value"}'
131
+ style="height: 600px"
132
+ ></adapt-automation>
133
+ <script src="https://cdn.mochabug.com/adapt/web/__VERSION__/adapt-web.core.min.js"></script>
134
+ ```
135
+
136
+ For complex values that are easier to build in JavaScript, set properties before loading the bundle:
137
+
138
+ ```html
139
+ <adapt-automation id="automation" automation-id="YOUR_ID" style="height: 600px"></adapt-automation>
140
+ <script>
141
+ const el = document.getElementById('automation');
142
+ el.inheritFrom = { hash: 'mb_session' };
143
+ el.signals = { key: 'value' };
144
+ </script>
145
+ <script src="https://cdn.mochabug.com/adapt/web/__VERSION__/adapt-web.core.min.js"></script>
146
+ ```
147
+
122
148
  ### JS-only properties
123
149
 
124
150
  Set via element reference — not available as HTML attributes.
125
151
 
126
152
  | Property | Type |
127
153
  |----------|------|
128
- | `signals` | `Record<string, SignalValue>` |
129
154
  | `capWidgetOptions` | `{ workerCount?: number; i18n?: CapWidgetI18n }` |
130
- | `inheritFrom` | `{ hash: string } \| { param: string }` |
131
155
  | `classNames` | `{ root?: string; iframe?: string; statusMessage?: string; statusCard?: string }` |
132
156
  | `styles` | `Partial<CSSStyleDeclaration>` |
133
157
  | `persistOptions` | `{ storage?: 'session' \| 'local'; ttl?: number; key?: string }` |
134
158
  | `text` | `StatusText` |
135
159
  | `theme` | `AdaptTheme` |
136
160
 
161
+ `signals` and `inheritFrom` are also available as JS properties. They are initial options; set them before the element initializes.
162
+
137
163
  ### Events
138
164
 
139
165
  | Event | Detail |
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.28/`
9
+ **CDN base:** `https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/`
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.28/adapt-core.min.js"></script>
24
- <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.28/adapt-web.cap.min.js"></script>
23
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/adapt-core.min.js"></script>
24
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/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.28/adapt-web.min.js" as="script">
47
- <link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.28/styles.css">
46
+ <link rel="preload" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/adapt-web.min.js" as="script">
47
+ <link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/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.28/adapt-web.min.js"></script>
51
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/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.28/adapt-web.core.min.js" as="script">
60
- <link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.28/styles.css">
59
+ <link rel="preload" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/adapt-web.core.min.js" as="script">
60
+ <link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/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.28/adapt-web.core.min.js"></script>
64
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/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.28/adapt-web.min.js"></script>
74
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/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.28/adapt-web.core.min.js"></script>
81
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/adapt-web.core.min.js"></script>
82
82
  ```
83
83
 
84
84
  ### ESM
@@ -108,6 +108,8 @@ import '@mochabug/adapt-web/styles.css';
108
108
  | `inherit-token` | Join an existing session |
109
109
  | `challenge-token` | Pre-solved challenge token |
110
110
  | `transmitter` | Transmitter ID |
111
+ | `inherit-from` | JSON object: `{"hash":"mb_session"}` or `{"param":"token"}` |
112
+ | `signals` | JSON object of initial signal values |
111
113
  | `fork-display-mode` | `side-by-side` (default) or `dialog` |
112
114
  | `side-by-side-split` | Split percentage, e.g. `60` |
113
115
  | `dark-mode` | Enable dark mode |
@@ -119,21 +121,45 @@ import '@mochabug/adapt-web/styles.css';
119
121
  | `persist` | Persist session across page refreshes |
120
122
  | `confirm-on-close` | Show a confirmation dialog before the user leaves the page while a session is active |
121
123
 
124
+ Initial JSON options can be written directly on the element:
125
+
126
+ ```html
127
+ <adapt-automation
128
+ automation-id="YOUR_ID"
129
+ inherit-from='{"hash":"mb_session"}'
130
+ signals='{"key":"value"}'
131
+ style="height: 600px"
132
+ ></adapt-automation>
133
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/adapt-web.core.min.js"></script>
134
+ ```
135
+
136
+ For complex values that are easier to build in JavaScript, set properties before loading the bundle:
137
+
138
+ ```html
139
+ <adapt-automation id="automation" automation-id="YOUR_ID" style="height: 600px"></adapt-automation>
140
+ <script>
141
+ const el = document.getElementById('automation');
142
+ el.inheritFrom = { hash: 'mb_session' };
143
+ el.signals = { key: 'value' };
144
+ </script>
145
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/adapt-web.core.min.js"></script>
146
+ ```
147
+
122
148
  ### JS-only properties
123
149
 
124
150
  Set via element reference — not available as HTML attributes.
125
151
 
126
152
  | Property | Type |
127
153
  |----------|------|
128
- | `signals` | `Record<string, SignalValue>` |
129
154
  | `capWidgetOptions` | `{ workerCount?: number; i18n?: CapWidgetI18n }` |
130
- | `inheritFrom` | `{ hash: string } \| { param: string }` |
131
155
  | `classNames` | `{ root?: string; iframe?: string; statusMessage?: string; statusCard?: string }` |
132
156
  | `styles` | `Partial<CSSStyleDeclaration>` |
133
157
  | `persistOptions` | `{ storage?: 'session' \| 'local'; ttl?: number; key?: string }` |
134
158
  | `text` | `StatusText` |
135
159
  | `theme` | `AdaptTheme` |
136
160
 
161
+ `signals` and `inheritFrom` are also available as JS properties. They are initial options; set them before the element initializes.
162
+
137
163
  ### Events
138
164
 
139
165
  | Event | Detail |
@@ -160,12 +186,12 @@ Requires a `client` JS property — set it after the element is in the DOM.
160
186
 
161
187
  ```html
162
188
  <head>
163
- <link rel="preload" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.28/adapt-web.cap.min.js" as="script">
164
- <link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.28/styles.css">
189
+ <link rel="preload" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/adapt-web.cap.min.js" as="script">
190
+ <link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/styles.css">
165
191
  </head>
166
192
  <body>
167
193
  <adapt-cap automation-id="YOUR_ID"></adapt-cap>
168
- <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.28/adapt-web.cap.min.js"></script>
194
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/adapt-web.cap.min.js"></script>
169
195
  <script>
170
196
  var el = document.querySelector('adapt-cap');
171
197
  el.client = MbAdapt.createConnectClient({ id: 'YOUR_ID' });
@@ -180,7 +206,7 @@ Requires a `client` JS property — set it after the element is in the DOM.
180
206
 
181
207
  ```html
182
208
  <adapt-cap automation-id="YOUR_ID"></adapt-cap>
183
- <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.28/adapt-web.cap.min.js"></script>
209
+ <script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.29/adapt-web.cap.min.js"></script>
184
210
  <script>
185
211
  var el = document.querySelector('adapt-cap');
186
212
  el.client = MbAdapt.createConnectClient({ id: 'YOUR_ID' });
@@ -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","debug"],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")}get debug(){return this.hasAttribute("debug")}set debug(v){v?this.setAttribute("debug",""):this.removeAttribute("debug")}async newSession(){this._client&&await this._client.newSession()}initialize(){this._tryInit()}connectedCallback(){requestAnimationFrame(()=>this._tryInit())}disconnectedCallback(){this._destroyClient()}attributeChangedCallback(name,oldValue,newValue){if(oldValue!==newValue){if(name==="automation-id"||name==="persist"||name==="debug"){this._destroyClient(),requestAnimationFrame(()=>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){console.error(`[adapt] <adapt-automation> is missing the required "automation-id" attribute. The element will not initialize. Set it via HTML: <adapt-automation automation-id="..."> or via the Astro/React/Vue component's automationId prop.`);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),this.debug&&(options.debug=!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);const signals=this.signals??this._parseData("adaptSignals"),capWidgetOptions=this.capWidgetOptions??this._parseData("adaptCapWidgetOptions"),inheritFrom=this.inheritFrom??this._parseData("adaptInheritFrom"),classNames=this.classNames??this._parseData("adaptClassNames"),text=this.text??this._parseData("adaptText"),theme=this._theme??this._parseData("adaptTheme"),persistOptions=this.persistOptions??this._parseData("adaptPersistOptions");signals!==void 0&&(options.signals=signals),capWidgetOptions!==void 0&&(options.capWidgetOptions=capWidgetOptions),inheritFrom!==void 0&&(options.inheritFrom=inheritFrom),classNames!==void 0&&(options.classNames=classNames),this.styles!==void 0&&(options.styles=this.styles),text!==void 0&&(options.text=text),theme!==void 0&&(options.theme=theme),persistOptions!==void 0?options.persist=persistOptions:this.persist&&(options.persist=!0),this._client=new AdaptWebClient(options)}_parseData(key){const raw=this.dataset[key];if(raw)try{return JSON.parse(raw)}catch{return}}_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","inherit-from","signals","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","debug"],PRE_UPGRADE_PROPERTIES=["signals","capWidgetOptions","inheritFrom","classNames","styles","persistOptions","text","theme","onSessionCallback","onOutputCallback","onForkActiveCallback","onErrorCallback"],BaseElement=typeof HTMLElement<"u"?HTMLElement:class{};class AdaptAutomationElement extends BaseElement{constructor(){super();this._client=null;for(const property of PRE_UPGRADE_PROPERTIES)this._upgradeProperty(property)}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")}get debug(){return this.hasAttribute("debug")}set debug(v){v?this.setAttribute("debug",""):this.removeAttribute("debug")}async newSession(){this._client&&await this._client.newSession()}initialize(){this._tryInit()}connectedCallback(){requestAnimationFrame(()=>this._tryInit())}disconnectedCallback(){this._destroyClient()}attributeChangedCallback(name,oldValue,newValue){if(oldValue!==newValue){if(name==="automation-id"||name==="persist"||name==="debug"){this._destroyClient(),requestAnimationFrame(()=>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}}}_upgradeProperty(property){if(!Object.prototype.hasOwnProperty.call(this,property))return;const element=this,value=element[property];delete element[property],element[property]=value}_tryInit(){if(this._client||!this.isConnected)return;const automationId=this.automationId;if(!automationId){console.error(`[adapt] <adapt-automation> is missing the required "automation-id" attribute. The element will not initialize. Set it via HTML: <adapt-automation automation-id="..."> or via the Astro/React/Vue component's automationId prop.`);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),this.debug&&(options.debug=!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);const signals=this.signals??this._parseJsonAttributeOrData("signals","adaptSignals",this._isSignals),capWidgetOptions=this.capWidgetOptions??this._parseData("adaptCapWidgetOptions"),inheritFrom=this.inheritFrom??this._parseJsonAttributeOrData("inherit-from","adaptInheritFrom",this._isInheritFrom),classNames=this.classNames??this._parseData("adaptClassNames"),text=this.text??this._parseData("adaptText"),theme=this._theme??this._parseData("adaptTheme"),persistOptions=this.persistOptions??this._parseData("adaptPersistOptions");signals!==void 0&&(options.signals=signals),capWidgetOptions!==void 0&&(options.capWidgetOptions=capWidgetOptions),inheritFrom!==void 0&&(options.inheritFrom=inheritFrom),classNames!==void 0&&(options.classNames=classNames),this.styles!==void 0&&(options.styles=this.styles),text!==void 0&&(options.text=text),theme!==void 0&&(options.theme=theme),persistOptions!==void 0?options.persist=persistOptions:this.persist&&(options.persist=!0),this._client=new AdaptWebClient(options)}_parseData(key){const raw=this.dataset[key];if(raw)try{return JSON.parse(raw)}catch{return}}_parseJsonAttributeOrData(attributeName,dataKey,validate){return this.hasAttribute(attributeName)?this._parseJsonAttribute(attributeName,validate):this._parseData(dataKey)}_parseJsonAttribute(name,validate){const raw=this.getAttribute(name);if(raw===null)return;let parsed;try{parsed=JSON.parse(raw)}catch{console.warn(`[adapt] Ignoring invalid JSON in <adapt-automation ${name}=...>.`);return}if(!validate(parsed)){console.warn(`[adapt] Ignoring invalid <adapt-automation ${name}=...> value.`);return}return parsed}_isSignals(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}_isInheritFrom(value){if(typeof value!="object"||value===null||Array.isArray(value))return!1;const candidate=value,hasHash=typeof candidate.hash=="string",hasParam=typeof candidate.param=="string";return hasHash!==hasParam}_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
- import{AdaptCapWidget}from"./AdaptCapWidget.js";const OBSERVED_ATTRIBUTES=["automation-id","dark-mode","worker-count"],BaseElement=typeof HTMLElement<"u"?HTMLElement:class{};class AdaptCapElement extends BaseElement{constructor(){super();this._widget=null}static get observedAttributes(){return OBSERVED_ATTRIBUTES}get client(){return this._client}set client(v){this._client=v,this._destroyWidget(),this._tryInit()}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")}connectedCallback(){this._tryInit()}disconnectedCallback(){this._destroyWidget()}attributeChangedCallback(name,oldValue,newValue){if(oldValue!==newValue){if(name==="automation-id"){this._destroyWidget(),this._tryInit();return}if(name==="dark-mode"){this._widget?.setDarkMode(this.darkMode);return}}}_tryInit(){if(this._widget||!this.isConnected)return;const automationId=this.automationId;if(!automationId){console.error('[adapt] <adapt-cap> is missing the required "automation-id" attribute. The element will not initialize.');return}if(!this._client){console.error('[adapt] <adapt-cap> is missing the required "client" property. Set it via JavaScript: el.client = createConnectClient({ id: "..." })');return}const workerCountAttr=this.getAttribute("worker-count");this._widget=new AdaptCapWidget({container:this,automationId,client:this._client,onSolve:(token,expires)=>{this.onSolveCallback?.(token,expires),this.dispatchEvent(new CustomEvent("adapt-cap-solve",{detail:{token,expires},bubbles:!0}))},onError:error=>{this.onErrorCallback?.(error),this.dispatchEvent(new CustomEvent("adapt-cap-error",{detail:{error},bubbles:!0}))},...workerCountAttr!==null&&{workerCount:Number(workerCountAttr)},...this.i18n!==void 0&&{i18n:this.i18n}}),this.darkMode&&this._widget.setDarkMode(!0)}_destroyWidget(){this._widget&&(this._widget.destroy(),this._widget=null)}}if(typeof customElements<"u"&&!customElements.get("adapt-cap")){customElements.define("adapt-cap",AdaptCapElement);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{AdaptCapElement};
1
+ import{AdaptCapWidget}from"./AdaptCapWidget.js";const OBSERVED_ATTRIBUTES=["automation-id","dark-mode","worker-count","hidden-field-name","troubleshooting-url","disable-haptics"],BaseElement=typeof HTMLElement<"u"?HTMLElement:class{};class AdaptCapElement extends BaseElement{constructor(){super();this._widget=null}static get observedAttributes(){return OBSERVED_ATTRIBUTES}get client(){return this._client}set client(v){this._client=v,this._destroyWidget(),this._tryInit()}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")}connectedCallback(){this._tryInit()}disconnectedCallback(){this._destroyWidget()}attributeChangedCallback(name,oldValue,newValue){if(oldValue!==newValue){if(name==="automation-id"){this._destroyWidget(),this._tryInit();return}if(name==="dark-mode"){this._widget?.setDarkMode(this.darkMode);return}(name==="worker-count"||name==="hidden-field-name"||name==="troubleshooting-url"||name==="disable-haptics")&&(this._destroyWidget(),this._tryInit())}}_tryInit(){if(this._widget||!this.isConnected)return;const automationId=this.automationId;if(!automationId){console.error('[adapt] <adapt-cap> is missing the required "automation-id" attribute. The element will not initialize.');return}if(!this._client){console.error('[adapt] <adapt-cap> is missing the required "client" property. Set it via JavaScript: el.client = createConnectClient({ id: "..." })');return}const workerCountAttr=this.getAttribute("worker-count"),hiddenFieldName=this.getAttribute("hidden-field-name"),troubleshootingUrl=this.getAttribute("troubleshooting-url");this._widget=new AdaptCapWidget({container:this,automationId,client:this._client,onSolve:(token,expires)=>{this.onSolveCallback?.(token,expires),this.dispatchEvent(new CustomEvent("adapt-cap-solve",{detail:{token,expires},bubbles:!0}))},onError:error=>{this.onErrorCallback?.(error),this.dispatchEvent(new CustomEvent("adapt-cap-error",{detail:{error},bubbles:!0}))},...workerCountAttr!==null&&{workerCount:Number(workerCountAttr)},...hiddenFieldName&&{hiddenFieldName},...troubleshootingUrl&&{troubleshootingUrl},...this.hasAttribute("disable-haptics")&&{disableHaptics:!0},...this.i18n!==void 0&&{i18n:this.i18n}}),this.darkMode&&this._widget.setDarkMode(!0)}_destroyWidget(){this._widget&&(this._widget.destroy(),this._widget=null)}}if(typeof customElements<"u"&&!customElements.get("adapt-cap")){customElements.define("adapt-cap",AdaptCapElement);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{AdaptCapElement};
@@ -1 +1 @@
1
- import{setupCapAdapter,cleanupCapAdapter,takeRedeemedChallengeExpiration}from"./cap-adapter.js";import{CAP_WIDGET_CSS}from"./css-cap.js";import"@cap.js/widget";class AdaptCapWidget{constructor(options){this.widgetContainer=null;this.widgetElement=null;this.destroyed=!1;if(!options.automationId)throw new Error('[adapt] AdaptCapWidget requires "automationId".');if(!options.client)throw new Error('[adapt] AdaptCapWidget requires "client". Create one with: createConnectClient({ id: "..." })');if(!options.onSolve)throw new Error('[adapt] AdaptCapWidget requires "onSolve" callback.');this.options=options;const container=typeof options.container=="string"?document.getElementById(options.container):options.container;if(!container)throw new Error(`Container ${typeof options.container=="string"?`with id '${options.container}'`:""} not found`);this.containerElement=container,this.injectStyles(),setupCapAdapter(options.client,options.automationId),this.mountWidget()}injectStyles(){if(getComputedStyle(document.documentElement).getPropertyValue("--mb-adapt-styles-loaded").trim()||document.getElementById("mb-adapt-cap-styles"))return;const style=document.createElement("style");style.id="mb-adapt-cap-styles",style.textContent=CAP_WIDGET_CSS,document.head.appendChild(style)}mountWidget(){this.widgetContainer=document.createElement("div"),this.widgetContainer.className="mb-adapt-cap";const innerContainer=document.createElement("div");if(innerContainer.className="mb-adapt-cap__container",this.widgetElement=document.createElement("cap-widget"),this.widgetElement.setAttribute("data-cap-api-endpoint",`/adapt-cap-${this.options.automationId}/`),this.options.workerCount&&this.widgetElement.setAttribute("data-cap-worker-count",String(this.options.workerCount)),this.options.i18n){const{i18n}=this.options;i18n.verifyingLabel&&this.widgetElement.setAttribute("data-cap-i18n-verifying-label",i18n.verifyingLabel),i18n.initialState&&this.widgetElement.setAttribute("data-cap-i18n-initial-state",i18n.initialState),i18n.solvedLabel&&this.widgetElement.setAttribute("data-cap-i18n-solved-label",i18n.solvedLabel),i18n.errorLabel&&this.widgetElement.setAttribute("data-cap-i18n-error-label",i18n.errorLabel)}this.widgetElement.addEventListener("solve",(e=>{if(this.destroyed)return;const token=e.detail?.token,expiresStr=e.detail?.expires,expires=takeRedeemedChallengeExpiration(this.options.automationId)??(expiresStr?new Date(expiresStr):new Date);setTimeout(()=>this.destroy(),0),token?this.options.onSolve(token,expires):this.options.onError?.(new Error("No token received from Cap.js"))})),this.widgetElement.addEventListener("error",(e=>{this.destroyed||(console.error("[AdaptCapWidget] Cap.js error:",e.detail),setTimeout(()=>this.destroy(),0),this.options.onError?.(new Error(e.detail?.message||"Cap.js error")))})),innerContainer.appendChild(this.widgetElement),this.widgetContainer.appendChild(innerContainer),this.containerElement.appendChild(this.widgetContainer)}setDarkMode(dark){this.widgetContainer&&(dark?this.widgetContainer.classList.add("mb-adapt-cap--dark"):this.widgetContainer.classList.remove("mb-adapt-cap--dark"))}destroy(){this.destroyed||(this.destroyed=!0,cleanupCapAdapter(),this.widgetContainer&&this.widgetContainer.parentNode&&this.widgetContainer.parentNode.removeChild(this.widgetContainer),this.widgetContainer=null,this.widgetElement=null)}}export{AdaptCapWidget};
1
+ import{setupCapAdapter,cleanupCapAdapter,takeRedeemedChallengeExpiration}from"./cap-adapter.js";import{CAP_WIDGET_CSS}from"./css-cap.js";import"@cap.js/widget";class AdaptCapWidget{constructor(options){this.widgetContainer=null;this.widgetElement=null;this.destroyed=!1;if(!options.automationId)throw new Error('[adapt] AdaptCapWidget requires "automationId".');if(!options.client)throw new Error('[adapt] AdaptCapWidget requires "client". Create one with: createConnectClient({ id: "..." })');if(!options.onSolve)throw new Error('[adapt] AdaptCapWidget requires "onSolve" callback.');this.options=options;const container=typeof options.container=="string"?document.getElementById(options.container):options.container;if(!container)throw new Error(`Container ${typeof options.container=="string"?`with id '${options.container}'`:""} not found`);this.containerElement=container,this.injectStyles(),setupCapAdapter(options.client,options.automationId),this.mountWidget()}injectStyles(){if(getComputedStyle(document.documentElement).getPropertyValue("--mb-adapt-styles-loaded").trim()||document.getElementById("mb-adapt-cap-styles"))return;const style=document.createElement("style");style.id="mb-adapt-cap-styles",style.textContent=CAP_WIDGET_CSS,document.head.appendChild(style)}mountWidget(){this.widgetContainer=document.createElement("div"),this.widgetContainer.className="mb-adapt-cap";const innerContainer=document.createElement("div");if(innerContainer.className="mb-adapt-cap__container",this.widgetElement=document.createElement("cap-widget"),this.widgetElement.setAttribute("data-cap-api-endpoint",`/adapt-cap-${this.options.automationId}/`),this.options.workerCount&&this.widgetElement.setAttribute("data-cap-worker-count",String(this.options.workerCount)),this.options.hiddenFieldName&&this.widgetElement.setAttribute("data-cap-hidden-field-name",this.options.hiddenFieldName),this.options.troubleshootingUrl&&this.widgetElement.setAttribute("data-cap-troubleshooting-url",this.options.troubleshootingUrl),this.options.disableHaptics&&this.widgetElement.setAttribute("data-cap-disable-haptics",""),this.options.i18n){const i18nAttributes=[["initialState","data-cap-i18n-initial-state"],["verifyingLabel","data-cap-i18n-verifying-label"],["solvedLabel","data-cap-i18n-solved-label"],["errorLabel","data-cap-i18n-error-label"],["troubleshootingLabel","data-cap-i18n-troubleshooting-label"],["wasmDisabled","data-cap-i18n-wasm-disabled"],["verifyAriaLabel","data-cap-i18n-verify-aria-label"],["verifyingAriaLabel","data-cap-i18n-verifying-aria-label"],["verifiedAriaLabel","data-cap-i18n-verified-aria-label"],["requiredLabel","data-cap-i18n-required-label"],["errorAriaLabel","data-cap-i18n-error-aria-label"]];for(const[key,attribute]of i18nAttributes){const value=this.options.i18n[key];value&&this.widgetElement.setAttribute(attribute,value)}}this.widgetElement.addEventListener("solve",(e=>{if(this.destroyed)return;const token=e.detail?.token,expiresStr=e.detail?.expires,expires=takeRedeemedChallengeExpiration(this.options.automationId)??(expiresStr?new Date(expiresStr):new Date);setTimeout(()=>this.destroy(),0),token?this.options.onSolve(token,expires):this.options.onError?.(new Error("No token received from Cap.js"))})),this.widgetElement.addEventListener("error",(e=>{this.destroyed||(console.error("[AdaptCapWidget] Cap.js error:",e.detail),setTimeout(()=>this.destroy(),0),this.options.onError?.(new Error(e.detail?.message||"Cap.js error")))})),innerContainer.appendChild(this.widgetElement),this.widgetContainer.appendChild(innerContainer),this.containerElement.appendChild(this.widgetContainer),this.hideCapAttribution()}hideCapAttribution(){const hide=()=>{if(this.destroyed||!this.widgetElement)return;const attribution=this.widgetElement.shadowRoot?.querySelector('[part="attribution"], .credits');attribution&&(attribution.style.setProperty("display","none","important"),attribution.style.setProperty("visibility","hidden","important"),attribution.style.setProperty("pointer-events","none","important"),attribution.setAttribute("aria-hidden","true"),attribution.setAttribute("tabindex","-1"))};hide(),queueMicrotask(hide),setTimeout(hide,0)}setDarkMode(dark){this.widgetContainer&&(dark?this.widgetContainer.classList.add("mb-adapt-cap--dark"):this.widgetContainer.classList.remove("mb-adapt-cap--dark"))}destroy(){this.destroyed||(this.destroyed=!0,cleanupCapAdapter(),this.widgetContainer&&this.widgetContainer.parentNode&&this.widgetContainer.parentNode.removeChild(this.widgetContainer),this.widgetContainer=null,this.widgetElement=null)}}export{AdaptCapWidget};
@@ -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.28/cap_wasm_bg.wasm",window.location.href).href);import{timestampDate}from"@bufbuild/protobuf/wkt";let currentClient=null,currentAutomationId=null;const verificationTokens=new Map,redeemedChallengeExpirations=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}}function takeRedeemedChallengeExpiration(automationId){const expires=redeemedChallengeExpirations.get(automationId)??null;return expires&&redeemedChallengeExpirations.delete(automationId),expires}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),redeemedChallengeExpirations.delete(currentAutomationId),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 redeemedChallengeExpirations.set(currentAutomationId,redeemed.expires),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){currentAutomationId&&currentAutomationId!==automationId&&(verificationTokens.delete(currentAutomationId),redeemedChallengeExpirations.delete(currentAutomationId)),currentClient=client,currentAutomationId=automationId,redeemedChallengeExpirations.delete(automationId)}function cleanupCapAdapter(){currentAutomationId&&(verificationTokens.delete(currentAutomationId),redeemedChallengeExpirations.delete(currentAutomationId)),currentClient=null,currentAutomationId=null}export{cleanupCapAdapter,createChallenge,redeemChallenge,setupCapAdapter,takeRedeemedChallengeExpiration};
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.29/cap_wasm_bg.wasm",window.location.href).href);import{timestampDate}from"@bufbuild/protobuf/wkt";let currentClient=null,currentAutomationId=null;const verificationTokens=new Map,redeemedChallengeExpirations=new Map;async function createChallenge(client,id){const response=await client.createChallenge({id}),instrumentation=response.instrumentation;return{count:response.count,size:response.size,difficulty:response.difficulty,expires:response.expires?timestampDate(response.expires):new Date,token:response.token,verificationToken:response.verificationToken,...instrumentation?{instrumentation}:{}}}async function redeemChallenge(client,id,verificationToken,solutions,options={}){const request={id,verificationToken,solutions,...options.instrumentation?{instrumentation:options.instrumentation}:{},...options.instrumentationBlocked?{instrumentationBlocked:!0}:{},...options.instrumentationTimeout?{instrumentationTimeout:!0}:{}},response=await client.redeemChallenge(request);return{token:response.token,expires:response.expires?timestampDate(response.expires):new Date}}function takeRedeemedChallengeExpiration(automationId){const expires=redeemedChallengeExpirations.get(automationId)??null;return expires&&redeemedChallengeExpirations.delete(automationId),expires}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),redeemedChallengeExpirations.delete(currentAutomationId),new Response(JSON.stringify({challenge:{c:challengeInfo.count,s:challengeInfo.size,d:challengeInfo.difficulty},token:challengeInfo.token,expires:challengeInfo.expires.toISOString(),...challengeInfo.instrumentation?{instrumentation:challengeInfo.instrumentation}:{}}),{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 body=options?.body?JSON.parse(options.body):{},solutions=(body.solutions||[]).map(s=>BigInt(s)),instrumentationBlocked=body.instr_blocked===!0||body.instr?.__blocked===!0,instrumentationTimeout=body.instr_timeout===!0||body.instr?.__timeout===!0,instrumentation=body.instr&&!instrumentationBlocked&&!instrumentationTimeout?body.instr:void 0,redeemed=await redeemChallenge(currentClient,currentAutomationId,verificationToken,solutions,{...instrumentation?{instrumentation}:{},...instrumentationBlocked?{instrumentationBlocked}:{},...instrumentationTimeout?{instrumentationTimeout}:{}});return redeemedChallengeExpirations.set(currentAutomationId,redeemed.expires),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){currentAutomationId&&currentAutomationId!==automationId&&(verificationTokens.delete(currentAutomationId),redeemedChallengeExpirations.delete(currentAutomationId)),currentClient=client,currentAutomationId=automationId,redeemedChallengeExpirations.delete(automationId)}function cleanupCapAdapter(){currentAutomationId&&(verificationTokens.delete(currentAutomationId),redeemedChallengeExpirations.delete(currentAutomationId)),currentClient=null,currentAutomationId=null}export{cleanupCapAdapter,createChallenge,redeemChallenge,setupCapAdapter,takeRedeemedChallengeExpiration};
@@ -24,6 +24,8 @@ const CAP_WIDGET_CSS=`/* ============================================
24
24
  /* Spinner */
25
25
  --mb-cap-spinner-color: #6366f1;
26
26
  --mb-cap-spinner-bg: #e5e7eb;
27
+ --mb-cap-invalid-border-color: #f55b50;
28
+ --mb-cap-invalid-ring-color: rgba(245, 91, 80, 0.2);
27
29
 
28
30
  /* Typography */
29
31
  --mb-cap-font: inherit;
@@ -80,10 +82,21 @@ const CAP_WIDGET_CSS=`/* ============================================
80
82
  --cap-spinner-color: var(--mb-cap-spinner-color);
81
83
  --cap-spinner-background-color: var(--mb-cap-spinner-bg);
82
84
  --cap-spinner-thickness: 3px;
85
+ --cap-invalid-border-color: var(--mb-cap-invalid-border-color);
86
+ --cap-invalid-ring-color: var(--mb-cap-invalid-ring-color);
83
87
 
84
88
  display: block;
85
89
  }
86
90
 
91
+ /* Hide Cap.js credits. Cap's shadow CSS marks credits as display:block!important,
92
+ so keep this in the standalone CAP stylesheet and reinforce it at runtime. */
93
+ .mb-adapt-cap cap-widget::part(attribution),
94
+ cap-widget::part(attribution) {
95
+ display: none !important;
96
+ visibility: hidden !important;
97
+ pointer-events: none !important;
98
+ }
99
+
87
100
  /* Responsive */
88
101
  @media (max-width: 380px) {
89
102
  .mb-adapt-cap {
@@ -52,6 +52,8 @@ const PANEL_MANAGER_CSS=`/* ====================================================
52
52
  --_cap-spinner-bg: var(--mb-adapt-cap-spinner-bg, #e2e8f0);
53
53
  --_cap-font: var(--mb-adapt-cap-font, inherit);
54
54
  --_cap-spinner-thickness: var(--mb-adapt-cap-spinner-thickness, 3px);
55
+ --_cap-invalid-border-color: var(--mb-adapt-cap-invalid-border-color, #f55b50);
56
+ --_cap-invalid-ring-color: var(--mb-adapt-cap-invalid-ring-color, rgba(245, 91, 80, 0.2));
55
57
  --_cap-shadow: var(--mb-adapt-cap-shadow, 0 4px 20px rgba(0, 0, 0, 0.08), 0 2px 8px rgba(0, 0, 0, 0.04));
56
58
  --_cap-shadow-hover: var(--mb-adapt-cap-shadow-hover, 0 8px 30px rgba(0, 0, 0, 0.12), 0 4px 12px rgba(0, 0, 0, 0.06));
57
59
 
@@ -621,11 +623,15 @@ const PANEL_MANAGER_CSS=`/* ====================================================
621
623
  --cap-spinner-color: var(--_cap-spinner-color);
622
624
  --cap-spinner-background-color: var(--_cap-spinner-bg);
623
625
  --cap-spinner-thickness: var(--_cap-spinner-thickness);
626
+ --cap-invalid-border-color: var(--_cap-invalid-border-color);
627
+ --cap-invalid-ring-color: var(--_cap-invalid-ring-color);
624
628
  }
625
629
 
626
630
  /* Hide Cap.js credits */
627
631
  cap-widget::part(attribution) {
628
- display: none;
632
+ display: none !important;
633
+ visibility: hidden !important;
634
+ pointer-events: none !important;
629
635
  }
630
636
 
631
637
  /* \u2500\u2500 Fork group action buttons \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 */