@drip-apex/sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +46 -0
- package/dist/_headers +3 -0
- package/dist/bundle-report.json +564 -0
- package/dist/drip.debug.js +2 -0
- package/dist/drip.debug.js.map +1 -0
- package/dist/drip.heatmap.js +2 -0
- package/dist/drip.heatmap.js.map +1 -0
- package/dist/drip.js +2 -0
- package/dist/drip.js.map +1 -0
- package/dist/drip.live.js +2 -0
- package/dist/drip.live.js.map +1 -0
- package/dist/editor.js +480 -0
- package/dist/editor.js.map +7 -0
- package/dist/index.mjs +645 -0
- package/dist/index.mjs.map +7 -0
- package/dist/metafiles/drip.debug.meta.json +973 -0
- package/dist/metafiles/drip.heatmap.meta.json +918 -0
- package/dist/metafiles/drip.live.meta.json +918 -0
- package/dist/metafiles/drip.meta.json +973 -0
- package/dist/metafiles/editor.meta.json +321 -0
- package/dist/metafiles/index.meta.json +1039 -0
- package/dist/metafiles/index.mjs.meta.json +78 -0
- package/dist/react/index.js +16973 -0
- package/dist/react/index.js.map +7 -0
- package/dist/sri.json +27 -0
- package/dist/types/analytics.d.ts +15 -0
- package/dist/types/antiflicker.d.ts +14 -0
- package/dist/types/assignment-store.d.ts +30 -0
- package/dist/types/audit.d.ts +9 -0
- package/dist/types/bucket.d.ts +2 -0
- package/dist/types/bucketing-cleanup.d.ts +5 -0
- package/dist/types/commerce-gift.d.ts +41 -0
- package/dist/types/commerce-price.d.ts +22 -0
- package/dist/types/commerce-shipping.d.ts +28 -0
- package/dist/types/css.d.ts +5 -0
- package/dist/types/cwv.d.ts +10 -0
- package/dist/types/data-layer-normalize.d.ts +1 -0
- package/dist/types/debug.d.ts +23 -0
- package/dist/types/define.d.ts +87 -0
- package/dist/types/devtools.d.ts +32 -0
- package/dist/types/dom-trigger.d.ts +3 -0
- package/dist/types/editor/api.d.ts +37 -0
- package/dist/types/editor/artifacts.d.ts +15 -0
- package/dist/types/editor/command-runtime.d.ts +48 -0
- package/dist/types/editor/controller.d.ts +97 -0
- package/dist/types/editor/device-preview.d.ts +23 -0
- package/dist/types/editor/index.d.ts +9 -0
- package/dist/types/editor/operator.d.ts +39 -0
- package/dist/types/editor/picker.d.ts +23 -0
- package/dist/types/editor/selector.d.ts +2 -0
- package/dist/types/editor/types.d.ts +55 -0
- package/dist/types/editor/view-kit.d.ts +33 -0
- package/dist/types/editor/view.d.ts +5 -0
- package/dist/types/editor-bootstrap.d.ts +37 -0
- package/dist/types/exclusion-groups.d.ts +59 -0
- package/dist/types/exposure-signals.d.ts +7 -0
- package/dist/types/flags.d.ts +65 -0
- package/dist/types/goals.d.ts +16 -0
- package/dist/types/guards.d.ts +39 -0
- package/dist/types/handover.d.ts +10 -0
- package/dist/types/hash.d.ts +19 -0
- package/dist/types/heatmap.d.ts +8 -0
- package/dist/types/hideflicker.d.ts +15 -0
- package/dist/types/hydration.d.ts +11 -0
- package/dist/types/index.d.ts +144 -0
- package/dist/types/js.d.ts +6 -0
- package/dist/types/module.d.ts +4 -0
- package/dist/types/money.d.ts +14 -0
- package/dist/types/mutate.d.ts +34 -0
- package/dist/types/observer-mute.d.ts +3 -0
- package/dist/types/pii-keys.d.ts +1 -0
- package/dist/types/prerequisites.d.ts +12 -0
- package/dist/types/qa-assistant-state.d.ts +68 -0
- package/dist/types/qa-assistant-view.d.ts +6 -0
- package/dist/types/qa-assistant.d.ts +9 -0
- package/dist/types/qa-toolbar.d.ts +19 -0
- package/dist/types/react/index.d.ts +84 -0
- package/dist/types/reassert-sentinel.d.ts +6 -0
- package/dist/types/router.d.ts +9 -0
- package/dist/types/runtime-tools.d.ts +50 -0
- package/dist/types/runtime.d.ts +22 -0
- package/dist/types/safe-regex.d.ts +6 -0
- package/dist/types/sanitize.d.ts +5 -0
- package/dist/types/semantic.d.ts +7 -0
- package/dist/types/shopify-cart-events.d.ts +7 -0
- package/dist/types/shopify-cart.d.ts +62 -0
- package/dist/types/signals.d.ts +31 -0
- package/dist/types/surface-signals.d.ts +6 -0
- package/dist/types/targeting-diagnostics.d.ts +5 -0
- package/dist/types/targeting.d.ts +50 -0
- package/dist/types/test-fixtures/commerce.d.ts +12 -0
- package/dist/types/track.d.ts +79 -0
- package/dist/types/types.d.ts +859 -0
- package/dist/types/wait.d.ts +7 -0
- package/package.json +74 -0
- package/src/analytics.ts +146 -0
- package/src/antiflicker.test.ts +127 -0
- package/src/antiflicker.ts +147 -0
- package/src/assignment-store.test.ts +171 -0
- package/src/assignment-store.ts +208 -0
- package/src/audit.test.ts +17 -0
- package/src/audit.ts +362 -0
- package/src/bucket.test.ts +65 -0
- package/src/bucket.ts +18 -0
- package/src/bucketing-cleanup.test.ts +30 -0
- package/src/bucketing-cleanup.ts +72 -0
- package/src/bucketing-parity.test.ts +41 -0
- package/src/commerce-analytics-lifecycle.test.ts +1416 -0
- package/src/commerce-config-lifecycle.test.ts +274 -0
- package/src/commerce-epoch-lifecycle.test.ts +62 -0
- package/src/commerce-gift.test.ts +1293 -0
- package/src/commerce-gift.ts +979 -0
- package/src/commerce-offers-display.test.ts +154 -0
- package/src/commerce-price.test.ts +1145 -0
- package/src/commerce-price.ts +941 -0
- package/src/commerce-revocation-lifecycle.test.ts +78 -0
- package/src/commerce-shipping.test.ts +630 -0
- package/src/commerce-shipping.ts +447 -0
- package/src/config-fetch.test.ts +325 -0
- package/src/css.ts +54 -0
- package/src/cwv.test.ts +95 -0
- package/src/cwv.ts +129 -0
- package/src/data-layer-normalize.ts +21 -0
- package/src/debug.test.ts +83 -0
- package/src/debug.ts +138 -0
- package/src/define.test.ts +327 -0
- package/src/define.ts +208 -0
- package/src/devtools.ts +582 -0
- package/src/dom-trigger.test.ts +70 -0
- package/src/dom-trigger.ts +55 -0
- package/src/editor/api.test.ts +154 -0
- package/src/editor/api.ts +185 -0
- package/src/editor/artifacts.test.ts +57 -0
- package/src/editor/artifacts.ts +115 -0
- package/src/editor/command-runtime.test.ts +225 -0
- package/src/editor/command-runtime.ts +572 -0
- package/src/editor/controller.test.ts +371 -0
- package/src/editor/controller.ts +596 -0
- package/src/editor/device-preview.test.ts +60 -0
- package/src/editor/device-preview.ts +120 -0
- package/src/editor/index.test.ts +161 -0
- package/src/editor/index.ts +169 -0
- package/src/editor/operator.test.ts +148 -0
- package/src/editor/operator.ts +256 -0
- package/src/editor/picker.test.ts +58 -0
- package/src/editor/picker.ts +152 -0
- package/src/editor/selector.test.ts +44 -0
- package/src/editor/selector.ts +110 -0
- package/src/editor/types.ts +92 -0
- package/src/editor/view-kit.ts +162 -0
- package/src/editor/view.test.ts +535 -0
- package/src/editor/view.ts +1395 -0
- package/src/editor-bootstrap.test.ts +116 -0
- package/src/editor-bootstrap.ts +213 -0
- package/src/event-schema-contract.test.ts +35 -0
- package/src/exclusion-groups.test.ts +383 -0
- package/src/exclusion-groups.ts +270 -0
- package/src/exposure-signals.test.ts +182 -0
- package/src/exposure-signals.ts +110 -0
- package/src/flags.test.ts +322 -0
- package/src/flags.ts +201 -0
- package/src/goals.test.ts +42 -0
- package/src/goals.ts +200 -0
- package/src/guards.test.ts +249 -0
- package/src/guards.ts +250 -0
- package/src/handover-cache-order.test.ts +32 -0
- package/src/handover.test.ts +349 -0
- package/src/handover.ts +309 -0
- package/src/hash.ts +214 -0
- package/src/heatmap.test.ts +305 -0
- package/src/heatmap.ts +373 -0
- package/src/hideflicker.ts +21 -0
- package/src/hydration.test.ts +252 -0
- package/src/hydration.ts +203 -0
- package/src/index.ts +7513 -0
- package/src/init-empty.test.ts +5572 -0
- package/src/js.test.ts +26 -0
- package/src/js.ts +61 -0
- package/src/module.ts +50 -0
- package/src/money.test.ts +35 -0
- package/src/money.ts +53 -0
- package/src/mutate.test.ts +304 -0
- package/src/mutate.ts +469 -0
- package/src/observer-mute.test.ts +88 -0
- package/src/observer-mute.ts +45 -0
- package/src/page-trigger.test.ts +84 -0
- package/src/personalization.test.ts +68 -0
- package/src/pii-keys.ts +17 -0
- package/src/prerequisites.test.ts +39 -0
- package/src/prerequisites.ts +94 -0
- package/src/qa-assistant-state.test.ts +471 -0
- package/src/qa-assistant-state.ts +505 -0
- package/src/qa-assistant-view.test.ts +185 -0
- package/src/qa-assistant-view.ts +768 -0
- package/src/qa-assistant.ts +40 -0
- package/src/qa-toolbar.ts +444 -0
- package/src/react/index.test.tsx +177 -0
- package/src/react/index.tsx +252 -0
- package/src/reassert-sentinel.test.ts +314 -0
- package/src/reassert-sentinel.ts +191 -0
- package/src/router.test.ts +78 -0
- package/src/router.ts +92 -0
- package/src/runtime-tools.test.ts +112 -0
- package/src/runtime-tools.ts +403 -0
- package/src/runtime.test.ts +217 -0
- package/src/runtime.ts +268 -0
- package/src/safe-regex.ts +35 -0
- package/src/sanitize.ts +34 -0
- package/src/semantic.ts +245 -0
- package/src/shopify-cart-events.test.ts +76 -0
- package/src/shopify-cart-events.ts +115 -0
- package/src/shopify-cart.test.ts +2823 -0
- package/src/shopify-cart.ts +1256 -0
- package/src/signals.ts +226 -0
- package/src/surface-signals.test.ts +83 -0
- package/src/surface-signals.ts +165 -0
- package/src/targeting-diagnostics.ts +560 -0
- package/src/targeting.detailed.test.ts +443 -0
- package/src/targeting.test.ts +1054 -0
- package/src/targeting.ts +1024 -0
- package/src/test-fixtures/commerce.ts +65 -0
- package/src/track.test.ts +817 -0
- package/src/track.ts +519 -0
- package/src/types.ts +991 -0
- package/src/wait.test.ts +96 -0
- package/src/wait.ts +238 -0
package/dist/editor.js
ADDED
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
"use strict";var ApexEditor=(()=>{var qt=Object.defineProperty;var mr=Object.getOwnPropertyDescriptor;var gr=Object.getOwnPropertyNames;var vr=Object.prototype.hasOwnProperty;var br=(r,t)=>{for(var e in t)qt(r,e,{get:t[e],enumerable:!0})},xr=(r,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of gr(t))!vr.call(r,n)&&n!==e&&qt(r,n,{get:()=>t[n],enumerable:!(i=mr(t,n))||i.enumerable});return r};var yr=r=>xr(qt({},"__esModule",{value:!0}),r);var gi={};br(gi,{__test:()=>mi,getActiveEditorSession:()=>hi,start:()=>fi});var H=class extends Error{constructor(e,i,n){super(e);this.status=i;this.payload=n}};function Z(r){return r&&typeof r=="object"&&!Array.isArray(r)?r:null}function ke(r){let t=Z(r)??{};return{mutations:Array.isArray(t.mutations)?t.mutations:[],customCss:typeof t.customCss=="string"?t.customCss:"",customJs:typeof t.customJs=="string"?t.customJs:""}}var wr=new Set(["navigate","reload","back","forward","click","type","wait_for","snapshot","screenshot","eval_readonly","console_logs","network_logs","network_probe","current_url","select_element","apply_artifacts"]),X=class{constructor(t,e,i=(...n)=>fetch(...n)){this.apiOrigin=t;this.session=e;this.fetchImpl=i}url(t,e){let i=new URL(t,this.apiOrigin);return e&&i.searchParams.set("variationId",e),i.toString()}async request(t,e){let i=await this.fetchImpl(t,{...e,credentials:"omit",cache:"no-store",referrerPolicy:"no-referrer",headers:{Authorization:`Bearer ${this.session.bearer}`,...e.body?{"Content-Type":"application/json"}:{},...e.headers??{}}}),n=Z(await i.json().catch(()=>null));if(!i.ok||n?.ok===!1)throw new H(typeof n?.error=="string"?n.error:`Editor API failed (${i.status})`,i.status,n);return n??{}}async loadArtifacts(t){let e=await this.request(this.url(`/api/editor-sessions/${encodeURIComponent(this.session.sid)}/artifacts`,t),{method:"GET"}),i=Z(e.variation)??{};if(typeof i.artifactHash!="string"||!i.artifactHash)throw new H("Editor load response did not include an artifact hash",500,e);return{variation:{id:typeof i.id=="string"?i.id:t,name:typeof i.name=="string"?i.name:"Variation",artifactHash:i.artifactHash,reviewStatus:typeof i.reviewStatus=="string"?i.reviewStatus:null},artifacts:ke(e.artifacts)}}async saveArtifacts(t,e,i){let n=await this.request(this.url(`/api/editor-sessions/${encodeURIComponent(this.session.sid)}/artifacts`,t),{method:"PATCH",body:JSON.stringify({...e,expectedPriorHash:i})});if(typeof n.artifactHash!="string")throw new H("Editor save response did not include an artifact hash",500,n);return{artifactHash:n.artifactHash,reviewStatus:typeof n.reviewStatus=="string"?n.reviewStatus:null,warningIssues:Array.isArray(n.warningIssues)?n.warningIssues:[],artifacts:ke(n.artifacts)}}async extendSession(){let t=await this.request(this.url(`/api/editor-sessions/${encodeURIComponent(this.session.sid)}/extend`),{method:"POST"}),e=Z(t.session);return typeof e?.expiresAt=="string"?e.expiresAt:null}async revoke(){await this.request(this.url(`/api/editor-sessions/${encodeURIComponent(this.session.sid)}`),{method:"DELETE"})}async claimCommands(t=10){let e=this.url(`/api/editor-sessions/${encodeURIComponent(this.session.sid)}/commands`),i=new URL(e);i.searchParams.set("limit",String(Math.max(1,Math.min(t,20))));let n=await this.request(i.toString(),{method:"GET"});if(!Array.isArray(n.commands))return[];let a=[];for(let c of n.commands){let l=Z(c),f=typeof l?.commandId=="string"?l.commandId:"",g=typeof l?.command=="string"?l.command:"";!f||!wr.has(g)||a.push({commandId:f,command:g,args:Z(l?.args)??{},expiresAt:typeof l?.expiresAt=="string"?l.expiresAt:null})}return a}async completeCommand(t,e){await this.request(this.url(`/api/editor-sessions/${encodeURIComponent(this.session.sid)}/commands`),{method:"PATCH",body:JSON.stringify({commandId:t,...e})})}};var Se=/(?:^|[-_])(react|vue|ember|svelte|uid|uuid|random|generated)[-_]?|\d{5,}/i,kr=/^(active|current|selected|hover|focus|open|closed|js-|is-|has-)|\d{4,}/i;function Ft(r){return typeof CSS<"u"&&typeof CSS.escape=="function"?CSS.escape(r):r.replace(/[^a-zA-Z0-9_-]/g,t=>`\\${t}`)}function Er(r,t){return`[${r}="${t.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"]`}function Y(r,t){try{return t.querySelectorAll(r).length===1}catch{return!1}}function Ae(r){let t=r.id.trim();return t&&t.length<=80&&!Se.test(t)?t:null}function Sr(r){let t=["data-testid","data-test","data-cy","data-drip-id","name","aria-label"];for(let e of t){let i=r.getAttribute(e)?.trim();if(i&&i.length<=120)return{name:e,value:i}}for(let e of Array.from(r.attributes))if(e.name.startsWith("data-")&&!e.name.startsWith("data-react")&&e.value&&e.value.length<=120&&!Se.test(e.value))return{name:e.name,value:e.value};return null}function Me(r){return Array.from(r.classList).filter(t=>t.length<=64&&!kr.test(t)).slice(0,2)}function Ee(r,t){let e=r.tagName.toLowerCase(),i=Ae(r);if(i){let f=`#${Ft(i)}`;if(Y(f,t))return f}let n=Sr(r);if(n){let f=`${e}${Er(n.name,n.value)}`;if(Y(f,t))return f}let a=Me(r);if(a.length){let f=`${e}.${a.map(Ft).join(".")}`;if(Y(f,t))return f}let c=r.parentElement;if(!c)return e;let l=Array.from(c.children).filter(f=>f.tagName===r.tagName);return l.length>1?`${e}:nth-of-type(${l.indexOf(r)+1})`:e}function lt(r,t=document){let e=r.ownerDocument??document,i=Ae(r);if(i){let l=`#${Ft(i)}`;if(Y(l,t))return l}let n=Ee(r,t);if(Y(n,t))return n;let a=[n],c=r.parentElement;for(;c&&c!==e.documentElement&&a.length<5;){let l=Ee(c,t);a.unshift(l);let f=a.join(" > ");if(Y(f,t))return f;if(l.startsWith("#"))break;c=c.parentElement}return a.join(" > ")}function ct(r){let t=r.tagName.toLowerCase(),e=Me(r)[0],i=r.getBoundingClientRect();return`${t}${e?`.${e}`:""} ${Math.round(i.width)}x${Math.round(i.height)}`}var Ar=900,Ce=80,z="[redacted]",Mr=/(?:account|address|auth(?:orization)?|bearer|card|cookie|credential|customer|cvv|email|name|pass(?:word|wd)?|payment|phone|postal|secret|session|ssn|token|user|value|zip)/i,Cr=/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi,$r=/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,Tr=/\b(?:bearer|basic)\s+[A-Za-z0-9._~+\/-]+=*/gi,Lr=/\b(?:\+?\d[\d .()-]{6,}\d)\b/g,Or=new Set(["html","text","setText","attribute","style","setStyle","remove","insertBefore","insertAfter"]);function dt(r){return r&&typeof r=="object"&&!Array.isArray(r)?r:null}function N(r){return typeof r=="string"?r.trim():""}function Rr(r){try{let t=new URL(r).hostname.toLowerCase();return t==="localhost"||t.endsWith(".localhost")||t==="127.0.0.1"||t==="::1"||t==="[::1]"}catch{return!1}}function L(r,t){try{let e=new URL(r,t);return e.protocol!=="http:"&&e.protocol!=="https:"?`${e.protocol}${z}`:(e.username="",e.password="",e.search="",e.hash="",e.toString())}catch{return z}}function kt(r){return r.replace(/https?:\/\/[^\s"'<>]+/gi,t=>L(t)).replace(Cr,z).replace($r,z).replace(Tr,z).replace(Lr,z).replace(/\b(?:api[-_]?key|authorization|cookie|password|secret|token)\s*[:=]\s*[^\s,;]+/gi,t=>{let e=t.includes(":")?":":"=";return`${t.split(e,1)[0]}${e}${z}`})}function pt(r,t=0,e=""){if(e&&Mr.test(e))return z;if(r===null||typeof r=="string"||typeof r=="number"||typeof r=="boolean")return typeof r=="string"?kt(r).slice(0,500):r;if(typeof r>"u")return null;if(t>4)return"[truncated]";if(r instanceof Element)return V(r);if(Array.isArray(r))return r.slice(0,120).map(i=>pt(i,t+1));if(typeof r=="object"){let i={};for(let[n,a]of Object.entries(r).slice(0,80))try{i[n]=pt(a,t+1,n)}catch{}return i}return`[${typeof r}]`}function Te(r){return!r||r instanceof HTMLInputElement||r instanceof HTMLTextAreaElement||r instanceof HTMLSelectElement||r instanceof HTMLFormElement||r instanceof HTMLElement&&r.isContentEditable?"":(r.textContent??"").trim().replace(/\s+/g," ")}function V(r){if(!r)return null;let t=null;try{let e=r.getBoundingClientRect();t={x:Math.round(e.x),y:Math.round(e.y),width:Math.round(e.width),height:Math.round(e.height)}}catch{}return{selector:lt(r),tag:r.tagName.toLowerCase(),text:kt(Te(r)).slice(0,220)||null,role:r.getAttribute("role"),href:r instanceof HTMLAnchorElement?L(r.href):null,name:r.getAttribute("name"),type:r.getAttribute("type"),rect:t}}function $e(r){return{...pt(r),...typeof r.url=="string"?{url:L(r.url)}:{}}}function wt(r){let t=N(r.selector);if(t)try{let a=document.querySelector(t);return a?{ok:!0,element:a,mode:"selector"}:{ok:!1,error:"Selector target not found.",repairHint:"Call browser_snapshot or browser_select_element to find a selector that exists on the live page."}}catch{return{ok:!1,error:`Invalid selector: ${t}`,repairHint:"Pass visible text or a valid CSS selector."}}let e=N(r.text??r.selectorOrText??r.instruction??r.condition);if(!e)return{ok:!1,error:"Target not found"};try{let a=document.querySelector(e);if(a)return{ok:!0,element:a,mode:"selectorOrText"}}catch{}let i=e.toLowerCase(),n=Array.from(document.querySelectorAll("button,a,input,textarea,select,label,[role='button'],[onclick],[data-testid]")).slice(0,350).filter(a=>{let c=`${a.getAttribute("aria-label")??""} ${a.getAttribute("title")??""} ${a.getAttribute("value")??""}`.toLowerCase();return Te(a).toLowerCase().includes(i)||c.includes(i)});return n.length===1?{ok:!0,element:n[0],mode:"text"}:n.length>1?{ok:!1,error:"Browser target text is ambiguous.",repairHint:"Pass the exact selector from browser_snapshot/browser_select_element instead of loose text."}:{ok:!1,error:"Target not found"}}function Ir(r){let t=dt(r),e=N(t?.selector),i=t?.action;if(!e||typeof i!="string"||!Or.has(i))return null;let n={selector:e,action:i};typeof t?.html=="string"&&(n.html=t.html),typeof t?.text=="string"&&(n.text=t.text);let a=dt(t?.attribute);a&&typeof a.name=="string"&&(typeof a.value=="string"||a.value===null)&&(n.attribute={name:a.name,value:a.value});let c=dt(t?.attributes);c&&(n.attributes=Object.fromEntries(Object.entries(c).filter(([,f])=>typeof f=="string"||f===null)));let l=dt(t?.styles);return l&&(n.styles=Object.fromEntries(Object.entries(l).filter(([,f])=>typeof f=="string"))),n}function Hr(r){let t=dt(r);if(!t||!Array.isArray(t.mutations))return null;let e=t.mutations.map(Ir);return e.some(i=>i===null)?null:{mutations:e,customCss:typeof t.customCss=="string"?t.customCss:"",customJs:typeof t.customJs=="string"?t.customJs:""}}function _r(r){return{...r}}var Et=class{constructor(t,e={navigate:i=>location.assign(i),reload:()=>location.reload(),back:()=>history.back(),forward:()=>history.forward()}){this.controller=t;this.navigation=e;this.consoleLogs=[];this.networkLogs=[];this.restoreConsole=null;this.performanceObserver=null}start(){if(this.restoreConsole)return;let t=new Map;for(let e of["log","info","warn","error"]){let i=console[e];t.set(e,i),console[e]=(...n)=>{this.consoleLogs.push({level:e,args:pt(n),ts:Date.now()}),this.consoleLogs.splice(0,Math.max(0,this.consoleLogs.length-Ce)),i.apply(console,n)}}if(this.restoreConsole=()=>{for(let[e,i]of t)console[e]=i;this.restoreConsole=null},typeof PerformanceObserver<"u")try{this.performanceObserver=new PerformanceObserver(e=>{for(let i of e.getEntries())this.networkLogs.push({url:i.name,type:i.entryType,startTime:Math.round(i.startTime),duration:Math.round(i.duration)});this.networkLogs.splice(0,Math.max(0,this.networkLogs.length-Ce))}),this.performanceObserver.observe({type:"resource",buffered:!0})}catch{}}stop(){this.restoreConsole?.(),this.performanceObserver?.disconnect(),this.performanceObserver=null}async execute(t){let e=t.args;switch(t.command){case"current_url":return{result:{ok:!0,url:L(location.href),originalUrl:L(location.href)}};case"snapshot":return{result:{ok:!0,snapshot:this.snapshot()}};case"console_logs":return{result:{ok:!0,logs:this.consoleLogs.slice(-50).map(i=>pt(i))}};case"network_logs":{let i=N(e.filter).toLowerCase();return{result:{ok:!0,logs:this.networkLogs.slice(-80).map($e).filter(a=>!i||JSON.stringify(a).toLowerCase().includes(i))}}}case"screenshot":return{result:{ok:!1,error:"Live-page screenshot capture is unsupported in the merchant SDK runtime.",repairHint:"Use browser_snapshot for DOM evidence or capture the store tab through the connected browser runner.",screenshot:{captured:!1,reason:"unsupported_live_origin"}}};case"eval_readonly":return{result:this.evaluateReadonly(e)};case"click":return{result:this.click(e)};case"type":return{result:this.type(e)};case"select_element":return{result:this.selectElement(e)};case"wait_for":return{result:await this.waitFor(e)};case"network_probe":return{result:await this.networkProbe(e)};case"apply_artifacts":{let i=Hr(e.artifacts);return{result:i?_r(this.controller.applyCommandArtifacts(i)):{ok:!1,error:"apply_artifacts requires a valid full artifact snapshot."}}}case"navigate":{let i=N(e.url);try{let n=new URL(i,this.controller.session.targetOrigin);return n.origin!==this.controller.session.targetOrigin?{result:{ok:!1,error:"Navigation must stay on the editor session origin."}}:{result:{ok:!0,url:L(n.toString())},afterAcknowledge:()=>this.navigation.navigate(n.toString())}}catch{return{result:{ok:!1,error:"Invalid navigation URL"}}}}case"reload":return{result:{ok:!0},afterAcknowledge:()=>this.navigation.reload()};case"back":return{result:{ok:!0},afterAcknowledge:()=>this.navigation.back()};case"forward":return{result:{ok:!0},afterAcknowledge:()=>this.navigation.forward()}}}snapshot(){let t=(e,i)=>Array.from(document.querySelectorAll(e)).slice(0,i).map(V).filter(Boolean);return{title:document.title?kt(document.title).slice(0,220):null,url:L(location.href),originalUrl:L(location.href),bodyTextLength:(document.body.textContent??"").length,headings:t("h1,h2,h3",18),interactive:t("button,a,input,textarea,select,[role='button'],form",45),generated:t("[data-drip-preview-generated], [class*='apex-'], [class*='abt-'], [class*='drip-']",20),consoleCount:this.consoleLogs.length,networkCount:this.networkLogs.length}}click(t){let e=wt(t);if(!e.ok||!e.element)return e;try{e.element.scrollIntoView({block:"center",inline:"center"})}catch{}return e.element instanceof HTMLElement?e.element.click():e.element.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0})),{ok:!0,element:V(e.element),targetResolution:{mode:e.mode}}}type(t){let e=wt(t);if(!e.ok||!e.element)return e;let i=typeof t.value=="string"?t.value:String(t.value??"");if(e.element instanceof HTMLInputElement||e.element instanceof HTMLTextAreaElement||e.element instanceof HTMLSelectElement)e.element.focus(),e.element.value=i;else if(e.element instanceof HTMLElement&&e.element.isContentEditable)e.element.focus(),e.element.textContent=i;else return{ok:!1,error:"Target does not accept text input"};return e.element.dispatchEvent(new Event("input",{bubbles:!0})),e.element.dispatchEvent(new Event("change",{bubbles:!0})),{ok:!0,element:V(e.element),valueLength:i.length}}selectElement(t){let e=wt(t);return e.ok&&e.element?{ok:!0,element:V(e.element),targetResolution:{mode:e.mode}}:e}async waitFor(t){let e=Math.max(100,Math.min(Number(t.timeoutMs)||5e3,15e3)),i=Date.now();for(;Date.now()-i<e;){let n=wt(t);if(n.ok&&n.element)return{ok:!0,element:V(n.element),waitedMs:Date.now()-i};await new Promise(a=>setTimeout(a,100))}return{ok:!1,error:"Target not found before timeout",waitedMs:Date.now()-i}}async networkProbe(t){let e=this.networkLogs.length,i=Math.max(250,Math.min(Number(t.waitMs)||2e3,8e3)),n=this.click(t);await new Promise(c=>setTimeout(c,i));let a=this.networkLogs.slice(e).slice(-30).map($e);return{ok:n.ok,attemptedAction:n.ok,action:n,waitedMs:i,currentUrl:L(location.href),originalUrl:L(location.href),networkObserved:a.length>0,successfulRequestCount:a.length,entries:a,...a.length?{}:{repairHint:"No resource request was observed after the action. Inspect the handler and selector, then retry browser_network_probe."}}}evaluateReadonly(t){if(!Rr(this.controller.session.targetOrigin))return{ok:!1,error:"eval_readonly is unsupported on live merchant origins.",repairHint:"Use browser_snapshot, browser_select_element, or another allowlisted inspection command."};if(N(t.code))return{ok:!1,error:"JavaScript evaluation is disabled in the merchant SDK runtime.",repairHint:"Pass an allowlisted operation: document_title, current_url, viewport, element_exists, element_count, or element_summary."};let e=N(t.operation);if(e==="document_title")return{ok:!0,operation:e,result:kt(document.title).slice(0,220)};if(e==="current_url")return{ok:!0,operation:e,result:L(location.href)};if(e==="viewport")return{ok:!0,operation:e,result:{width:window.innerWidth,height:window.innerHeight}};if(["element_exists","element_count","element_summary"].includes(e)){let i=N(t.selector);if(!i)return{ok:!1,error:`${e} requires a selector.`};try{let n=Array.from(document.querySelectorAll(i));return e==="element_exists"?{ok:!0,operation:e,result:n.length>0}:e==="element_count"?{ok:!0,operation:e,result:n.length}:{ok:!0,operation:e,result:V(n[0]??null)}}catch{return{ok:!1,error:"The inspection selector is invalid."}}}return{ok:!1,error:"eval_readonly requires an allowlisted declarative operation.",repairHint:"Use document_title, current_url, viewport, element_exists, element_count, or element_summary."}}},St=class{constructor(t,e){this.api=t;this.executor=e;this.running=!1;this.timer=null;this.polling=!1}start(){this.running||(this.running=!0,this.executor.start(),this.poll())}stop(){this.running=!1,this.timer&&clearTimeout(this.timer),this.timer=null,this.executor.stop()}async poll(){if(!(!this.running||this.polling)){this.polling=!0;try{let t=await this.api.claimCommands();for(let e of t){if(!this.running)break;let i;try{i=await this.executor.execute(e)}catch(n){await this.api.completeCommand(e.commandId,{error:n instanceof Error?n.message:"Browser command execution failed"});continue}if(await this.api.completeCommand(e.commandId,{result:i.result}),i.afterAcknowledge){let n=i.afterAcknowledge;this.stop(),setTimeout(n,0);break}}}catch(t){t instanceof H&&[401,403,410].includes(t.status)&&this.stop()}finally{this.polling=!1,this.running&&(this.timer=setTimeout(()=>{this.poll()},Ar))}}}};function At(r){let t=new DOMParser().parseFromString(r,"text/html");for(let e of Array.from(t.querySelectorAll("script")))e.remove();for(let e of Array.from(t.body.querySelectorAll("*")))for(let i of Array.from(e.attributes)){if(i.name.toLowerCase().startsWith("on")){e.removeAttribute(i.name);continue}["href","src","action","formaction","xlink:href"].includes(i.name.toLowerCase())&&i.value.replace(/\s+/g,"").toLowerCase().startsWith("javascript:")&&e.removeAttribute(i.name)}return t.body.innerHTML}var Le=new Map,Mt=0;function Ct(r){if(Mt===0)for(let[t,e]of Le)try{let i=t.takeRecords();i.length&&e&&e(i,t)}catch{}Mt+=1;try{return r()}finally{if(Mt-=1,Mt===0)for(let t of Le.keys())try{t.takeRecords()}catch{}}}var Pr="hybrid";function $t(){return Pr==="strict"}var Gt="data-drip-inserted",Dr=[],zr=new Set(["href","src","action","formaction","xlink:href"]),Nr=new Set(["image/png","image/jpeg","image/gif","image/webp","image/avif"]);function Zt(r,t){let e=r.trim().toLowerCase();if(!e||e.startsWith("on")||e==="srcdoc")return!1;if(t===null||!zr.has(e))return!0;let i=t.replace(/[\u0000-\u0020]+/g,"").toLowerCase();if(i.startsWith("javascript:"))return!1;if(!i.startsWith("data:"))return!0;let n=i.slice(5).split(/[;,]/,1)[0];return Nr.has(n)}function Kt(r){let t=At(r);if(!$t())return t;let e=document.createElement("template");e.innerHTML=t;for(let i of Array.from(e.content.querySelectorAll("*")))for(let n of Array.from(i.attributes))Zt(n.name,n.value)||i.removeAttribute(n.name);return e.innerHTML}function Wt(r){if(!r||r.startsWith("--")||r.includes("-"))return r;let t=r.replace(/[A-Z]/g,e=>"-"+e.toLowerCase());return t.startsWith("ms-")&&(t="-"+t),t}function Ur(r,t){return r.action+":"+t+":"+(r.selector||"")+":"+(r.html||r.text||"")}function Ie(r){return r==="insertBefore"||r==="insertAfter"}function jr(r,t,e=Dr){switch(r.action){case"html":e.push({kind:"content",element:t,property:"innerHTML",value:t.innerHTML});break;case"text":case"setText":e.push({kind:"content",element:t,property:"textContent",value:t.textContent});break;case"attribute":{let i=new Set;r.attribute&&i.add(r.attribute.name),r.attributes&&Object.keys(r.attributes).forEach(n=>i.add(n)),e.push({kind:"attribute",element:t,values:Array.from(i).map(n=>({name:n,value:t.getAttribute(n)}))});break}case"style":case"setStyle":{let i=t.style,n=Object.keys(r.styles??{}).map(Wt);e.push({kind:"style",element:t,values:n.map(a=>({name:a,value:i.getPropertyValue(a),priority:i.getPropertyPriority(a)}))});break}case"remove":e.push({kind:"remove",element:t,parent:t.parentNode,nextSibling:t.nextSibling});break}}function Jr(r){switch(r.kind){case"content":r.property==="innerHTML"?r.element.innerHTML=r.value??"":r.element.textContent=r.value;break;case"attribute":for(let{name:t,value:e}of r.values)e===null?r.element.removeAttribute(t):r.element.setAttribute(t,e);break;case"style":for(let{name:t,value:e,priority:i}of r.values)e?r.element.style.setProperty(t,e,i):r.element.style.removeProperty(t);break;case"remove":if(!r.parent||r.element.parentNode)return;try{r.parent.insertBefore(r.element,r.nextSibling)}catch{r.parent.appendChild(r.element)}break;case"insert":for(let t of r.nodes)t.parentNode?.removeChild(t);break}}function Oe(r,t){switch(r.action){case"html":typeof r.html=="string"&&(t.innerHTML=Kt(r.html));break;case"text":case"setText":typeof r.text=="string"&&(t.textContent=r.text);break;case"attribute":if(r.attribute&&(!$t()||Zt(r.attribute.name,r.attribute.value))&&(r.attribute.value===null?t.removeAttribute(r.attribute.name):t.setAttribute(r.attribute.name,r.attribute.value)),r.attributes)for(let[e,i]of Object.entries(r.attributes))$t()&&!Zt(e,i)||(i===null?t.removeAttribute(e):t.setAttribute(e,i));break;case"style":case"setStyle":if(r.styles)for(let[e,i]of Object.entries(r.styles))t.style.setProperty(Wt(e),i);break;case"remove":t.remove();break;case"insertBefore":typeof r.html=="string"&&t.insertAdjacentHTML("beforebegin",Kt(r.html));break;case"insertAfter":typeof r.html=="string"&&t.insertAdjacentHTML("afterend",Kt(r.html));break}}function Br(r,t){let e=r.parentElement;return e?Array.from(e.querySelectorAll("["+Gt+"]")).some(i=>i.getAttribute(Gt)===t):!1}function Vr(r,t){r.setAttribute(Gt,t)}function Re(r,t,e,i){return Ct(()=>{if(Ie(r.action)){let n=t.parentNode;if(!n||typeof r.html!="string")return null;let a=t.previousSibling,c=t.nextSibling;Oe(r,t);let l=[],f=r.action==="insertBefore"?a?a.nextSibling:n.firstChild:t.nextSibling,g=r.action==="insertBefore"?t:c;for(;f&&f!==g;)l.push(f),f=f.nextSibling;let S=l.filter(E=>E instanceof Element);return i&&S.forEach(E=>Vr(E,i)),l.length&&e.push({kind:"insert",nodes:l}),S[0]??null}return jr(r,t,e),Oe(r,t),null})}function qr(r,t,e){let i=t.root||document;r.forEach((n,a)=>{let c;try{c=i.querySelectorAll(n.selector)}catch{t.onMiss?.(n,a);return}if(c.length===0){t.onMiss?.(n,a);return}c.forEach(l=>{let f=Ur(n,a);if(Ie(n.action)){if(Br(l,f))return;Re(n,l,e,f),t.onApplied?.(n,l,a);return}Re(n,l,e,f),t.onApplied?.(n,l,a)})})}function Tt(){let r=[];return{apply(t,e={}){qr(t,e,r)},rollback(){Ct(()=>{for(let t=r.length-1;t>=0;t-=1)Jr(r[t])}),r.length=0},get snapshotCount(){return r.length}}}var Xt={mutations:[],customCss:"",customJs:""};function w(r){return{mutations:r.mutations.map(t=>({...t,attribute:t.attribute?{...t.attribute}:void 0,attributes:t.attributes?{...t.attributes}:void 0,styles:t.styles?{...t.styles}:void 0})),customCss:r.customCss,customJs:r.customJs}}function Fr(r,t){if(r.selector!==t.selector)return!1;let e=new Set(["text","setText","html"]),i=new Set(["style","setStyle"]);return e.has(r.action)&&e.has(t.action)||i.has(r.action)&&i.has(t.action)?!0:r.action===t.action}function Ot(r,t){if(t.action==="remove")return{...r,mutations:[...r.mutations.filter(n=>n.selector!==t.selector),t]};let e=r.mutations.filter(n=>!(n.selector===t.selector&&n.action==="remove")).map(n=>({...n})),i=e.findIndex(n=>Fr(n,t));if(i<0)e.push(t);else if((t.action==="style"||t.action==="setStyle")&&e[i].styles)e[i]={...e[i],...t,styles:{...e[i].styles,...t.styles}};else if(t.action==="attribute"){let n=e[i],a={...n.attribute?{[n.attribute.name]:n.attribute.value}:{},...n.attributes??{}},c={...t.attribute?{[t.attribute.name]:t.attribute.value}:{},...t.attributes??{}};e[i]={...n,...t,attribute:void 0,attributes:{...a,...c}}}else e[i]=t;return{...r,mutations:e}}function He(r,t){return{...r,mutations:r.mutations.filter(e=>e.selector!==t)}}function _e(r,t){return{...r,mutations:r.mutations.filter((e,i)=>i!==t)}}var Lt=class{constructor(){this.undoStack=[];this.redoStack=[]}push(t){this.undoStack.push(w(t)),this.undoStack=this.undoStack.slice(-50),this.redoStack=[]}undo(t){let e=this.undoStack.pop();return e?(this.redoStack.push(w(t)),w(e)):null}redo(t){let e=this.redoStack.pop();return e?(this.undoStack.push(w(t)),w(e)):null}reset(){this.undoStack=[],this.redoStack=[]}get canUndo(){return this.undoStack.length>0}get canRedo(){return this.redoStack.length>0}};var ut="apex-editor-draft-css",Wr=700,Kr=1500,Rt=class{constructor(t,e,i=new X(e,t),n=()=>location.reload()){this.session=t;this.apiOrigin=e;this.api=i;this.reload=n;this.state={variation:null,artifacts:w(Xt),artifactsEnabled:!0,pickerActive:!1,selectedElement:null,selectedSelector:null,saveState:"idle",saveMessage:null,dock:"top",canUndo:!1,canRedo:!1,jsApplied:!1,reloadRequired:!1,deviceState:"closed"};this.listeners=new Set;this.history=new Lt;this.visualContext=null;this.devicePreview=null;this.saveTimer=null;this.saveQueue=Promise.resolve();this.revision=0;this.variationRequest=0;this.cleanups=new Set}getState(){return this.state}subscribe(t){return this.listeners.add(t),t(this.state),()=>this.listeners.delete(t)}async initialize(){await this.selectVariation(this.session.initialVariationId)}async selectVariation(t){let e=++this.variationRequest;this.cancelSave(),this.patch({saveState:"idle",saveMessage:"Loading draft..."});try{let i=await this.api.loadArtifacts(t);if(e!==this.variationRequest)return;this.history.reset(),this.revision+=1,this.state={...this.state,variation:i.variation,artifacts:w(i.artifacts),selectedElement:null,selectedSelector:null,saveState:"saved",saveMessage:"Saved",canUndo:!1,canRedo:!1,jsApplied:!1,reloadRequired:!1},this.applyVisualArtifacts(),this.emit()}catch(i){if(e!==this.variationRequest)return;this.patch({saveState:"error",saveMessage:i instanceof Error?i.message:"Draft could not be loaded"})}}setPickerActive(t){this.patch({pickerActive:t})}selectElement(t,e){this.patch({selectedElement:t,selectedSelector:e,pickerActive:!1})}clearSelection(){this.clearSelectedElement()}clearSelectedElement(){this.patch({selectedElement:null,selectedSelector:null,pickerActive:!1})}removeSelector(t){this.commit(He(this.state.artifacts,t))}removeMutation(t){!Number.isInteger(t)||t<0||t>=this.state.artifacts.mutations.length||this.commit(_e(this.state.artifacts,t))}restoreArtifacts(t){this.commit(w(t))}async extendSession(){let t=await this.api.extendSession();return t&&(this.session.expiresAt=t),t}async resolveConflict(t){let e=this.state.variation;if(!(!e||this.state.saveState!=="conflict")){if(t==="theirs"){await this.selectVariation(e.id);return}try{let i=await this.api.loadArtifacts(e.id);this.state={...this.state,variation:{...e,artifactHash:i.variation.artifactHash},saveState:"idle",saveMessage:"Unsaved changes"},this.emit(),await this.saveNow()}catch(i){this.patch({saveState:"error",saveMessage:i instanceof Error?i.message:"Draft could not be saved"})}}}toggleArtifacts(t){this.state={...this.state,artifactsEnabled:t},this.applyVisualArtifacts(),this.devicePreview?.update(this.state.artifacts,t),this.emit()}setDock(t){this.patch({dock:t})}setText(t){this.mutateSelected({action:"setText",text:t})}setImageSource(t){this.mutateSelected({action:"attribute",attributes:{src:t}})}setStyle(t,e){this.mutateSelected({action:"setStyle",styles:{[t]:e}})}hideSelected(){this.setStyle("display","none")}removeSelected(){this.mutateSelected({action:"remove"})}setCustomCss(t){this.commit({...this.state.artifacts,customCss:t})}setCustomJs(t){this.commit({...this.state.artifacts,customJs:t},!1),this.patch({jsApplied:!1})}applyCustomJs(){let t=this.state.artifacts.customJs.trim();if(t)try{new Function(`${t}
|
|
2
|
+
//# sourceURL=apex-editor-draft.js`)(),this.patch({jsApplied:!0,reloadRequired:!0,saveMessage:"JavaScript applied. Reload required to undo."})}catch(e){this.patch({saveState:"error",saveMessage:e instanceof Error?e.message:"JavaScript failed"})}}undo(){let t=this.history.undo(this.state.artifacts);t&&this.replaceFromHistory(t)}redo(){let t=this.history.redo(this.state.artifacts);t&&this.replaceFromHistory(t)}attachDevicePreview(t){this.devicePreview=t}setDeviceState(t){this.patch({deviceState:t})}openDevicePreview(){this.devicePreview?.open(this.state.artifactsEnabled?this.state.artifacts:w(Xt))}closeDevicePreview(){this.devicePreview?.close()}addCleanup(t){return this.cleanups.add(t),()=>this.cleanups.delete(t)}applyCommandArtifacts(t){this.visualContext?.rollback(),this.visualContext=null,document.getElementById(ut)?.remove();let e=t.mutations.map(g=>this.selectorCount(g.selector));this.state={...this.state,artifactsEnabled:!0},this.commit(w(t));let i=t.mutations.map((g,S)=>{let E=e[S],$=this.selectorCount(g.selector),Dt=this.verifyMutationEffect(g,E,$);return{index:S,selector:g.selector,action:g.action,beforeCount:E,afterCount:$,effectVerified:Dt,error:E<0?"Invalid selector":null}}),n=Array.from(new Set(t.mutations.filter(g=>g.action!=="remove").map(g=>g.selector))),a=n.map(g=>{let S=this.selectorElements(g),E=S.slice(0,8).map($=>({text:($.textContent??"").trim().replace(/\s+/g," ").slice(0,240),visible:this.isVisible($)}));return{selector:g,count:S.length,visibleCount:E.filter($=>$.visible).length,matches:E}}),c=i.filter(g=>!g.effectVerified),l=a.reduce((g,S)=>g+S.visibleCount,0),f=/\b(?:fetch|XMLHttpRequest|sendBeacon)\b/.test(t.customJs);return{ok:c.length===0,mutationAudit:i,generatedSelectors:n,generatedVisibility:a,visibleGeneratedCount:l,hiddenEffectVerifiedCount:i.filter(g=>g.action==="remove"&&g.effectVerified).length,networkRequired:f,customJsDeferred:t.customJs.trim().length>0,...c.length?{error:"One or more mutation selectors did not match the live page.",repairHint:"Inspect the current browser snapshot, choose a selector that exists, and reapply the draft."}:{}}}saveNow(){if(this.cancelSave(),!this.state.variation||this.state.saveState==="conflict")return Promise.resolve();let t=this.state.variation.id,e=this.variationRequest,i=this.saveQueue.then(()=>this.performSave(t,e));return this.saveQueue=i.catch(()=>{}),i}async performSave(t,e){if(e!==this.variationRequest||this.state.variation?.id!==t||this.state.saveState==="conflict")return;let i=this.state.variation.artifactHash,n=w(this.state.artifacts),a=this.revision;this.patch({saveState:"saving",saveMessage:"Saving..."});try{let c=await this.api.saveArtifacts(t,n,i);if(e!==this.variationRequest||this.state.variation?.id!==t)return;let l=a!==this.revision;this.state={...this.state,variation:{...this.state.variation,artifactHash:c.artifactHash,reviewStatus:c.reviewStatus},artifacts:l?this.state.artifacts:w(c.artifacts),saveState:l?"idle":"saved",saveMessage:l?"Saving latest changes...":c.warningIssues[0]?.message??"Saved"},this.emit()}catch(c){if(e!==this.variationRequest||this.state.variation?.id!==t)return;c instanceof H&&c.status===409?this.patch({saveState:"conflict",saveMessage:"Draft changed elsewhere. Reload this variation before saving."}):this.patch({saveState:"error",saveMessage:c instanceof Error?c.message:"Draft could not be saved"})}}async exit(){this.cancelSave(),this.runCleanups(),this.devicePreview?.close(!1),this.visualContext?.rollback(),document.getElementById(ut)?.remove();try{window.opener?.postMessage({type:"apex:editor-exited",sid:this.session.sid,experimentId:this.session.experimentId,variationId:this.state.variation?.id??this.session.initialVariationId},this.apiOrigin)}catch{}try{await this.withTimeout(this.api.revoke(),Kr)}catch{}this.reload()}destroy(){this.cancelSave(),this.runCleanups(),this.devicePreview?.close(!1),this.visualContext?.rollback(),document.getElementById(ut)?.remove(),this.listeners.clear()}mutateSelected(t){let e=this.state.selectedSelector;e&&this.commit(Ot(this.state.artifacts,{...t,selector:e}))}commit(t,e=!0){this.state.saveState!=="conflict"&&(this.history.push(this.state.artifacts),this.revision+=1,this.state={...this.state,artifacts:w(t),saveState:"idle",saveMessage:"Unsaved changes",canUndo:this.history.canUndo,canRedo:this.history.canRedo},e&&this.applyVisualArtifacts(),this.devicePreview?.update(this.state.artifacts,this.state.artifactsEnabled),this.emit(),this.scheduleSave())}replaceFromHistory(t){this.revision+=1,this.state={...this.state,artifacts:t,saveState:"idle",saveMessage:"Unsaved changes",canUndo:this.history.canUndo,canRedo:this.history.canRedo,jsApplied:!1},this.applyVisualArtifacts(),this.devicePreview?.update(t,this.state.artifactsEnabled),this.emit(),this.scheduleSave()}applyVisualArtifacts(){if(this.visualContext?.rollback(),this.visualContext=null,document.getElementById(ut)?.remove(),!!this.state.artifactsEnabled){if(this.state.artifacts.customCss.trim()){let t=document.createElement("style");t.id=ut,t.textContent=this.state.artifacts.customCss,(document.head||document.documentElement).appendChild(t)}this.visualContext=Tt(),this.visualContext.apply(this.state.artifacts.mutations)}}scheduleSave(){this.cancelSave(),this.saveTimer=setTimeout(()=>{this.saveNow()},Wr)}cancelSave(){this.saveTimer&&clearTimeout(this.saveTimer),this.saveTimer=null}patch(t){this.state={...this.state,...t},this.emit()}emit(){for(let t of this.listeners)t(this.state)}selectorElements(t){try{return Array.from(document.querySelectorAll(t))}catch{return[]}}selectorCount(t){try{return document.querySelectorAll(t).length}catch{return-1}}isVisible(t){if(!(t instanceof HTMLElement))return!0;let e=getComputedStyle(t);if(e.display==="none"||e.visibility==="hidden"||Number(e.opacity)===0)return!1;let i=t.getBoundingClientRect();return i.width>0&&i.height>0||!!t.textContent?.trim()}verifyMutationEffect(t,e,i){if(e<=0)return!1;if(t.action==="remove")return i===0;let n=this.selectorElements(t.selector);if(!n.length)return!1;if((t.action==="text"||t.action==="setText")&&typeof t.text=="string")return n.every(a=>a.textContent===t.text);if(t.action==="html"&&typeof t.html=="string"){let a=At(t.html);return n.every(c=>{let l=c.cloneNode(!1);return l.innerHTML=a,c.innerHTML===l.innerHTML})}if(t.action==="attribute"){let a={...t.attribute?{[t.attribute.name]:t.attribute.value}:{},...t.attributes??{}};return n.every(c=>Object.entries(a).every(([l,f])=>f===null?!c.hasAttribute(l):c.getAttribute(l)===f))}return t.action==="style"||t.action==="setStyle"?n.every(a=>Object.entries(t.styles??{}).every(([c,l])=>a.style.getPropertyValue(c.includes("-")?c:c.replace(/[A-Z]/g,f=>`-${f.toLowerCase()}`))===l)):!0}runCleanups(){for(let t of this.cleanups)t();this.cleanups.clear()}async withTimeout(t,e){let i=null;try{return await Promise.race([t,new Promise(n=>{i=setTimeout(()=>n(void 0),e)})])}finally{i&&clearTimeout(i)}}};var Pe="apex-editor-device-preview";var Gr=5e3,De="apex-editor-device-css",It=class{constructor(t,e){this.frame=t;this.onState=e;this.context=null;this.hiddenChildren=[];this.timer=null;this.artifacts=null}open(t){this.close(!1),this.artifacts=t,this.hideStorePage(),this.onState("loading"),this.frame.hidden=!1,this.frame.onload=()=>this.handleLoad(),this.frame.onerror=()=>this.blocked();let e=new URL(location.href);e.hash="",this.frame.src=e.toString(),this.timer=setTimeout(()=>this.blocked(),Gr)}update(t,e=!0){this.artifacts=e?t:{mutations:[],customCss:"",customJs:""};let i=this.readDocument();i&&this.apply(i,this.artifacts)}close(t=!0){this.timer&&clearTimeout(this.timer),this.timer=null,this.context?.rollback(),this.context=null,this.frame.onload=null,this.frame.onerror=null,this.frame.hidden=!0,this.frame.removeAttribute("src");for(let e of this.hiddenChildren)e.element.style.visibility=e.visibility;this.hiddenChildren=[],t&&this.onState("closed")}handleLoad(){let t=this.readDocument();if(!t?.body||!this.artifacts){this.blocked();return}this.timer&&clearTimeout(this.timer),this.timer=null,this.apply(t,this.artifacts),this.onState("active")}readDocument(){try{let t=this.frame.contentDocument,e=this.frame.contentWindow?.location.href??"";return!t||!e||e==="about:blank"?null:t}catch{return null}}apply(t,e){if(this.context?.rollback(),this.context=Tt(),t.getElementById(De)?.remove(),e.customCss.trim()){let i=t.createElement("style");i.id=De,i.textContent=e.customCss,(t.head||t.documentElement).appendChild(i)}this.context.apply(e.mutations,{root:t})}hideStorePage(){let t=document.getElementById("apex-editor-host");this.hiddenChildren=Array.from(document.body?.children??[]).filter(e=>e instanceof HTMLElement&&e!==t).map(e=>{let i=e.style.visibility;return e.style.visibility="hidden",{element:e,visibility:i}})}blocked(){this.timer&&clearTimeout(this.timer),this.timer=null,this.frame.onload=null,this.frame.onerror=null,this.frame.hidden=!0,this.frame.removeAttribute("src"),this.restoreStorePage(),this.onState("blocked")}restoreStorePage(){for(let t of this.hiddenChildren)t.element.style.visibility=t.visibility;this.hiddenChildren=[]}};function Ht(r){return!!r?.closest("#apex-editor-host")}function ze(r){return r.composedPath().some(t=>t instanceof Element&&t.id==="apex-editor-host")}function Yt(r){return r.ownerDocument===document&&r.getRootNode()===document}var _t=class{constructor(t,e,i,n){this.overlay=t;this.onSelect=e;this.onActiveChange=i;this.onUnsupported=n;this.active=!1;this.hovered=null;this.selected=null;this.onPointerMove=t=>{if(!this.active||ze(t))return;let e=t.composedPath()[0],i=e instanceof Element?e:null;!i||!Yt(i)||Ht(i)||(this.hovered=i,this.renderOverlay(i))};this.onClick=t=>{if(!this.active||ze(t))return;let e=t.composedPath()[0],i=e instanceof Element?e:null;if(i){if(!Yt(i)||Ht(i)){Ht(i)||(t.preventDefault(),t.stopImmediatePropagation(),this.onUnsupported?.());return}t.preventDefault(),t.stopImmediatePropagation(),this.selected=i,this.hovered=null,this.active=!1,this.renderOverlay(i),this.onSelect(i,lt(i)),this.onActiveChange(!1)}};this.onKeyDown=t=>{if(t.key==="Escape"&&this.active){t.preventDefault(),this.setActive(!1);return}let e=t.target;if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement||e instanceof HTMLElement&&e.isContentEditable||!this.selected||!["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].includes(t.key))return;let i=t.key==="ArrowUp"?this.selected.parentElement:t.key==="ArrowDown"?this.selected.firstElementChild:t.key==="ArrowLeft"?this.selected.previousElementSibling:this.selected.nextElementSibling;!i||!Yt(i)||Ht(i)||(t.preventDefault(),this.selected=i,this.renderOverlay(i),this.onSelect(i,lt(i)))};this.refresh=()=>{this.renderOverlay(this.active?this.hovered:this.selected)};document.addEventListener("pointermove",this.onPointerMove,!0),document.addEventListener("click",this.onClick,!0),document.addEventListener("keydown",this.onKeyDown,!0),window.addEventListener("scroll",this.refresh,!0),window.addEventListener("resize",this.refresh)}setActive(t){this.active=t,t||(this.hovered=null),this.renderOverlay(t?this.hovered:this.selected),this.onActiveChange(t)}setSelected(t){this.selected=t,this.renderOverlay(this.active?this.hovered:t)}destroy(){document.removeEventListener("pointermove",this.onPointerMove,!0),document.removeEventListener("click",this.onClick,!0),document.removeEventListener("keydown",this.onKeyDown,!0),window.removeEventListener("scroll",this.refresh,!0),window.removeEventListener("resize",this.refresh)}renderOverlay(t){if(!t?.isConnected){this.overlay.box.hidden=!0,this.overlay.label.hidden=!0;return}let e=t.getBoundingClientRect();if(e.width<=0||e.height<=0){this.overlay.box.hidden=!0,this.overlay.label.hidden=!0;return}this.overlay.box.hidden=!1,this.overlay.label.hidden=!1,this.overlay.box.dataset.state=this.active&&t!==this.selected?"hover":"selected",this.overlay.box.style.transform=`translate(${Math.round(e.left)}px,${Math.round(e.top)}px)`,this.overlay.box.style.width=`${Math.round(e.width)}px`,this.overlay.box.style.height=`${Math.round(e.height)}px`,this.overlay.label.textContent=ct(t);let i=e.top>=28?e.top-24:e.bottom+4;this.overlay.label.style.transform=`translate(${Math.max(4,Math.round(e.left))}px,${Math.round(i)}px)`}};var Ne=18e4,Zr=12,Xr=["main","header","footer","section","article","nav","form","h1","h2","h3","p","button","a[href]","input","select","textarea","img","[role]","[data-testid]"].join(",");function je(r){return r.replace(/\s+/g," ").trim()}function ft(r,t){try{let e=new URL(r,t);return e.protocol==="http:"||e.protocol==="https:"?(e.username="",e.password="",e.search="",e.hash="",e.toString()):`${e.protocol}[redacted]`}catch{return r.split(/[?#]/,1)[0].slice(0,500)}}function Yr(r){return Array.from(r.attributes).filter(({name:t})=>{let e=t.toLowerCase();return e==="id"||e==="class"||e==="href"||e==="src"||e==="alt"||e==="title"||e==="name"||e==="type"||e==="role"||e.startsWith("aria-")||e==="data-testid"||e==="data-section-id"||e==="data-product-id"}).map(({name:t,value:e})=>[t,t.toLowerCase()==="href"||t.toLowerCase()==="src"?ft(e,r.ownerDocument.baseURI):e.slice(0,500)])}function Qr(r){let t=r.tagName.toLowerCase(),e=Yr(r).map(([n,a])=>`${n}=${JSON.stringify(a)}`).join(" "),i=r instanceof HTMLInputElement||r instanceof HTMLTextAreaElement||r instanceof HTMLSelectElement?"":je(r.textContent??"").slice(0,600);return`<${t}${e?` ${e}`:""}>${i}</${t}>`}function ti(r=document){let t=[`url=${ft(r.location?.href??"")}`,`title=${je(r.title??"")}`],e=new Set;for(let i of Array.from(r.querySelectorAll(Xr)))if(!(e.has(i)||i.id==="apex-editor-host")&&(e.add(i),t.push(Qr(i)),t.join(`
|
|
3
|
+
`).length>=Ne))break;return t.join(`
|
|
4
|
+
`).slice(0,Ne)}function ei(r){if(!r||typeof r!="object"||Array.isArray(r))return null;let t=r;return typeof t.selector=="string"&&typeof t.action=="string"?t:null}function Ue(r,t){return t.trim()?r.trim()?`${r.trimEnd()}
|
|
5
|
+
|
|
6
|
+
${t.trimStart()}`:t:r}function ri(r){let t=Array.isArray(r.generatedMutations)?r.generatedMutations.map(ei).filter(n=>!!n):[],e=typeof r.generatedCss=="string"?r.generatedCss:"",i=typeof r.generatedJs=="string"?r.generatedJs:"";return r.mergeStrategy==="replace"?{mutations:t,customCss:e,customJs:i}:{mutations:t.reduce((n,a)=>Ot(n,a),r.current).mutations,customCss:Ue(r.current.customCss,e),customJs:Ue(r.current.customJs,i)}}function ii(r,t){if(r&&typeof r=="object"){let e=r.error;if(typeof e=="string"&&e.trim())return e.trim()}return`Operator request failed (${t})`}async function Je(r){let e=await(r.fetchImpl??fetch)(new URL(`/api/editor-sessions/${encodeURIComponent(r.session.sid)}/operator`,r.apiOrigin),{method:"POST",credentials:"omit",cache:"no-store",referrerPolicy:"no-referrer",signal:r.signal,headers:{Authorization:`Bearer ${r.session.bearer}`,"Content-Type":"application/json"},body:JSON.stringify({prompt:r.prompt,variationId:r.variationId,domContext:ti(r.documentLike),pageContext:r.pageContext??`Live merchant page: ${ft(r.session.targetUrl)}`,existingMutations:r.artifacts.mutations,existingCustomCss:r.artifacts.customCss,existingCustomJs:r.artifacts.customJs,conversation:r.conversation.slice(-Zr),selectedElement:r.selectedElement??void 0})}),i=await e.json().catch(()=>null);if(!e.ok||!i)throw new Error(ii(i,e.status));let n=i.mergeStrategy==="replace"?"replace":"append",a=ri({current:r.artifacts,generatedMutations:i.mutations,generatedCss:i.customCss,generatedJs:i.customJs,mergeStrategy:n}),c=(Array.isArray(i.mutations)?i.mutations.length:0)+(typeof i.customCss=="string"&&i.customCss.trim()?1:0)+(typeof i.customJs=="string"&&i.customJs.trim()?1:0);return{artifacts:a,explanation:typeof i.explanation=="string"&&i.explanation.trim()?i.explanation.trim():c?"Draft treatment created. Review the result before QA.":"No draft changes were produced.",artifactCount:c,mergeStrategy:n}}var ni={pointer:"M4 3l7.6 18 2.3-7.4L21 11.5zM13.9 13.9L19 19",undo:"M9 14L4 9l5-5M4 9h10.5a5.5 5.5 0 015.5 5.5v0a5.5 5.5 0 01-5.5 5.5H11",redo:"M15 14l5-5-5-5M20 9H9.5A5.5 5.5 0 004 14.5v0A5.5 5.5 0 009.5 20H13",monitor:"M3 4h18a1 1 0 011 1v11a1 1 0 01-1 1H3a1 1 0 01-1-1V5a1 1 0 011-1zM8 21h8M12 17v4",tablet:"M6 2h12a2 2 0 012 2v16a2 2 0 01-2 2H6a2 2 0 01-2-2V4a2 2 0 012-2zM12 18h.01",phone:"M8 2h8a2 2 0 012 2v16a2 2 0 01-2 2H8a2 2 0 01-2-2V4a2 2 0 012-2zM11 18h2",wifiOff:"M2 2l20 20M8.5 16.5a5 5 0 015.6-1M5 12.5a10 10 0 015.2-2.7M2 8.8a15 15 0 014.2-2.5M16.6 6.6A15 15 0 0122 8.8M12 20h.01",braces:"M8 3H7a2 2 0 00-2 2v4a2 2 0 01-2 2 2 2 0 012 2v4a2 2 0 002 2h1M16 3h1a2 2 0 012 2v4a2 2 0 002 2 2 2 0 00-2 2v4a2 2 0 01-2 2h-1",collapse:"M9 3v18M3 5a2 2 0 012-2h14a2 2 0 012 2v14a2 2 0 01-2 2H5a2 2 0 01-2-2zM13 10l3 2-3 2",history:"M3 12a9 9 0 113 6.7M3 12H1.5M3 12l-1.8 2M12 7v5l3.5 2",send:"M22 2L11 13M22 2l-7 20-4-9-9-4z",stop:"M6 6h12v12H6z",cursorBox:"M3 3h8M3 3v8M21 13v8h-8M9 9l7 7M16 9v7h-7",check:"M5 13l4 4L19 7",x:"M18 6L6 18M6 6l12 12",chevD:"M6 9l6 6 6-6",chevR:"M9 6l6 6-6 6",refresh:"M3 12a9 9 0 0114.5-7L21 8M21 3v5h-5M21 12a9 9 0 01-14.5 7L3 16M3 21v-5h5",external:"M15 3h6v6M21 3l-9 9M10 5H5a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2v-5",code:"M16 18l6-6-6-6M8 6l-6 6 6 6",clock:"M12 22a10 10 0 100-20 10 10 0 000 20zM12 7v5l3 2",eye:"M2 12s4-7 10-7 10 7 10 7-4 7-10 7-10-7-10-7zM12 15a3 3 0 100-6 3 3 0 000 6z",alert:"M10.3 3.9L1.8 18a2 2 0 001.7 3h17a2 2 0 001.7-3L13.7 3.9a2 2 0 00-3.4 0zM12 9v4M12 17h.01",globe:"M12 2a10 10 0 100 20 10 10 0 000-20zM2 12h20M12 2a15 15 0 010 20M12 2a15 15 0 000 20",play:"M6 4l14 8-14 8z",dot:"M12 12h.01"};function p(r,t=14,e=""){return`<svg width="${t}" height="${t}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" ${e}><path d="${ni[r]}"/></svg>`}var oi=0;function R(r=16,t="#fff"){let e=`apex-op-mark-${++oi}`;return`<svg width="${r}" height="${r}" viewBox="0 0 120 120" fill="none" aria-hidden="true" style="flex-shrink:0">
|
|
7
|
+
<defs><mask id="${e}"><rect width="120" height="120" fill="#fff"/><rect x="0" y="68" width="120" height="6" fill="#000"/></mask></defs>
|
|
8
|
+
<path d="M60 14 C92 14 106 36 106 60 C106 84 92 106 60 106 C28 106 14 84 14 60 C14 36 28 14 60 14 Z M60 38 C46 38 38 48 38 60 C38 72 46 82 60 82 C74 82 82 72 82 60 C82 48 74 38 60 38 Z" fill="${t}" fill-rule="evenodd" mask="url(#${e})"/>
|
|
9
|
+
<rect x="92" y="92" width="14" height="14" rx="2" fill="#5B29FF"/>
|
|
10
|
+
</svg>`}function v(r){return r.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var Be=`
|
|
11
|
+
:host {
|
|
12
|
+
--bg0:#08080A;--bg1:#0A0A0C;--raised:#141419;--raised-hi:#1A1A21;--inset:#0B0B0E;
|
|
13
|
+
--border:rgba(255,255,255,0.06);--border-hi:rgba(255,255,255,0.10);--border-px:rgba(255,255,255,0.14);
|
|
14
|
+
--text1:#FAFAFA;--text2:rgba(255,255,255,0.66);--text3:rgba(255,255,255,0.42);--text4:rgba(255,255,255,0.26);
|
|
15
|
+
--purple500:#5B29FF;--purple400:#7C54FF;--purple300:#9B6FFF;--purple200:#C8B4FF;
|
|
16
|
+
--purple-soft:rgba(91,41,255,0.14);--purple-bd:rgba(124,84,255,0.34);
|
|
17
|
+
--positive:#3DD68C;--warning:#FACC15;--negative:#EB5252;--negative-soft:#F39797;
|
|
18
|
+
all:initial;font-family:Inter,system-ui,sans-serif;color:var(--text1);letter-spacing:0;
|
|
19
|
+
position:fixed;inset:0;z-index:2147483647;pointer-events:none;font-size:12.5px;line-height:1.5;
|
|
20
|
+
}
|
|
21
|
+
*{box-sizing:border-box;letter-spacing:0;margin:0;padding:0}
|
|
22
|
+
button,input,select,textarea{font:inherit;color:inherit;font-family:inherit}
|
|
23
|
+
button{cursor:pointer;background:none;border:none}
|
|
24
|
+
button:disabled{cursor:not-allowed}
|
|
25
|
+
:is(button,textarea,input,a):focus-visible{outline:2px solid var(--purple400);outline-offset:2px}
|
|
26
|
+
@keyframes ee-spin{to{transform:rotate(360deg)}}
|
|
27
|
+
@keyframes ee-pulse{0%{transform:scale(0.7);opacity:0.9}100%{transform:scale(1.6);opacity:0}}
|
|
28
|
+
@keyframes ee-in{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
|
|
29
|
+
.ee-in{animation:ee-in 160ms ease-out}
|
|
30
|
+
.spin{animation:ee-spin 1s linear infinite}
|
|
31
|
+
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:0.01ms!important;animation-iteration-count:1!important;transition-duration:0.01ms!important}}
|
|
32
|
+
|
|
33
|
+
/* Buttons */
|
|
34
|
+
.btn{display:inline-flex;align-items:center;gap:7px;justify-content:center;padding:7px 12px;font-size:13px;font-weight:550;border-radius:8px;border:1px solid transparent;line-height:1.2;white-space:nowrap;transition:background 120ms,border-color 120ms,color 120ms;pointer-events:auto}
|
|
35
|
+
.btn.sm{padding:5px 10px;font-size:12px}
|
|
36
|
+
.btn:disabled{opacity:0.45}
|
|
37
|
+
.btn.primary{background:var(--purple500);color:#fff;border-color:rgba(255,255,255,0.14)}
|
|
38
|
+
.btn.soft{background:var(--purple-soft);color:var(--purple200);border-color:var(--purple-bd)}
|
|
39
|
+
.btn.ghost{background:transparent;color:var(--text2);border-color:var(--border)}
|
|
40
|
+
.btn.ghost:hover{background:var(--raised-hi);color:var(--text1)}
|
|
41
|
+
.btn.bare{background:transparent;color:var(--text2);border-color:transparent}
|
|
42
|
+
.btn.danger{background:rgba(235,82,82,0.14);color:var(--negative-soft);border-color:rgba(235,82,82,0.3)}
|
|
43
|
+
.iconbtn{width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border-radius:8px;border:1px solid transparent;background:transparent;color:var(--text2);flex-shrink:0;transition:background 120ms,color 120ms;pointer-events:auto}
|
|
44
|
+
.iconbtn:hover{background:var(--raised-hi);color:var(--text1)}
|
|
45
|
+
.iconbtn.active{background:var(--purple-soft);color:var(--purple200);border-color:var(--purple-bd)}
|
|
46
|
+
.iconbtn:disabled{opacity:0.4}
|
|
47
|
+
.iconbtn.xs{width:22px;height:22px}
|
|
48
|
+
|
|
49
|
+
/* Status dot */
|
|
50
|
+
.dot{position:relative;width:7px;height:7px;flex-shrink:0;display:inline-block}
|
|
51
|
+
.dot i{position:absolute;inset:0;border-radius:50%}
|
|
52
|
+
.dot.ok i{background:var(--positive)}.dot.warn i{background:var(--warning)}.dot.err i{background:var(--negative)}.dot.purple i{background:var(--purple300)}
|
|
53
|
+
.dot b{position:absolute;inset:-3px;border-radius:50%;border:1px solid currentColor}
|
|
54
|
+
.dot.ok b{color:var(--positive)}.dot.warn b{color:var(--warning)}.dot.err b{color:var(--negative)}.dot.purple b{color:var(--purple300)}
|
|
55
|
+
.dot b{animation:ee-pulse 1.4s ease-out infinite}
|
|
56
|
+
|
|
57
|
+
/* Save chip */
|
|
58
|
+
.save-chip{display:inline-flex;align-items:center;gap:7px;font-size:12px;font-weight:550;padding:4px 9px;border-radius:7px;background:rgba(255,255,255,0.04);border:1px solid var(--border);white-space:nowrap}
|
|
59
|
+
.save-chip.unsaved{color:var(--warning)}
|
|
60
|
+
.save-chip.saving{color:var(--purple200)}
|
|
61
|
+
.save-chip.saved{color:var(--positive)}
|
|
62
|
+
.save-chip.failed,.save-chip.conflict{color:var(--negative-soft);background:rgba(235,82,82,0.10);border-color:rgba(235,82,82,0.25)}
|
|
63
|
+
.save-chip .retry{border:none;background:rgba(255,255,255,0.1);color:#fff;font-size:11.5px;font-weight:600;border-radius:5px;padding:2px 7px;margin-left:2px;pointer-events:auto}
|
|
64
|
+
|
|
65
|
+
/* Segmented control */
|
|
66
|
+
.seg{display:inline-flex;background:var(--inset);border-radius:8px;padding:2px;gap:2px;border:1px solid var(--border);pointer-events:auto}
|
|
67
|
+
.seg button{display:inline-flex;align-items:center;gap:6px;justify-content:center;padding:5px 11px;border-radius:6px;border:none;background:transparent;color:var(--text3);font-size:12px;font-weight:550;transition:background 120ms,color 120ms}
|
|
68
|
+
.seg button.sm{padding:4px 8px}
|
|
69
|
+
.seg button[aria-checked="true"]{background:var(--raised-hi);color:var(--text1);box-shadow:inset 0 0 0 1px var(--border-px)}
|
|
70
|
+
|
|
71
|
+
/* Pills & chips */
|
|
72
|
+
.draft-pill{display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border-radius:999px;background:rgba(250,204,21,0.10);border:1px solid rgba(250,204,21,0.3);font-size:11px;font-weight:600;color:var(--warning);white-space:nowrap}
|
|
73
|
+
.session-chip{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:550;color:var(--warning);padding:4px 9px;border-radius:7px;border:1px solid rgba(250,204,21,0.35);background:rgba(250,204,21,0.08);white-space:nowrap;font-variant-numeric:tabular-nums}
|
|
74
|
+
.session-chip .extend{border:none;background:rgba(250,204,21,0.16);color:var(--warning);font-size:11.5px;font-weight:600;border-radius:5px;padding:2px 7px;pointer-events:auto}
|
|
75
|
+
.session-note{font-size:11px;color:var(--text4);white-space:nowrap}
|
|
76
|
+
.conn-chip{display:inline-flex;align-items:center;gap:7px;font-size:12px;font-weight:550;white-space:nowrap;color:var(--text3)}
|
|
77
|
+
.conn-chip.offline{color:var(--negative-soft)}
|
|
78
|
+
.conn-chip.connecting{color:var(--warning)}
|
|
79
|
+
.ctx-chip{display:inline-flex;align-items:center;gap:7px;max-width:100%;background:var(--purple-soft);border:1px solid var(--purple-bd);border-radius:8px;padding:5px 8px;font-size:11.5px;color:var(--purple200);font-weight:550}
|
|
80
|
+
.ctx-chip .name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
81
|
+
.ctx-chip .replace{border:none;background:rgba(255,255,255,0.08);color:var(--text2);font-size:10.5px;font-weight:600;border-radius:5px;padding:2px 7px;pointer-events:auto}
|
|
82
|
+
.ctx-chip .clear{border:none;background:none;color:var(--text3);padding:2px;display:inline-flex;pointer-events:auto}
|
|
83
|
+
|
|
84
|
+
/* Fields */
|
|
85
|
+
.field{width:100%;background:var(--inset);color:var(--text1);border:1px solid var(--border-hi);border-radius:8px;padding:8px 10px;font-size:12.5px;line-height:1.5;outline:none;resize:vertical;pointer-events:auto}
|
|
86
|
+
.field::placeholder{color:rgba(255,255,255,0.28)}
|
|
87
|
+
.field.code{white-space:pre;font-variant-numeric:tabular-nums;min-height:150px}
|
|
88
|
+
.flabel{display:block;font-size:11.5px;font-weight:550;color:var(--text3);margin-bottom:5px}
|
|
89
|
+
.fhint{display:block;font-size:11px;color:var(--text4);margin-top:4px}
|
|
90
|
+
|
|
91
|
+
/* Banners */
|
|
92
|
+
.banner{display:flex;align-items:center;gap:9px;padding:8px 12px;border-radius:10px;color:var(--text1);font-size:12.5px;box-shadow:0 12px 32px rgba(0,0,0,0.4);pointer-events:auto;max-width:560px}
|
|
93
|
+
.banner .body{flex:1;min-width:0}
|
|
94
|
+
.banner.info{background:linear-gradient(0deg,rgba(91,41,255,0.16),rgba(91,41,255,0.16)),var(--bg1);border:1px solid var(--purple-bd)}
|
|
95
|
+
.banner.info svg{color:var(--purple200)}
|
|
96
|
+
.banner.warn{background:linear-gradient(0deg,rgba(250,204,21,0.10),rgba(250,204,21,0.10)),var(--bg1);border:1px solid rgba(250,204,21,0.35)}
|
|
97
|
+
.banner.warn svg{color:var(--warning)}
|
|
98
|
+
.banner.error{background:linear-gradient(0deg,rgba(235,82,82,0.12),rgba(235,82,82,0.12)),var(--bg1);border:1px solid rgba(235,82,82,0.35)}
|
|
99
|
+
.banner.error svg{color:var(--negative-soft)}
|
|
100
|
+
|
|
101
|
+
/* Modal */
|
|
102
|
+
.modal-backdrop{position:fixed;inset:0;z-index:300;display:flex;align-items:center;justify-content:center;background:rgba(5,5,8,0.55);backdrop-filter:blur(3px);pointer-events:auto}
|
|
103
|
+
.modal{width:430px;max-width:calc(100vw - 40px);background:var(--bg1);border:1px solid var(--border-px);border-radius:14px;box-shadow:0 32px 80px rgba(0,0,0,0.55);overflow:hidden;color:var(--text1)}
|
|
104
|
+
.modal .m-head{display:flex;gap:10px;align-items:flex-start;padding:18px 18px 0}
|
|
105
|
+
.modal .m-icon{width:30px;height:30px;border-radius:8px;background:rgba(255,255,255,0.05);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;flex-shrink:0}
|
|
106
|
+
.modal .m-icon.warn{color:var(--warning)}.modal .m-icon.purple{color:var(--purple300)}.modal .m-icon.ok{color:var(--positive)}
|
|
107
|
+
.modal .m-title{font-size:15px;font-weight:600;letter-spacing:-0.015em;padding-top:4px}
|
|
108
|
+
.modal .m-body{padding:12px 18px 4px;font-size:13px;line-height:1.6;color:var(--text2)}
|
|
109
|
+
.modal .m-body p{margin:0}
|
|
110
|
+
.modal .m-body p+p{margin-top:10px}
|
|
111
|
+
.modal .m-actions{display:flex;justify-content:flex-end;gap:8px;padding:14px 18px 18px}
|
|
112
|
+
`;var Qt=352,Ve=52,Pt=300,ai=`
|
|
113
|
+
.zone{position:fixed;left:0;top:0;bottom:0;right:${Qt}px;pointer-events:none}
|
|
114
|
+
.zone.rail{right:${Ve}px}
|
|
115
|
+
.zone.narrow{right:0}
|
|
116
|
+
.page-border{position:absolute;inset:0;pointer-events:none;box-shadow:inset 0 0 0 3px rgba(91,41,255,0.75)}
|
|
117
|
+
.select-banner{position:absolute;top:12px;left:50%;transform:translateX(-50%);display:flex;align-items:center;gap:9px;padding:7px 12px;background:var(--purple500);color:#fff;border-radius:999px;border:1px solid rgba(255,255,255,0.25);box-shadow:0 12px 32px rgba(91,41,255,0.45);font-size:12.5px;font-weight:600;white-space:nowrap;pointer-events:auto}
|
|
118
|
+
.select-banner button{border:none;background:rgba(255,255,255,0.16);color:#fff;font-size:11.5px;font-weight:600;border-radius:999px;padding:3px 9px}
|
|
119
|
+
.banners{position:absolute;left:50%;transform:translateX(-50%);display:grid;gap:8px;width:max-content;max-width:calc(100% - 24px);pointer-events:none}
|
|
120
|
+
.banners.lower{top:54px}
|
|
121
|
+
.banners:not(.lower){top:12px}
|
|
122
|
+
.orig-chip{position:absolute;bottom:14px;left:50%;transform:translateX(-50%);display:flex;align-items:center;gap:8px;padding:6px 12px;border-radius:999px;background:rgba(10,10,13,0.92);border:1px solid var(--border-px);color:var(--text2);font-size:12px;font-weight:550;white-space:nowrap;pointer-events:auto}
|
|
123
|
+
.orig-chip svg{color:var(--purple300)}
|
|
124
|
+
.orig-chip button{border:none;background:var(--purple-soft);color:var(--purple200);font-size:11.5px;font-weight:600;border-radius:999px;padding:3px 9px}
|
|
125
|
+
|
|
126
|
+
.dock{position:fixed;right:0;top:0;bottom:0;width:${Qt}px;background:var(--bg1);border-left:1px solid var(--border-px);display:flex;flex-direction:column;min-height:0;pointer-events:auto}
|
|
127
|
+
.rail-dock{position:fixed;right:0;top:0;bottom:0;width:${Ve}px;background:var(--bg1);border-left:1px solid var(--border-px);display:flex;flex-direction:column;align-items:center;gap:10px;padding:12px 0;pointer-events:auto}
|
|
128
|
+
.rail-dock .sep{width:24px;height:1px;background:var(--border)}
|
|
129
|
+
.rail-dock .grow{flex:1}
|
|
130
|
+
|
|
131
|
+
.id-head{padding:12px 14px 10px;border-bottom:1px solid var(--border);flex-shrink:0}
|
|
132
|
+
.id-row{display:flex;align-items:center;gap:9px}
|
|
133
|
+
.id-meta{flex:1;min-width:0}
|
|
134
|
+
.id-title{font-size:13px;font-weight:600;letter-spacing:-0.01em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
135
|
+
.id-sub{font-size:11px;color:var(--text3);margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
136
|
+
.id-chips{display:flex;align-items:center;gap:8px;margin-top:10px;flex-wrap:wrap}
|
|
137
|
+
.id-chips .grow{flex:1}
|
|
138
|
+
.id-conn{margin-top:8px}
|
|
139
|
+
|
|
140
|
+
.var-wrap{position:relative}
|
|
141
|
+
.var-btn{display:flex;align-items:center;gap:8px;padding:5px 9px;background:var(--raised);border:1px solid var(--border-hi);border-radius:8px;color:var(--text1);font-size:12.5px;font-weight:550;max-width:190px;pointer-events:auto}
|
|
142
|
+
.var-btn .vid{width:18px;height:18px;border-radius:5px;background:var(--purple-soft);border:1px solid var(--purple-bd);color:var(--purple200);font-size:10.5px;font-weight:700;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}
|
|
143
|
+
.var-btn .vname{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
144
|
+
.var-menu{position:absolute;top:calc(100% + 6px);left:0;z-index:250;width:248px;background:var(--bg1);border:1px solid var(--border-px);border-radius:10px;box-shadow:0 20px 48px rgba(0,0,0,0.55);padding:5px;pointer-events:auto}
|
|
145
|
+
.var-menu .note{font-size:11px;color:var(--text3);padding:6px 9px 4px}
|
|
146
|
+
.var-item{display:flex;align-items:center;gap:9px;width:100%;text-align:left;padding:8px 9px;border-radius:7px;border:none;background:transparent;color:var(--text1)}
|
|
147
|
+
.var-item[aria-selected="true"]{background:var(--purple-soft)}
|
|
148
|
+
.var-item .vid{width:20px;height:20px;border-radius:5px;flex-shrink:0;background:var(--raised-hi);color:#fff;font-size:11px;font-weight:700;display:inline-flex;align-items:center;justify-content:center}
|
|
149
|
+
.var-item[aria-selected="true"] .vid{background:var(--purple500)}
|
|
150
|
+
.var-item .meta{flex:1;min-width:0}
|
|
151
|
+
.var-item .n{display:block;font-size:12.5px;font-weight:550;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
152
|
+
.var-item .s{display:block;font-size:11px;color:var(--text3)}
|
|
153
|
+
|
|
154
|
+
.view-row{display:flex;align-items:center;gap:8px;padding:8px 14px;border-bottom:1px solid var(--border);flex-shrink:0}
|
|
155
|
+
.view-row .grow{flex:1}
|
|
156
|
+
.undo-redo{display:flex;gap:2px}
|
|
157
|
+
|
|
158
|
+
.tabs{display:flex;gap:2px;padding:0 8px;border-bottom:1px solid var(--border);flex-shrink:0}
|
|
159
|
+
.tab{display:inline-flex;align-items:center;gap:6px;padding:9px 10px 8px;background:none;border:none;border-bottom:2px solid transparent;color:var(--text3);font-size:12.5px;font-weight:550;margin-bottom:-1px;transition:color 120ms;pointer-events:auto}
|
|
160
|
+
.tab[aria-selected="true"]{color:var(--text1);border-bottom-color:var(--purple400)}
|
|
161
|
+
.tab .count{font-size:10.5px;font-weight:650;background:var(--raised-hi);color:var(--text3);border-radius:999px;padding:1px 6px}
|
|
162
|
+
.tab[aria-selected="true"] .count{background:var(--purple-soft);color:var(--purple200)}
|
|
163
|
+
|
|
164
|
+
.panel{flex:1;min-height:0;display:flex;flex-direction:column}
|
|
165
|
+
.foot{display:flex;align-items:center;gap:10px;padding:10px 14px;border-top:1px solid var(--border);flex-shrink:0}
|
|
166
|
+
.foot .grow{flex:1}
|
|
167
|
+
|
|
168
|
+
/* Operator */
|
|
169
|
+
.op-ctx{padding:10px 14px 8px;border-bottom:1px solid var(--border);flex-shrink:0;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
|
|
170
|
+
.op-ctx .lbl{font-size:11.5px;color:var(--text3)}
|
|
171
|
+
.op-ctx .opt{font-size:11.5px;color:var(--text4)}
|
|
172
|
+
.op-thread{flex:1;overflow-y:auto;min-height:0;padding:12px 14px;display:flex;flex-direction:column;gap:10px}
|
|
173
|
+
.op-empty{margin:auto 0;text-align:center;padding:18px 6px}
|
|
174
|
+
.op-empty .mark{width:42px;height:42px;margin:0 auto 12px;border-radius:12px;background:var(--purple-soft);border:1px solid var(--purple-bd);display:flex;align-items:center;justify-content:center}
|
|
175
|
+
.op-empty .t{font-size:13.5px;font-weight:600;color:var(--text1);margin-bottom:5px}
|
|
176
|
+
.op-empty p{font-size:12.5px;color:var(--text3);line-height:1.6;margin:0 0 14px}
|
|
177
|
+
.op-empty .sugs{display:flex;flex-direction:column;gap:6px;align-items:stretch}
|
|
178
|
+
.sug{font-size:12px;color:var(--text2);background:var(--raised);border:1px solid var(--border);border-radius:8px;padding:7px 11px;text-align:left;pointer-events:auto}
|
|
179
|
+
.msg-user{align-self:flex-end;max-width:88%;display:grid;gap:4px;justify-items:end}
|
|
180
|
+
.msg-user .ref{display:inline-flex;align-items:center;gap:5px;font-size:10.5px;color:var(--purple200);background:var(--purple-soft);border:1px solid var(--purple-bd);border-radius:6px;padding:2px 7px}
|
|
181
|
+
.msg-user .bubble{background:var(--purple500);color:#fff;border-radius:12px 12px 3px 12px;padding:8px 11px;font-size:12.5px;line-height:1.5;white-space:pre-wrap;word-break:break-word}
|
|
182
|
+
.op-card{align-self:stretch;border-radius:12px;padding:10px 12px}
|
|
183
|
+
.op-card.working{background:var(--inset);border:1px solid var(--border)}
|
|
184
|
+
.op-card.failed{background:rgba(235,82,82,0.08);border:1px solid rgba(235,82,82,0.3)}
|
|
185
|
+
.op-card.done{background:rgba(61,214,140,0.06);border:1px solid rgba(61,214,140,0.28)}
|
|
186
|
+
.op-card .head{display:flex;align-items:center;gap:8px;font-size:12px;font-weight:600;margin-bottom:7px}
|
|
187
|
+
.op-card.working .head{color:var(--text1);margin-bottom:8px}
|
|
188
|
+
.op-card.failed .head{color:var(--negative-soft);margin-bottom:5px}
|
|
189
|
+
.op-card.done .head{color:var(--positive)}
|
|
190
|
+
.op-card .steps{display:grid;gap:7px}
|
|
191
|
+
.op-card .step{display:flex;align-items:center;gap:9px;font-size:12px}
|
|
192
|
+
.op-card .step.done{color:var(--text3)}
|
|
193
|
+
.op-card .step.cur{color:var(--text1)}
|
|
194
|
+
.op-card .step.todo{color:var(--text4)}
|
|
195
|
+
.op-card .step .idle{width:12px;text-align:center;color:var(--text4)}
|
|
196
|
+
.op-card p{font-size:12px;color:var(--text2);line-height:1.55;margin:0}
|
|
197
|
+
.op-card .items{display:grid;gap:6px}
|
|
198
|
+
.op-card .item{font-size:12px;color:var(--text2);display:flex;gap:8px;align-items:baseline}
|
|
199
|
+
.op-card .item .b{flex:1;line-height:1.45}
|
|
200
|
+
.op-card .item .sel{display:block;font-size:10.5px;color:var(--text4);word-break:break-all}
|
|
201
|
+
.op-card .row{display:flex;gap:8px;margin-top:10px;flex-wrap:wrap}
|
|
202
|
+
.op-card .hint{font-size:10.5px;color:var(--text4);margin-top:8px}
|
|
203
|
+
.op-input{padding:10px 14px 12px;border-top:1px solid var(--border);flex-shrink:0}
|
|
204
|
+
.op-input .line{display:flex;gap:8px;align-items:flex-end}
|
|
205
|
+
.op-input textarea{flex:1;min-height:52px;max-height:120px}
|
|
206
|
+
.op-input .send{width:34px;height:34px;flex:0 0 34px;border-radius:8px;background:var(--purple500);color:#fff;display:inline-flex;align-items:center;justify-content:center;border:1px solid rgba(255,255,255,0.14);pointer-events:auto}
|
|
207
|
+
.op-input .send:disabled{opacity:0.4}
|
|
208
|
+
.op-input .note{font-size:10.5px;color:var(--text4);margin-top:6px}
|
|
209
|
+
|
|
210
|
+
/* Code */
|
|
211
|
+
.code-panel{display:flex;flex-direction:column;min-height:0;overflow-y:auto;flex:1}
|
|
212
|
+
.code-head{padding:10px 14px 0;display:flex;align-items:center;gap:8px}
|
|
213
|
+
.code-head .peer{font-size:11px;color:var(--text4)}
|
|
214
|
+
.code-body{padding:12px 14px;display:grid;gap:10px}
|
|
215
|
+
.code-ok{font-size:11.5px;color:var(--text3);display:flex;gap:7px;align-items:center}
|
|
216
|
+
.code-ok svg{color:var(--positive)}
|
|
217
|
+
.js-warn{display:flex;gap:9px;padding:9px 11px;border-radius:9px;background:rgba(250,204,21,0.08);border:1px solid rgba(250,204,21,0.3);font-size:11.5px;line-height:1.55;color:var(--text2)}
|
|
218
|
+
.js-warn svg{color:var(--warning);flex-shrink:0;margin-top:1px}
|
|
219
|
+
.js-warn strong{color:var(--warning);font-weight:600}
|
|
220
|
+
.code-foot{border-top:1px solid var(--border);padding:10px 14px 12px;font-size:11.5px;color:var(--text3);line-height:1.6}
|
|
221
|
+
.code-foot button{border:none;background:none;color:var(--purple200);font-size:11.5px;padding:0;text-decoration:underline;text-underline-offset:2px;pointer-events:auto}
|
|
222
|
+
|
|
223
|
+
/* Changes */
|
|
224
|
+
.chg-panel{overflow-y:auto;flex:1;min-height:0}
|
|
225
|
+
.chg-head{padding:12px 14px 8px;display:flex;align-items:center;gap:8px}
|
|
226
|
+
.chg-head .t{font-size:13px;font-weight:600;color:var(--text1);flex:1}
|
|
227
|
+
.chg-empty{font-size:12.5px;color:var(--text3);padding:4px 14px 14px;line-height:1.6}
|
|
228
|
+
.chg-list{display:grid;gap:6px;padding:2px 14px 12px}
|
|
229
|
+
.chg-row{display:flex;gap:9px;align-items:flex-start;padding:9px 10px;background:var(--inset);border:1px solid var(--border);border-radius:9px}
|
|
230
|
+
.chg-row .org{margin-top:1px;flex-shrink:0;color:var(--purple300)}
|
|
231
|
+
.chg-row .meta{flex:1;min-width:0}
|
|
232
|
+
.chg-row .l{font-size:12.5px;color:var(--text1);font-weight:550;line-height:1.4;word-break:break-word}
|
|
233
|
+
.chg-row .s{font-size:11px;color:var(--text4);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
234
|
+
.chg-art{border-top:1px solid var(--border);padding:10px 14px 12px}
|
|
235
|
+
.chg-art .toggle{display:inline-flex;align-items:center;gap:7px;border:none;background:none;color:var(--text2);font-size:12px;font-weight:550;padding:0;pointer-events:auto}
|
|
236
|
+
.chg-art .json{margin-top:8px;background:var(--inset);border:1px solid var(--border);border-radius:9px;padding:10px 12px;font-size:11px;line-height:1.65;color:var(--text2);white-space:pre-wrap;word-break:break-word;font-variant-numeric:tabular-nums;max-height:280px;overflow:auto}
|
|
237
|
+
.chg-art .note{font-size:11.5px;color:var(--text3);line-height:1.55;margin-top:10px}
|
|
238
|
+
.chg-art .pill-row{margin-top:8px}
|
|
239
|
+
|
|
240
|
+
/* Boot overlay */
|
|
241
|
+
.boot{position:fixed;inset:0;z-index:400;background:#08080A;display:flex;align-items:center;justify-content:center;pointer-events:auto}
|
|
242
|
+
.boot[hidden]{display:none}
|
|
243
|
+
.boot .box{width:330px;max-width:calc(100vw - 48px)}
|
|
244
|
+
.boot .kicker{display:flex;align-items:center;gap:8px;margin-bottom:8px;font-size:15px;font-weight:650;letter-spacing:-0.02em}
|
|
245
|
+
.boot .sub{font-size:12.5px;color:var(--text3);margin-bottom:22px}
|
|
246
|
+
.boot .steps{display:grid;gap:12px}
|
|
247
|
+
.boot .step{display:flex;align-items:center;gap:10px;font-size:13px}
|
|
248
|
+
.boot .step.done{color:var(--text3)}
|
|
249
|
+
.boot .step.cur{color:#fff}
|
|
250
|
+
.boot .step.todo{color:var(--text4)}
|
|
251
|
+
.boot .step .idle{width:14px;text-align:center}
|
|
252
|
+
.boot .bar{margin-top:26px;height:3px;border-radius:999px;background:var(--raised-hi);overflow:hidden}
|
|
253
|
+
.boot .bar i{display:block;height:100%;background:var(--purple500);border-radius:999px;transition:width 400ms ease}
|
|
254
|
+
.boot .scope{margin-top:22px;font-size:11.5px;color:var(--text4);line-height:1.6}
|
|
255
|
+
.boot .err{margin-top:18px;font-size:12.5px;color:var(--negative-soft);line-height:1.55}
|
|
256
|
+
|
|
257
|
+
/* Picker overlay */
|
|
258
|
+
.picker-box{position:fixed;left:0;top:0;border:2px solid var(--purple400);background:rgba(91,41,255,0.08);pointer-events:none;z-index:200}
|
|
259
|
+
.picker-box[data-state="hover"]{border-style:dashed}
|
|
260
|
+
.picker-box[data-state="selected"]{border-style:solid;border-color:var(--purple500)}
|
|
261
|
+
.picker-label{position:fixed;left:0;top:0;padding:3px 8px;border-radius:6px;background:var(--purple500);color:#fff;font-size:11px;font-weight:600;white-space:nowrap;pointer-events:none;z-index:201}
|
|
262
|
+
|
|
263
|
+
/* Device preview */
|
|
264
|
+
.device{position:fixed;left:0;top:0;bottom:0;right:${Qt}px;background:var(--bg0);display:flex;align-items:center;justify-content:center;padding:24px;pointer-events:auto;z-index:90}
|
|
265
|
+
.device.narrow{right:0}
|
|
266
|
+
.device[hidden]{display:none}
|
|
267
|
+
.device-shell{display:flex;flex-direction:column;gap:12px;align-items:center;max-width:100%;max-height:100%}
|
|
268
|
+
.device-head{width:min(420px,100%);display:flex;align-items:center;justify-content:space-between;color:var(--text2);font-size:12px}
|
|
269
|
+
.device-frame{border:1px solid var(--border-hi);border-radius:10px;background:#fff;box-shadow:0 24px 64px rgba(0,0,0,0.5);max-width:calc(100% - 8px);max-height:calc(100vh - 140px)}
|
|
270
|
+
.device-fallback{width:390px;max-width:calc(100vw - 48px);padding:16px;background:var(--raised);border:1px solid var(--border-hi);border-radius:10px;color:var(--text2);font-size:12px;line-height:1.6}
|
|
271
|
+
.device-fallback .row{display:flex;gap:8px;margin-top:10px}
|
|
272
|
+
|
|
273
|
+
/* Narrow viewport: bottom sheet */
|
|
274
|
+
.sheet{position:fixed;left:0;right:0;bottom:0;background:var(--bg1);border-top:1px solid var(--border-px);border-radius:16px 16px 0 0;box-shadow:0 -16px 48px rgba(0,0,0,0.5);display:flex;flex-direction:column;pointer-events:auto;max-height:64vh}
|
|
275
|
+
.sheet .handle{background:none;border:none;padding:8px 0 4px;display:flex;justify-content:center;width:100%;pointer-events:auto}
|
|
276
|
+
.sheet .handle i{width:36px;height:4px;border-radius:999px;background:var(--border-px);display:block}
|
|
277
|
+
.sheet .bar{display:flex;align-items:center;gap:8px;padding:2px 14px 10px;flex-wrap:wrap}
|
|
278
|
+
.sheet .bar .grow{flex:1}
|
|
279
|
+
.sheet .row2{display:flex;align-items:center;gap:8px;padding:0 14px 8px;flex-wrap:wrap}
|
|
280
|
+
`,si=["Make the announcement bar mention free returns","Add a trust message below the buy button","Make this section more compact"];function Fe(r){let t=li(r.selector);switch(r.action){case"text":case"setText":return`${t}: \u201C${(r.text??"").trim().slice(0,80)}\u201D`;case"html":return`${t}: content replaced`;case"attribute":{let e=[...r.attribute?[r.attribute.name]:[],...Object.keys(r.attributes??{})];return e.includes("src")?`${t}: image swapped`:`${t}: ${e.join(", ")||"attribute"} changed`}case"style":case"setStyle":return`${t}: style changed`;case"remove":return`${t}: removed`;case"insertBefore":case"insertAfter":return`${t}: content added`;default:return`${t}: updated`}}function li(r){return(r.split(/[\s>+~]+/).filter(Boolean).pop()??r).slice(0,60)||"Element"}function ci(r){return r.saveState==="saving"?"saving":r.saveState==="saved"?"saved":r.saveState==="conflict"?"conflict":r.saveState==="error"?"failed":r.variation?"unsaved":"loading"}function te(r){let t=ci(r),e=t==="unsaved"?"Unsaved changes":t==="saving"?"Saving\u2026":t==="saved"?"Saved":t==="failed"?"Save failed":t==="conflict"?"Conflict":"Loading draft\u2026",i=t==="saving"||t==="loading"?p("refresh",12,'class="spin"'):t==="saved"?p("check",12):t==="unsaved"?p("dot",12):p("alert",12);return`<span class="save-chip ${t==="loading"?"saving":t}" role="status" aria-live="polite">${i}${e}${t==="failed"?'<button type="button" class="retry" data-action="retry-save">Retry</button>':""}</span>`}function ht(r){let t=r.artifacts.mutations.map((e,i)=>({kind:"mutation",selector:e.selector,mutationIndex:i,label:Fe(e),target:e.selector,origin:"operator",risky:!1}));return r.artifacts.customCss.trim()&&t.push({kind:"css",selector:null,mutationIndex:null,label:"Custom CSS",target:`${r.artifacts.customCss.trim().split(`
|
|
281
|
+
`).length} lines`,origin:"code",risky:!1}),r.artifacts.customJs.trim()&&t.push({kind:"js",selector:null,mutationIndex:null,label:"Custom JavaScript",target:"runs when the variation loads",origin:"code",risky:r.reloadRequired}),t}function ee(r,t){let e=new Set(r.mutations.map(n=>JSON.stringify(n))),i=t.mutations.filter(n=>!e.has(JSON.stringify(n))).map(n=>({label:Fe(n),target:n.selector}));return t.customCss.trim()!==r.customCss.trim()&&i.push({label:"Custom CSS updated",target:"variation stylesheet"}),t.customJs.trim()!==r.customJs.trim()&&i.push({label:"Custom JavaScript updated",target:"variation script"}),i}function qe(r){let t=Math.floor(r/60),e=Math.max(0,Math.floor(r%60));return`${t}:${String(e).padStart(2,"0")}`}function We(r,t){let e=document.createElement("style");e.textContent=Be+ai;let i=document.createElement("div"),n=document.createElement("div");n.className="zone";let a=document.createElement("div");a.className="picker-box",a.hidden=!0;let c=document.createElement("div");c.className="picker-label",c.hidden=!0;let l=document.createElement("div");l.className="device",l.hidden=!0;let f=document.createElement("div");f.className="boot",r.append(e,n,i,a,c,l,f);let g=t.session,S=(()=>{try{return new URL(g.targetUrl).host}catch{return g.targetOrigin.replace(/^https?:\/\//,"")}})(),E=(()=>{try{let o=new URL(g.targetUrl);return o.pathname+o.search}catch{return null}})(),$=g.experimentName?.trim()||"On-site editor",Dt=o=>`${t.apiOrigin}/tests/${encodeURIComponent(g.experimentId)}/variations/${encodeURIComponent(o)}`,mt=()=>Math.max(0,Math.floor((Date.parse(g.expiresAt)-Date.now())/1e3)),u=t.getState(),_="operator",gt="css",tt=!1,et=!1,U=!1,j=!1,J="variation",F=u.selectedSelector,I=u.selectedElement?ct(u.selectedElement):u.selectedSelector,rt="desktop",P=navigator.onLine===!1?"offline":"connected",M=null,it=!1,D=null,W=!1,nt="",ot=!1,vt=null,zt=0,Nt=null,Ut=mt()<=Pt,B=!1,oe=0,O=[],at=[],bt=typeof window.matchMedia=="function"?window.matchMedia("(max-width: 759px)"):null;U=bt?.matches??!1;let ae=new It(Ge(),o=>{t.setDeviceState(o)});t.attachDevicePreview(ae);function Ge(){return l.innerHTML=`<div class="device-shell">
|
|
282
|
+
<div class="device-head"><span class="d-title">Device preview</span><button type="button" class="iconbtn" data-action="device-close" aria-label="Close device preview">${p("x",13)}</button></div>
|
|
283
|
+
<iframe class="device-frame" name="${Pe}" title="Store device preview"></iframe>
|
|
284
|
+
<div class="device-fallback" hidden>The store blocks device framing. Open this draft on a mobile device or use your browser's device mode.<div class="row"><button type="button" class="btn ghost sm" data-action="device-copy">Copy current URL</button></div></div>
|
|
285
|
+
</div>`,l.querySelector("iframe")}let jt=l.querySelector("iframe"),Ze=l.querySelector(".device-fallback"),T=new _t({box:a,label:c},(o,s)=>{t.selectElement(o,s),T.setSelected(o),F=s,I=ct(o),_="operator",U&&(et=!0),m()},o=>{t.setPickerActive(o),m()},()=>{M="unsupported",m()}),Jt=o=>`<span class="draft-pill">${p("eye",11)}${o?"Draft":"Draft \u2014 not visible to shoppers"}</span>`,Xe=()=>P==="offline"?'<span class="conn-chip offline" role="status"><span class="dot err"><i></i><b></b></span>Offline \u2014 reconnecting\u2026</span>':"",se=()=>{let o=mt();return o<=Pt?`<span class="session-chip" title="Editing session time remaining">${p("clock",12)}<span data-session-text>Session ends in ${qe(o)}</span><button type="button" class="extend" data-action="extend-session">Extend</button></span>`:`<span class="session-note" title="Editing session time remaining" data-session-text>Session \xB7 ${Math.floor(o/60)} min left</span>`},le=o=>{let s=u.variation,h=s?.name||"Variation",d=(h.trim()[0]||"V").toUpperCase(),k=j?`<div class="var-menu ee-in" role="listbox" aria-label="Eligible variations">
|
|
286
|
+
<div class="note">Switching keeps your saved draft \u2014 nothing is lost.</div>
|
|
287
|
+
${g.variations.map(y=>{let b=y.id===s?.id,x=y.name||y.slug||"Variation",K=(x.trim()[0]||"V").toUpperCase();return`<button type="button" class="var-item" role="option" aria-selected="${b}" data-action="variation-pick" data-variation="${v(y.id)}">
|
|
288
|
+
<span class="vid" aria-hidden="true">${v(K)}</span>
|
|
289
|
+
<span class="meta"><span class="n">${v(x)}</span><span class="s">${b?`${ht(u).length} change${ht(u).length===1?"":"s"} in draft`:"Draft"}</span></span>
|
|
290
|
+
${b?p("check",13):""}
|
|
291
|
+
</button>`}).join("")}
|
|
292
|
+
</div>`:"";return`<div class="var-wrap">
|
|
293
|
+
<button type="button" class="var-btn" data-action="variation-open" aria-haspopup="listbox" aria-expanded="${j}" aria-label="Variation: ${v(h)}. Switch variation">
|
|
294
|
+
<span class="vid" aria-hidden="true">${v(d)}</span>
|
|
295
|
+
${o?"":`<span class="vname">${v(h)}</span>`}
|
|
296
|
+
${p("chevD",12)}
|
|
297
|
+
</button>
|
|
298
|
+
${k}
|
|
299
|
+
</div>`},ce=()=>{let o=u.variation?.name||"Variation";return`<div class="seg" role="radiogroup" aria-label="Compare original and variation">
|
|
300
|
+
<button type="button" role="radio" aria-checked="${J==="original"}" data-action="compare" data-view="original">Original</button>
|
|
301
|
+
<button type="button" role="radio" aria-checked="${J==="variation"}" data-action="compare" data-view="variation">${v(o)}</button>
|
|
302
|
+
</div>`},Ye=()=>`<div class="seg" role="radiogroup" aria-label="Preview viewport">
|
|
303
|
+
<button type="button" class="sm" role="radio" aria-checked="${rt==="desktop"}" data-action="device" data-device="desktop" title="Desktop preview" aria-label="Desktop preview">${p("monitor",13)}</button>
|
|
304
|
+
<button type="button" class="sm" role="radio" aria-checked="${rt==="tablet"}" data-action="device" data-device="tablet" title="Tablet preview \u2014 768px" aria-label="Tablet preview, 768 pixels">${p("tablet",13)}</button>
|
|
305
|
+
<button type="button" class="sm" role="radio" aria-checked="${rt==="mobile"}" data-action="device" data-device="mobile" title="Mobile preview \u2014 390px" aria-label="Mobile preview, 390 pixels">${p("phone",13)}</button>
|
|
306
|
+
</div>`,de=()=>`<div class="undo-redo">
|
|
307
|
+
<button type="button" class="iconbtn" data-action="undo" aria-label="Undo" title="Undo" ${u.canUndo?"":"disabled"}>${p("undo",15)}</button>
|
|
308
|
+
<button type="button" class="iconbtn" data-action="redo" aria-label="Redo" title="Redo" ${u.canRedo?"":"disabled"}>${p("redo",15)}</button>
|
|
309
|
+
</div>`,pe=()=>{let o=ht(u).length,s=(h,d,k,y)=>`<button type="button" class="tab" role="tab" aria-selected="${_===h}" data-action="tab" data-tab="${h}">${k}${d}${y?`<span class="count">${y}</span>`:""}</button>`;return`<div class="tabs" role="tablist" aria-label="Editor panels">
|
|
310
|
+
${s("operator","Operator",R(12,_==="operator"?"#fff":"rgba(255,255,255,0.55)"))}
|
|
311
|
+
${s("code","Code",p("braces",13))}
|
|
312
|
+
${s("changes","Changes",p("history",13),o)}
|
|
313
|
+
</div>`},Qe=(o,s)=>`<span class="ctx-chip">${p("cursorBox",12)}<span class="name">${v(s)}</span>${o?"":`<button type="button" class="replace" data-action="ctx-replace" aria-label="Replace selected element">Replace</button><button type="button" class="clear" data-action="ctx-clear" aria-label="Clear selected element">${p("x",11)}</button>`}</span>`,tr=()=>{let o=u.pickerActive,s=F&&I?`<span class="lbl">Talking about</span>${Qe(!1,I)}`:`<button type="button" class="btn sm ${o?"primary":"soft"}" data-action="inspect-toggle">${p("pointer",13)}${o?"Click something on the page\u2026":"Point at an element"}</button><span class="opt">optional \u2014 you can also just describe the change</span>`,h=O.length===0,d=`<div class="op-empty">
|
|
314
|
+
<div class="mark" aria-hidden="true">${R(20)}</div>
|
|
315
|
+
<div class="t">What should change on this page?</div>
|
|
316
|
+
<p>Point at an element or just describe it. Operator makes the change on the draft \u2014 you see it on the real page immediately.</p>
|
|
317
|
+
<div class="sugs">${si.map(b=>`<button type="button" class="sug" data-action="suggestion">${v(b)}</button>`).join("")}</div>
|
|
318
|
+
</div>`,k=O.map(b=>{if(b.role==="user")return`<div class="msg-user">${b.ctxLabel?`<span class="ref">${p("cursorBox",10)} ${v(b.ctxLabel)}</span>`:""}<div class="bubble">${v(b.text)}</div></div>`;if(b.phase==="working")return`<div class="op-card working ee-in">
|
|
319
|
+
<div class="head">${R(13)}<span>Operator</span>${b.abort?`<button type="button" class="btn sm bare" style="margin-left:auto;padding:2px 6px" data-action="op-stop" data-msg="${b.id}">${p("stop",12)}Stop</button>`:""}</div>
|
|
320
|
+
<div class="steps" role="status" aria-live="polite">${b.steps.map((G,st)=>{let A=st<b.step?"done":st===b.step?"cur":"todo",yt=A==="done"?p("check",12):A==="cur"?p("refresh",12,'class="spin"'):'<span class="idle">\xB7</span>';return`<div class="step ${A}">${yt}${v(G)}</div>`}).join("")}</div>
|
|
321
|
+
</div>`;if(b.phase==="failed")return`<div class="op-card failed ee-in" role="alert">
|
|
322
|
+
<div class="head">${p("alert",13)} Operator couldn't finish</div>
|
|
323
|
+
<p>${v(b.error??"Something went wrong.")} Nothing was changed on the draft.</p>
|
|
324
|
+
<div class="row"><button type="button" class="btn sm soft" data-action="op-retry" data-msg="${b.id}">${p("refresh",12)}Try again</button></div>
|
|
325
|
+
</div>`;if(b.phase==="save-failed")return`<div class="op-card failed ee-in" role="alert">
|
|
326
|
+
<div class="head">${p("alert",13)} Change applied, but not saved</div>
|
|
327
|
+
<p>${v(b.error??"The draft could not be saved.")} The proposed change remains on this page so you can review it and retry saving.</p>
|
|
328
|
+
<div class="row"><button type="button" class="btn sm soft" data-action="retry-save" data-msg="${b.id}">${p("refresh",12)}Retry save</button><button type="button" class="btn sm bare" data-action="op-all-changes">${p("history",12)}Review changes</button></div>
|
|
329
|
+
</div>`;let x=b.results.length,K=he(b);return`<div class="op-card done ee-in">
|
|
330
|
+
<div class="head">${p("check",13)} ${x===1?"Made 1 change":`Made ${x} changes`} \u2014 it's on the page now</div>
|
|
331
|
+
<div class="items">${b.results.map(G=>`<div class="item">${R(11)}<span class="b">${v(G.label)}<span class="sel">${v(G.target)}</span></span></div>`).join("")}</div>
|
|
332
|
+
<div class="row">
|
|
333
|
+
<button type="button" class="btn sm ghost" data-action="op-undo-run" data-msg="${b.id}" ${K?"":"disabled"}>${p("undo",12)}${b.undone?"Undone":"Undo this"}</button>
|
|
334
|
+
<button type="button" class="btn sm bare" data-action="op-all-changes">${p("history",12)}All changes</button>
|
|
335
|
+
</div>
|
|
336
|
+
<div class="hint">Not right? Just tell Operator what to adjust.</div>
|
|
337
|
+
</div>`}).join(""),y=I?`What should change about the ${I.toLowerCase()}?`:"Describe a change\u2026";return`<div class="panel" role="tabpanel" aria-label="Operator">
|
|
338
|
+
<div class="op-ctx">${s}</div>
|
|
339
|
+
<div class="op-thread" data-op-thread>${h?d:k}</div>
|
|
340
|
+
<form class="op-input" data-operator-form>
|
|
341
|
+
<div class="line">
|
|
342
|
+
<textarea class="field" data-field="operator-prompt" rows="2" maxlength="30000" placeholder="${v(y)}" aria-label="Describe the change for Operator" ${ot?"disabled":""}>${v(nt)}</textarea>
|
|
343
|
+
<button type="submit" class="send" aria-label="Send to Operator" title="Send to Operator" ${ot||!u.variation?"disabled":""}>${p("send",15)}</button>
|
|
344
|
+
</div>
|
|
345
|
+
<div class="note">Operator edits this draft only \u2014 shoppers never see it.</div>
|
|
346
|
+
</form>
|
|
347
|
+
</div>`},er=()=>{let o=`<div class="code-body">
|
|
348
|
+
<label><span class="flabel">CSS on this variation</span>
|
|
349
|
+
<textarea class="field code" data-field="css" rows="9" spellcheck="false" aria-label="Custom CSS for this variation">${v(u.artifacts.customCss)}</textarea>
|
|
350
|
+
<span class="fhint">Scoped to the experiment page. Applies live as you type.</span>
|
|
351
|
+
</label>
|
|
352
|
+
<div class="code-ok">${p("check",12)} CSS changes are fully undoable.</div>
|
|
353
|
+
</div>`,s=`<div class="code-body">
|
|
354
|
+
<label><span class="flabel">JavaScript on this variation</span>
|
|
355
|
+
<textarea class="field code" data-field="js" rows="9" spellcheck="false" aria-label="Custom JavaScript for this variation">${v(u.artifacts.customJs)}</textarea>
|
|
356
|
+
</label>
|
|
357
|
+
<div class="js-warn" role="note">${p("alert",14)}<span>JavaScript changes the live page directly and <strong>can't be undone by the editor</strong>. Undo removes it from the draft; close and relaunch the editor to fully reset the page.</span></div>
|
|
358
|
+
<div style="display:flex;gap:8px">
|
|
359
|
+
<button type="button" class="btn soft" data-action="run-js">${p("play",13)}Run on page</button>
|
|
360
|
+
</div>
|
|
361
|
+
${u.reloadRequired?`<div class="code-ok" style="color:var(--warning)">${p("alert",12,'style="color:var(--warning)"')} JavaScript ran on this page. Relaunch the editor to fully reset it.</div>`:""}
|
|
362
|
+
</div>`;return`<div class="code-panel" role="tabpanel" aria-label="Code">
|
|
363
|
+
<div class="code-head">
|
|
364
|
+
<div class="seg" role="radiogroup" aria-label="Code language">
|
|
365
|
+
<button type="button" role="radio" aria-checked="${gt==="css"}" data-action="code-lang" data-lang="css">${p("braces",13)}CSS</button>
|
|
366
|
+
<button type="button" role="radio" aria-checked="${gt==="js"}" data-action="code-lang" data-lang="js">${p("code",13)}JavaScript</button>
|
|
367
|
+
</div>
|
|
368
|
+
<span class="peer">works without Operator</span>
|
|
369
|
+
</div>
|
|
370
|
+
${gt==="css"?o:s}
|
|
371
|
+
<div class="code-foot">Code and Operator write to the same draft. Operator's changes appear as artifact operations you can inspect under <button type="button" data-action="view-artifact">Changes \u2192 View artifact</button>. Full code authoring also lives in the variation workspace in Apex.</div>
|
|
372
|
+
</div>`},rr=()=>{let o=ht(u),s=o.map((d,k)=>`<div class="chg-row">
|
|
373
|
+
<span class="org" title="${d.origin==="operator"?"Made by Operator":"Custom code"}">${d.origin==="operator"?R(13):p(d.kind==="css"?"braces":"code",13)}</span>
|
|
374
|
+
<div class="meta">
|
|
375
|
+
<div class="l">${v(d.label)}</div>
|
|
376
|
+
<div class="s">${v(d.target)} \xB7 ${d.origin==="operator"?"Operator":"code"}${d.risky?" \xB7 relaunch the editor to fully revert":""}</div>
|
|
377
|
+
</div>
|
|
378
|
+
<button type="button" class="iconbtn xs" data-action="chg-remove" data-kind="${d.kind}" data-index="${d.mutationIndex??k}" aria-label="Remove change: ${v(d.label)}">${p("x",11)}</button>
|
|
379
|
+
</div>`).join(""),h=JSON.stringify({variation:u.variation?.name??null,artifactHash:u.variation?.artifactHash??null,operations:u.artifacts.mutations,customCss:u.artifacts.customCss||null,customJs:u.artifacts.customJs||null},null,2);return`<div class="chg-panel" role="tabpanel" aria-label="Changes">
|
|
380
|
+
<div class="chg-head"><span class="t">${o.length} change${o.length===1?"":"s"} in this draft</span>${te(u)}</div>
|
|
381
|
+
${o.length===0?'<p class="chg-empty">No changes yet. Ask Operator, or add CSS or JavaScript in Code.</p>':`<div class="chg-list">${s}</div>`}
|
|
382
|
+
<div class="chg-art">
|
|
383
|
+
<button type="button" class="toggle" data-action="artifact-toggle" aria-expanded="${W}">${p(W?"chevD":"chevR",12)}View artifact (JSON)</button>
|
|
384
|
+
${W?`<div class="json ee-in" aria-label="Variation artifact JSON">${v(h)}</div>`:""}
|
|
385
|
+
<div class="note">Drafts save automatically. Nothing is shown to shoppers until the experiment is launched from Apex.</div>
|
|
386
|
+
<div class="pill-row">${Jt(!1)}</div>
|
|
387
|
+
</div>
|
|
388
|
+
</div>`},ue=()=>_==="operator"?tr():_==="code"?er():rr(),ir=()=>tt?`<div class="rail-dock">
|
|
389
|
+
${R(16)}
|
|
390
|
+
<button type="button" class="iconbtn" data-action="expand" aria-label="Expand editor panel">${p("collapse",15)}</button>
|
|
391
|
+
<div class="sep"></div>
|
|
392
|
+
<button type="button" class="iconbtn ${u.pickerActive?"active":""}" data-action="rail-inspect" aria-label="Point at an element">${p("pointer",15)}</button>
|
|
393
|
+
<div class="grow"></div>
|
|
394
|
+
<span title="Connection: ${P}"><span class="dot ${P==="connected"?"ok":"err"}"><i></i>${P==="connected"?"":"<b></b>"}</span></span>
|
|
395
|
+
</div>`:`<div class="dock">
|
|
396
|
+
<div class="id-head">
|
|
397
|
+
<div class="id-row">
|
|
398
|
+
${R(18)}
|
|
399
|
+
<div class="id-meta">
|
|
400
|
+
<div class="id-title" title="${v($)}">${v($)}</div>
|
|
401
|
+
<div class="id-sub">On your store \xB7 ${v(S)}</div>
|
|
402
|
+
</div>
|
|
403
|
+
<button type="button" class="iconbtn" data-action="collapse" aria-label="Collapse editor panel">${p("collapse",15)}</button>
|
|
404
|
+
</div>
|
|
405
|
+
<div class="id-chips">
|
|
406
|
+
${le(!1)}
|
|
407
|
+
${Jt(!0)}
|
|
408
|
+
<span class="grow"></span>
|
|
409
|
+
${te(u)}
|
|
410
|
+
</div>
|
|
411
|
+
${P!=="connected"?`<div class="id-conn">${Xe()}</div>`:""}
|
|
412
|
+
</div>
|
|
413
|
+
<div class="view-row">
|
|
414
|
+
${de()}
|
|
415
|
+
${ce()}
|
|
416
|
+
<span class="grow"></span>
|
|
417
|
+
${Ye()}
|
|
418
|
+
</div>
|
|
419
|
+
${pe()}
|
|
420
|
+
${ue()}
|
|
421
|
+
<div class="foot">
|
|
422
|
+
${se()}
|
|
423
|
+
<span class="grow"></span>
|
|
424
|
+
<button type="button" class="btn primary" data-action="done">${p("check",13)}Done</button>
|
|
425
|
+
</div>
|
|
426
|
+
</div>`,nr=()=>{let o=`<div class="bar">
|
|
427
|
+
${R(14)}
|
|
428
|
+
${le(!0)}
|
|
429
|
+
${Jt(!0)}
|
|
430
|
+
<span class="grow"></span>
|
|
431
|
+
${te(u)}
|
|
432
|
+
</div>`;return et?`<div class="sheet">
|
|
433
|
+
<button type="button" class="handle" data-action="sheet-toggle" aria-label="Collapse editor" aria-expanded="true"><i></i></button>
|
|
434
|
+
${o}
|
|
435
|
+
<div class="row2">
|
|
436
|
+
${de()}
|
|
437
|
+
${ce()}
|
|
438
|
+
${se()}
|
|
439
|
+
<span class="grow"></span>
|
|
440
|
+
<button type="button" class="btn primary sm" data-action="done">${p("check",12)}Done</button>
|
|
441
|
+
</div>
|
|
442
|
+
${pe()}
|
|
443
|
+
${ue()}
|
|
444
|
+
</div>`:`<div class="sheet">
|
|
445
|
+
<button type="button" class="handle" data-action="sheet-toggle" aria-label="Expand editor" aria-expanded="false"><i></i></button>
|
|
446
|
+
${o}
|
|
447
|
+
</div>`},or=()=>{let o=u.pickerActive,s=[];return M==="unsupported"&&s.push(`<div class="banner warn ee-in" role="status">${p("alert",14)}<span class="body">That element can't be edited here. Point at an element on the storefront page instead.</span><button type="button" class="btn sm ghost" data-action="banner-dismiss">OK</button></div>`),M==="spanav"&&s.push(`<div class="banner info ee-in" role="status">${p("globe",14)}<span class="body">You navigated to ${v(location.pathname+location.search)}. This variation targets ${v(E||"")}, so changes are paused until you return.</span><button type="button" class="btn sm soft" data-action="spa-back">Back to target page</button><button type="button" class="btn sm ghost" data-action="banner-dismiss">Stay</button></div>`),P==="offline"&&s.push(`<div class="banner error ee-in" role="status">${p("wifiOff",14)}<span class="body">Connection lost. Your edits are kept locally and will save when you're back online.</span></div>`),`${o?`<div class="page-border" aria-hidden="true"></div><div class="select-banner ee-in">${p("pointer",13)}Click an element to talk about it<button type="button" data-action="back-to-browsing">Back to browsing \xB7 Esc</button></div>`:""}
|
|
448
|
+
${s.length?`<div class="banners ${o?"lower":""}">${s.join("")}</div>`:""}
|
|
449
|
+
${J==="original"?`<div class="orig-chip ee-in">${p("eye",13)}Viewing the original \u2014 draft changes hidden<button type="button" data-action="show-variation">Show ${v(u.variation?.name||"variation")}</button></div>`:""}`},ar=()=>{if(u.saveState==="conflict")return`<div class="modal-backdrop"><div class="modal ee-in" role="dialog" aria-modal="true" aria-label="This draft changed somewhere else">
|
|
450
|
+
<div class="m-head"><span class="m-icon warn">${p("alert",15)}</span><div class="m-title">This draft changed somewhere else</div></div>
|
|
451
|
+
<div class="m-body">
|
|
452
|
+
<p>Someone saved a newer version of <strong style="color:var(--text1)">${v(u.variation?.name||"this variation")}</strong> while you were editing \u2014 likely from the Apex dashboard.</p>
|
|
453
|
+
<p>Loading the newer version discards your unsaved edits here. Keeping yours overwrites theirs.</p>
|
|
454
|
+
</div>
|
|
455
|
+
<div class="m-actions"><button type="button" class="btn ghost" data-action="conflict-mine">Keep my version</button><button type="button" class="btn primary" data-action="conflict-theirs">Load newer version</button></div>
|
|
456
|
+
</div></div>`;if(D==="expired"){let o=Nt?`${Math.max(1,Math.round((Date.now()-Nt)/1e3))} seconds ago`:null;return`<div class="modal-backdrop"><div class="modal ee-in" role="dialog" aria-modal="true" aria-label="Editing session ended" style="width:410px">
|
|
457
|
+
<div class="m-head"><span class="m-icon purple">${p("clock",15)}</span><div class="m-title">Editing session ended</div></div>
|
|
458
|
+
<div class="m-body">
|
|
459
|
+
<p>Sessions are time-limited for security. ${o?`Your draft was saved <strong style="color:var(--text1)">${o}</strong> \u2014 nothing was lost.`:"Your saved draft is safe in Apex."}</p>
|
|
460
|
+
<p>Start a new session from the variation in Apex.</p>
|
|
461
|
+
</div>
|
|
462
|
+
<div class="m-actions"><button type="button" class="btn ghost" data-action="expired-close">Close editor</button><button type="button" class="btn primary" data-action="expired-apex">${p("external",13)}Open variation in Apex</button></div>
|
|
463
|
+
</div></div>`}if(D==="stop"){let o=ht(u);return`<div class="modal-backdrop"><div class="modal ee-in" role="dialog" aria-modal="true" aria-label="Done editing?">
|
|
464
|
+
<div class="m-head"><span class="m-icon ok">${p("check",15)}</span><div class="m-title">Done editing?</div></div>
|
|
465
|
+
<div class="m-body">
|
|
466
|
+
<p>${o.length} change${o.length===1?"":"s"} saved to the ${v(u.variation?.name||"variation")} draft. The editor will be removed from the page and the session closed.</p>
|
|
467
|
+
${o.length?`<div style="margin-top:12px;display:grid;gap:5px">${o.slice(0,4).map(s=>`<div style="font-size:12px;color:var(--text3);display:flex;gap:7px;align-items:center">${p("check",11,'style="color:var(--positive)"')} ${v(s.label)}</div>`).join("")}</div>`:""}
|
|
468
|
+
<p style="font-size:12px;color:var(--text3)">Launching the experiment still happens from Apex \u2014 closing here never starts traffic.</p>
|
|
469
|
+
</div>
|
|
470
|
+
<div class="m-actions"><button type="button" class="btn ghost" data-action="modal-keep">Keep editing</button><button type="button" class="btn primary" data-action="modal-save-close">${p("check",13)}Save and close</button></div>
|
|
471
|
+
</div></div>`}return""},sr=()=>{let o=u.variation?3:2,s=!u.variation&&u.saveState==="error",h=Math.max(1,Math.round((Date.parse(g.expiresAt)-Date.now())/6e4)),d=["Starting a secure editing session",`Connecting to ${S}`,`Loading the ${u.variation?.name||"variation"} draft`];return`<div class="box">
|
|
472
|
+
<div class="kicker">${R(22)} Apex</div>
|
|
473
|
+
<div class="sub">On-site editor \xB7 ${v($)}</div>
|
|
474
|
+
<div class="steps" role="status" aria-live="polite">${d.map((k,y)=>{let b=y<o?"done":y===o?"cur":"todo",x=b==="done"?p("check",14,'style="color:var(--positive)"'):b==="cur"?p("refresh",14,'class="spin" style="color:var(--purple300)"'):'<span class="idle">\xB7</span>';return`<div class="step ${b}">${x}${v(k)}</div>`}).join("")}</div>
|
|
475
|
+
<div class="bar"><i style="width:${Math.min(100,o/3*100+12)}%"></i></div>
|
|
476
|
+
${s?`<div class="err">${v(u.saveMessage||"The draft could not be loaded.")}<div style="margin-top:10px"><button type="button" class="btn soft sm" data-action="boot-retry">Try again</button></div></div>`:""}
|
|
477
|
+
<div class="scope">Session is scoped to this experiment and store, and expires after ${h} minutes. Drafts only \u2014 shoppers never see your edits.</div>
|
|
478
|
+
</div>`},m=()=>{u=t.getState(),!B&&u.variation&&(B=!0),f.hidden=B,B||(f.innerHTML=sr());let o=r.activeElement,s=o?.dataset?.field,h=o&&"selectionStart"in o?[o.selectionStart,o.selectionEnd]:null;n.className=`zone${U?" narrow":tt?" rail":""}`,n.innerHTML=B?or():"",l.className=`device${U?" narrow":""}`,i.innerHTML=B?`${U?nr():ir()}${ar()}`:"",r.host.dataset.apexEditorSheetState=U?et?"expanded":"collapsed":"desktop",l.hidden=u.deviceState==="closed",jt.hidden=u.deviceState==="blocked",Ze.hidden=u.deviceState!=="blocked";let d=l.querySelector(".d-title");if(d&&(d.textContent=rt==="tablet"?"Tablet preview \xB7 768 \xD7 1024":"Mobile preview \xB7 390 \xD7 844"),s){let k=i.querySelector(`[data-field="${s}"]`);k?.focus(),k&&h&&"setSelectionRange"in k&&k.setSelectionRange(h[0],h[1])}lr()},lr=()=>{let o=i.querySelector("[data-op-thread]");o&&(o.scrollTop=o.scrollHeight)},cr=t.subscribe(()=>m()),fe=(o,s)=>JSON.stringify(o)===JSON.stringify(s);function he(o){return o.phase!=="done"||o.undone||!o.postArtifacts?!1:[...O].reverse().find(h=>h.role==="op"&&h.phase==="done"&&!h.undone)?.id===o.id&&fe(t.getState().artifacts,o.postArtifacts)}let me=(o,s,h)=>{if(!u.variation||ot)return;let d=w(t.getState().artifacts),k=s?{selector:s,tag:u.selectedSelector===s?u.selectedElement?.tagName.toLowerCase():void 0,textPreview:u.selectedSelector===s&&(u.selectedElement?.textContent??"").replace(/\s+/g," ").trim().slice(0,200)||void 0}:null,y=new AbortController,b={id:++oe,role:"user",text:o,ctxLabel:h},x={id:++oe,role:"op",phase:"working",step:0,steps:[h?`Inspecting the ${h.toLowerCase()}`:"Reading the page","Asking Operator to draft the change","Applying the change to the draft"],prompt:o,ctxSelector:s,ctxLabel:h,preArtifacts:d,postArtifacts:null,results:[],error:null,undone:!1,abort:y};O.push(b,x),at.push({role:"user",content:o}),ot=!0,k&&(F=null,I=null,T.setSelected(null),t.clearSelectedElement()),m();let K=setTimeout(()=>{x.phase==="working"&&(x.step=1,m())},600),G=[`Live merchant page: ${ft(g.targetUrl)}`,s?`The user selected this element as the request context: selector "${s}"${h?` (${h})`:""}. Ground the change on it.`:""].filter(Boolean).join(`
|
|
479
|
+
`),st=Je({apiOrigin:t.apiOrigin,session:g,variationId:u.variation.id,prompt:o,artifacts:d,conversation:at.slice(0,-1).slice(-12),pageContext:G,signal:y.signal,selectedElement:k}).then(async A=>{if(clearTimeout(K),x.phase!=="working"||y.signal.aborted||(x.step=2,m(),y.signal.aborted))return;let yt=t.applyCommandArtifacts(A.artifacts);if(x.postArtifacts=w(t.getState().artifacts),y.signal.aborted){t.restoreArtifacts(d),await t.saveNow();return}at.push({role:"assistant",content:A.explanation}),x.abort=null,await t.saveNow();let we=t.getState().saveState;if(we==="error"||we==="conflict"){x.phase="save-failed",x.abort=null,x.results=ee(d,t.getState().artifacts),x.error=t.getState().saveMessage;return}x.phase="done",x.abort=null,x.postArtifacts=w(t.getState().artifacts),x.results=ee(d,t.getState().artifacts),x.results.length||(x.results=[{label:A.explanation,target:"no page changes"}]),yt.ok||x.results.push({label:"One selector needs review \u2014 check the result on the page.",target:yt.repairHint??"selector audit"})}).catch(A=>{clearTimeout(K),!y.signal.aborted&&(x.phase=x.postArtifacts?"save-failed":"failed",x.abort=null,x.error=A instanceof Error?A.message:"Operator could not build the draft.",x.postArtifacts&&(x.results=ee(d,t.getState().artifacts)))}).finally(()=>{if(y.signal.aborted){let A=O.indexOf(b);A>=0&&O.splice(A,2),at.pop()}vt===st&&(vt=null),ot=!1,m()});vt=st},dr=async o=>{let s=++zt;for(let d of O)d.role==="op"&&d.phase==="working"&&d.abort?.abort();if(await vt,s!==zt||(await t.saveNow(),s!==zt))return;let h=t.getState().saveState;if(h==="error"||h==="conflict"){m();return}F=null,I=null,T.setSelected(null),t.clearSelection(),O.length=0,at.length=0,J="variation",t.toggleArtifacts(!0),await t.selectVariation(o),m()},pr=async o=>{let s=!!(o?.postArtifacts&&fe(t.getState().artifacts,o.postArtifacts));await t.saveNow();let h=t.getState().saveState;o?.phase==="save-failed"&&h!=="error"&&h!=="conflict"&&(o.phase="done",o.error=null,o.postArtifacts=s?w(t.getState().artifacts):null),m()},xt=o=>{let s=Number(o.dataset.msg),h=O.find(d=>d.id===s);return h&&h.role==="op"?h:null},Bt=o=>{if(rt=o,o==="desktop"){t.closeDevicePreview(),m();return}let s=o==="tablet"?{width:768,height:1024}:{width:390,height:844};jt.style.width=`${s.width}px`,jt.style.height=`${s.height}px`,t.openDevicePreview(),m()},Vt=o=>{let s=o.target.closest("[data-action]");if(!s){j&&(j=!1,m());return}switch(s.dataset.action){case"collapse":tt=!0,m();break;case"expand":tt=!1,m();break;case"rail-inspect":tt=!1,T.setActive(!0);break;case"sheet-toggle":et=!et,m();break;case"variation-open":j=!j,m();break;case"variation-pick":{j=!1;let d=s.dataset.variation;d&&d!==u.variation?.id&&dr(d),m();break}case"tab":_=s.dataset.tab??"operator",m();break;case"compare":{let d=s.dataset.view==="original"?"original":"variation";d!==J&&(J=d,t.toggleArtifacts(d==="variation")),m();break}case"show-variation":J="variation",t.toggleArtifacts(!0),m();break;case"device":Bt(s.dataset.device??"desktop");break;case"undo":t.undo();break;case"redo":t.redo();break;case"inspect-toggle":T.setActive(!u.pickerActive);break;case"back-to-browsing":T.setActive(!1);break;case"ctx-replace":T.setActive(!0);break;case"ctx-clear":F=null,I=null,T.setSelected(null),t.clearSelection(),m();break;case"suggestion":nt=s.textContent?.trim()??"",m();break;case"op-stop":xt(s)?.abort?.abort();break;case"op-retry":{let d=xt(s);d&&me(d.prompt,d.ctxSelector,d.ctxLabel);break}case"op-undo-run":{let d=xt(s);d&&he(d)&&(t.restoreArtifacts(d.preArtifacts),d.undone=!0,m());break}case"op-all-changes":_="changes",m();break;case"code-lang":gt=s.dataset.lang==="js"?"js":"css",m();break;case"run-js":t.applyCustomJs();break;case"view-artifact":_="changes",W=!0,m();break;case"artifact-toggle":W=!W,m();break;case"chg-remove":{let d=s.dataset.kind;d==="mutation"?t.removeMutation(Number(s.dataset.index)):d==="css"?t.setCustomCss(""):d==="js"&&t.setCustomJs("");break}case"retry-save":pr(xt(s));break;case"extend-session":ur();break;case"banner-dismiss":M==="spanav"&&(it=!0),M=null,m();break;case"spa-back":M=null,it=!1,location.assign(g.targetUrl);break;case"done":D="stop",m();break;case"modal-keep":D=null,m();break;case"modal-save-close":t.saveNow().then(()=>{let d=t.getState().saveState;if(d!=="error"&&d!=="conflict")return t.exit();m()}).catch(()=>m());break;case"conflict-mine":t.resolveConflict("mine");break;case"conflict-theirs":t.resolveConflict("theirs");break;case"expired-close":t.exit();break;case"expired-apex":window.open(Dt(u.variation?.id??g.initialVariationId),"_blank","noopener");break;case"boot-retry":t.selectVariation(g.initialVariationId);break;default:break}};i.addEventListener("click",Vt),n.addEventListener("click",Vt),f.addEventListener("click",Vt),i.addEventListener("input",o=>{let s=o.target;s.dataset.field==="css"?t.setCustomCss(s.value):s.dataset.field==="js"?t.setCustomJs(s.value):s.dataset.field==="operator-prompt"&&(nt=s.value)}),i.addEventListener("submit",o=>{if(!o.target.closest("[data-operator-form]"))return;o.preventDefault();let h=nt.trim();h&&(nt="",me(h,F,I))}),l.addEventListener("click",o=>{let s=o.target.closest("[data-action]")?.dataset.action;s==="device-close"&&Bt("desktop"),s==="device-copy"&&navigator.clipboard?.writeText(location.href)});let ge=o=>{let s=o.composedPath()[0],h=s instanceof HTMLInputElement||s instanceof HTMLTextAreaElement||s instanceof HTMLSelectElement||s instanceof HTMLElement&&s.isContentEditable;if(o.key==="Escape"){if(D==="stop"){D=null,m();return}if(u.deviceState!=="closed"){o.preventDefault(),Bt("desktop");return}return}if(!h){if(o.key==="s"||o.key==="S"){T.setActive(!u.pickerActive);return}(o.metaKey||o.ctrlKey)&&(o.key==="z"||o.key==="Z")&&(o.preventDefault(),o.shiftKey?t.redo():t.undo())}};window.addEventListener("keydown",ge,!0);let ur=async()=>{try{await t.extendSession()&&(Ut=mt()<=Pt,m())}catch{}},ve={value:u.saveState},fr=t.subscribe(o=>{o.saveState==="saved"&&ve.value!=="saved"&&(Nt=Date.now()),ve.value=o.saveState}),hr=setInterval(()=>{let o=mt();if(o<=0&&D!=="expired"){D="expired",T.setActive(!1),m();return}let s=o<=Pt;if(s!==Ut){Ut=s,m();return}let h=i.querySelector("[data-session-text]");if(h&&(h.textContent=s?`Session ends in ${qe(o)}`:`Session \xB7 ${Math.floor(o/60)} min left`),E&&B){let d=location.pathname+location.search!==E;d&&M!=="spanav"&&!it&&M===null?(M="spanav",m()):!d&&(M==="spanav"||it)&&(M==="spanav"&&(M=null),it=!1,m())}},1e3),be=()=>{P="connected",m(),t.saveNow()},xe=()=>{P="offline",m()};window.addEventListener("online",be),window.addEventListener("offline",xe);let ye=()=>{U=bt?.matches??!1,m()};return bt?.addEventListener?.("change",ye),m(),{destroy(){for(let o of O)o.role==="op"&&o.phase==="working"&&o.abort?.abort();cr(),fr(),clearInterval(hr),T.destroy(),ae.close(!1),window.removeEventListener("keydown",ge,!0),window.removeEventListener("online",be),window.removeEventListener("offline",xe),bt?.removeEventListener?.("change",ye),e.remove(),i.remove(),n.remove(),a.remove(),c.remove(),l.remove(),f.remove()}}}var re="apex-editor-host",di=1e4,ne=null,q=null,ie=null,Q=null;function Ke(){Q?.stop(),ie?.destroy(),q?.destroy(),ie=null,Q=null,q=null,ne=null,document.getElementById(re)?.remove()}function C(r){return typeof r=="string"&&r.trim()?r.trim():null}function pi(r,t){if(!r||typeof r!="object")return null;let e=r,i={sid:C(e.sid),bearer:C(e.bearer),expiresAt:C(e.expiresAt),shopId:C(e.shopId),experimentId:C(e.experimentId),initialVariationId:C(e.initialVariationId),targetUrl:C(e.targetUrl),targetOrigin:C(e.targetOrigin)};if(i.sid!==t||!i.bearer||!i.expiresAt||!i.shopId||!i.experimentId||!i.initialVariationId||!i.targetUrl||!i.targetOrigin||!Number.isFinite(Date.parse(i.expiresAt))||Date.parse(i.expiresAt)<=Date.now())return null;let n=[];if(Array.isArray(e.variations))for(let a of e.variations){if(!a||typeof a!="object")continue;let c=a,l=C(c.id);l&&n.push({id:l,name:C(c.name),slug:C(c.slug)})}return{sid:t,bearer:i.bearer,expiresAt:i.expiresAt,shopId:i.shopId,experimentId:i.experimentId,experimentName:C(e.experimentName),initialVariationId:i.initialVariationId,targetUrl:i.targetUrl,targetOrigin:i.targetOrigin,variations:n}}function ui(r){document.getElementById(re)?.remove();let t=document.createElement("div");t.id=re,t.setAttribute("data-apex-editor-state","connected");let e=t.attachShadow({mode:"closed"});(document.body||document.documentElement).appendChild(t),ie=We(e,r)}async function fi(r){let t=new AbortController,e=setTimeout(()=>t.abort(),di),i=!1;try{let n=new URL("/api/editor-sessions/exchange",r.apiOrigin);n.searchParams.set("sid",r.sid);let a=await fetch(n.toString(),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:r.token}),cache:"no-store",credentials:"omit",referrerPolicy:"no-referrer",signal:t.signal});if(!a.ok)return!1;let c=await a.json().catch(()=>null);if(c?.ok!==!0)return!1;let l=pi(c.session,r.sid);if(!l||typeof location<"u"&&l.targetOrigin!==location.origin)return!1;ne=l,i=!0;let f=new X(r.apiOrigin,l);q=new Rt(l,r.apiOrigin,f),ui(q),await q.initialize(),Q=new St(f,new Et(q)),q.addCleanup(()=>{Q?.stop(),Q=null}),Q.start();try{window.opener?.postMessage({type:"apex:editor-connected",sid:l.sid,experimentId:l.experimentId,variationId:l.initialVariationId},r.apiOrigin)}catch{}return!0}catch{return i&&Ke(),!1}finally{clearTimeout(e)}}function hi(){return ne}var mi={reset:Ke};return yr(gi);})();
|
|
480
|
+
//# sourceMappingURL=editor.js.map
|