@depup/base44__vite-plugin 1.0.4-depup.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/README.md +34 -0
- package/changes.json +22 -0
- package/compat/agents.cjs +13 -0
- package/compat/base44Client.cjs +6 -0
- package/compat/entities.cjs +25 -0
- package/compat/functions.cjs +9 -0
- package/compat/integrations.cjs +9 -0
- package/dist/ErrorOverlay.d.ts +12 -0
- package/dist/ErrorOverlay.d.ts.map +1 -0
- package/dist/ErrorOverlay.js +51 -0
- package/dist/ErrorOverlay.js.map +1 -0
- package/dist/bridge.d.ts +8 -0
- package/dist/bridge.d.ts.map +1 -0
- package/dist/bridge.js +8 -0
- package/dist/bridge.js.map +1 -0
- package/dist/capabilities/inline-edit/controller.d.ts +3 -0
- package/dist/capabilities/inline-edit/controller.d.ts.map +1 -0
- package/dist/capabilities/inline-edit/controller.js +203 -0
- package/dist/capabilities/inline-edit/controller.js.map +1 -0
- package/dist/capabilities/inline-edit/dom-utils.d.ts +7 -0
- package/dist/capabilities/inline-edit/dom-utils.d.ts.map +1 -0
- package/dist/capabilities/inline-edit/dom-utils.js +59 -0
- package/dist/capabilities/inline-edit/dom-utils.js.map +1 -0
- package/dist/capabilities/inline-edit/index.d.ts +3 -0
- package/dist/capabilities/inline-edit/index.d.ts.map +1 -0
- package/dist/capabilities/inline-edit/index.js +2 -0
- package/dist/capabilities/inline-edit/index.js.map +1 -0
- package/dist/capabilities/inline-edit/types.d.ts +29 -0
- package/dist/capabilities/inline-edit/types.d.ts.map +1 -0
- package/dist/capabilities/inline-edit/types.js +2 -0
- package/dist/capabilities/inline-edit/types.js.map +1 -0
- package/dist/consts.d.ts +11 -0
- package/dist/consts.d.ts.map +1 -0
- package/dist/consts.js +11 -0
- package/dist/consts.js.map +1 -0
- package/dist/error-overlay-plugin.d.ts +3 -0
- package/dist/error-overlay-plugin.d.ts.map +1 -0
- package/dist/error-overlay-plugin.js +15 -0
- package/dist/error-overlay-plugin.js.map +1 -0
- package/dist/html-injections-plugin.d.ts +8 -0
- package/dist/html-injections-plugin.d.ts.map +1 -0
- package/dist/html-injections-plugin.js +132 -0
- package/dist/html-injections-plugin.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +158 -0
- package/dist/index.js.map +1 -0
- package/dist/injections/layer-dropdown/consts.d.ts +20 -0
- package/dist/injections/layer-dropdown/consts.d.ts.map +1 -0
- package/dist/injections/layer-dropdown/consts.js +41 -0
- package/dist/injections/layer-dropdown/consts.js.map +1 -0
- package/dist/injections/layer-dropdown/controller.d.ts +4 -0
- package/dist/injections/layer-dropdown/controller.d.ts.map +1 -0
- package/dist/injections/layer-dropdown/controller.js +88 -0
- package/dist/injections/layer-dropdown/controller.js.map +1 -0
- package/dist/injections/layer-dropdown/dropdown-ui.d.ts +13 -0
- package/dist/injections/layer-dropdown/dropdown-ui.d.ts.map +1 -0
- package/dist/injections/layer-dropdown/dropdown-ui.js +186 -0
- package/dist/injections/layer-dropdown/dropdown-ui.js.map +1 -0
- package/dist/injections/layer-dropdown/types.d.ts +26 -0
- package/dist/injections/layer-dropdown/types.d.ts.map +1 -0
- package/dist/injections/layer-dropdown/types.js +3 -0
- package/dist/injections/layer-dropdown/types.js.map +1 -0
- package/dist/injections/layer-dropdown/utils.d.ts +25 -0
- package/dist/injections/layer-dropdown/utils.d.ts.map +1 -0
- package/dist/injections/layer-dropdown/utils.js +143 -0
- package/dist/injections/layer-dropdown/utils.js.map +1 -0
- package/dist/injections/navigation-notifier.d.ts +2 -0
- package/dist/injections/navigation-notifier.d.ts.map +1 -0
- package/dist/injections/navigation-notifier.js +34 -0
- package/dist/injections/navigation-notifier.js.map +1 -0
- package/dist/injections/sandbox-hmr-notifier.d.ts +2 -0
- package/dist/injections/sandbox-hmr-notifier.d.ts.map +1 -0
- package/dist/injections/sandbox-hmr-notifier.js +10 -0
- package/dist/injections/sandbox-hmr-notifier.js.map +1 -0
- package/dist/injections/sandbox-mount-observer.d.ts +2 -0
- package/dist/injections/sandbox-mount-observer.d.ts.map +1 -0
- package/dist/injections/sandbox-mount-observer.js +18 -0
- package/dist/injections/sandbox-mount-observer.js.map +1 -0
- package/dist/injections/unhandled-errors-handlers.d.ts +2 -0
- package/dist/injections/unhandled-errors-handlers.d.ts.map +1 -0
- package/dist/injections/unhandled-errors-handlers.js +93 -0
- package/dist/injections/unhandled-errors-handlers.js.map +1 -0
- package/dist/injections/utils.d.ts +65 -0
- package/dist/injections/utils.d.ts.map +1 -0
- package/dist/injections/utils.js +186 -0
- package/dist/injections/utils.js.map +1 -0
- package/dist/injections/visual-edit-agent.d.ts +2 -0
- package/dist/injections/visual-edit-agent.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent.js +583 -0
- package/dist/injections/visual-edit-agent.js.map +1 -0
- package/dist/jsx-processor.d.ts +17 -0
- package/dist/jsx-processor.d.ts.map +1 -0
- package/dist/jsx-processor.js +129 -0
- package/dist/jsx-processor.js.map +1 -0
- package/dist/jsx-utils.d.ts +16 -0
- package/dist/jsx-utils.d.ts.map +1 -0
- package/dist/jsx-utils.js +98 -0
- package/dist/jsx-utils.js.map +1 -0
- package/dist/processors/collection-id-processor.d.ts +20 -0
- package/dist/processors/collection-id-processor.d.ts.map +1 -0
- package/dist/processors/collection-id-processor.js +182 -0
- package/dist/processors/collection-id-processor.js.map +1 -0
- package/dist/processors/collection-item-field-processor.d.ts +39 -0
- package/dist/processors/collection-item-field-processor.d.ts.map +1 -0
- package/dist/processors/collection-item-field-processor.js +289 -0
- package/dist/processors/collection-item-field-processor.js.map +1 -0
- package/dist/processors/collection-item-id-processor.d.ts +12 -0
- package/dist/processors/collection-item-id-processor.d.ts.map +1 -0
- package/dist/processors/collection-item-id-processor.js +50 -0
- package/dist/processors/collection-item-id-processor.js.map +1 -0
- package/dist/processors/static-array-processor.d.ts +28 -0
- package/dist/processors/static-array-processor.d.ts.map +1 -0
- package/dist/processors/static-array-processor.js +173 -0
- package/dist/processors/static-array-processor.js.map +1 -0
- package/dist/processors/utils/collection-tracing-utils.d.ts +36 -0
- package/dist/processors/utils/collection-tracing-utils.d.ts.map +1 -0
- package/dist/processors/utils/collection-tracing-utils.js +390 -0
- package/dist/processors/utils/collection-tracing-utils.js.map +1 -0
- package/dist/processors/utils/shared-utils.d.ts +96 -0
- package/dist/processors/utils/shared-utils.d.ts.map +1 -0
- package/dist/processors/utils/shared-utils.js +600 -0
- package/dist/processors/utils/shared-utils.js.map +1 -0
- package/dist/statics/index.mjs +16 -0
- package/dist/statics/index.mjs.map +1 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +22 -0
- package/dist/utils.js.map +1 -0
- package/dist/visual-edit-plugin.d.ts +3 -0
- package/dist/visual-edit-plugin.d.ts.map +1 -0
- package/dist/visual-edit-plugin.js +100 -0
- package/dist/visual-edit-plugin.js.map +1 -0
- package/package.json +75 -0
- package/src/ErrorOverlay.ts +71 -0
- package/src/bridge.ts +8 -0
- package/src/capabilities/inline-edit/controller.ts +254 -0
- package/src/capabilities/inline-edit/dom-utils.ts +58 -0
- package/src/capabilities/inline-edit/index.ts +2 -0
- package/src/capabilities/inline-edit/types.ts +35 -0
- package/src/consts.ts +11 -0
- package/src/error-overlay-plugin.ts +19 -0
- package/src/html-injections-plugin.ts +166 -0
- package/src/index.ts +225 -0
- package/src/injections/layer-dropdown/LAYERS.md +258 -0
- package/src/injections/layer-dropdown/consts.ts +51 -0
- package/src/injections/layer-dropdown/controller.ts +109 -0
- package/src/injections/layer-dropdown/dropdown-ui.ts +242 -0
- package/src/injections/layer-dropdown/types.ts +30 -0
- package/src/injections/layer-dropdown/utils.ts +175 -0
- package/src/injections/navigation-notifier.ts +43 -0
- package/src/injections/sandbox-hmr-notifier.ts +8 -0
- package/src/injections/sandbox-mount-observer.ts +25 -0
- package/src/injections/unhandled-errors-handlers.ts +114 -0
- package/src/injections/utils.ts +208 -0
- package/src/injections/visual-edit-agent.ts +706 -0
- package/src/jsx-processor.ts +169 -0
- package/src/jsx-utils.ts +131 -0
- package/src/processors/collection-id-processor.ts +261 -0
- package/src/processors/collection-item-field-processor.ts +439 -0
- package/src/processors/collection-item-id-processor.ts +69 -0
- package/src/processors/static-array-processor.ts +260 -0
- package/src/processors/utils/collection-tracing-utils.ts +507 -0
- package/src/processors/utils/shared-utils.ts +785 -0
- package/src/utils.ts +27 -0
- package/src/visual-edit-plugin.md +358 -0
- package/src/visual-edit-plugin.ts +110 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
function ie(e,n){let o=n.top<27,s=n.height>=54,a=n.width>=window.innerWidth-4,c=a?"8px":"-2px",d=a?"8px":"4px";o&&s?(e.style.top="2px",e.style.left=d):o?(e.style.top=`${n.height+2}px`,e.style.left=c):(e.style.top="-27px",e.style.left=c)}function G(e){let n=e;return!!(n.dataset?.sourceLocation||n.dataset?.visualSelectorId)}function w(e){let n=e;return n.dataset?.sourceLocation||n.dataset?.visualSelectorId||null}var X=["src"],T="data-vite-plugin-element";function S(e){if(!e)return[];let n=Array.from(document.querySelectorAll(`[data-source-location="${e}"]`));return n.length>0?n:Array.from(document.querySelectorAll(`[data-visual-selector-id="${e}"]`))}function le(e,n){e.forEach(o=>{o.setAttribute("class",n)})}function se(e,n,o){X.includes(n)&&e.forEach(s=>{s.setAttribute(n,o)})}function ae(e,n){let o={};for(let s of n){let a=e.getAttribute(s);a!==null&&(o[s]=a)}return o}function de(){if(document.getElementById("freeze-animations"))return;document.documentElement.setAttribute("data-visual-edit-active","");let e=document.createElement("style");e.id="freeze-animations",e.textContent=`
|
|
2
|
+
[data-visual-edit-active] *:not([${T}]):not([${T}] *),
|
|
3
|
+
[data-visual-edit-active] *:not([${T}]):not([${T}] *)::before,
|
|
4
|
+
[data-visual-edit-active] *:not([${T}]):not([${T}] *)::after {
|
|
5
|
+
animation-play-state: paused !important;
|
|
6
|
+
transition: none !important;
|
|
7
|
+
}
|
|
8
|
+
`;let n=document.createElement("style");n.id="freeze-pointer-events",n.textContent=`
|
|
9
|
+
[data-visual-edit-active] * { pointer-events: none !important; }
|
|
10
|
+
[${T}], [${T}] * { pointer-events: auto !important; }
|
|
11
|
+
`;let o=document.head||document.documentElement;o.appendChild(e),o.appendChild(n),document.getAnimations().forEach(s=>{let a=s.effect?.target;if(!(a instanceof Element&&a.closest(`[${T}]`)))try{s.finish()}catch{s.pause()}})}function ce(){let e=document.getElementById("freeze-animations");e&&(e.remove(),document.getElementById("freeze-pointer-events")?.remove(),document.documentElement.removeAttribute("data-visual-edit-active"),document.getAnimations().forEach(n=>{if(n.playState==="paused")try{n.play()}catch{}}))}function Y(e,n){let o=document.getElementById("freeze-pointer-events");o&&(o.disabled=!0);let s=document.elementFromPoint(e,n);return o&&(o.disabled=!1),s?.closest("[data-source-location], [data-visual-selector-id]")??null}function ue(e,n,o){let s=Y(e,n);if(!s)return null;let a=w(s);return a===o?null:a}var fe={position:"absolute",backgroundColor:"#ffffff",border:"1px solid #e2e8f0",borderRadius:"6px",boxShadow:"0 4px 12px rgba(0, 0, 0, 0.15)",fontSize:"12px",minWidth:"120px",maxHeight:"200px",overflowY:"auto",zIndex:"10001",padding:"4px 0",pointerEvents:"auto"},me={padding:"4px 12px",cursor:"pointer",color:"#334155",backgroundColor:"transparent",whiteSpace:"nowrap",lineHeight:"1.5",fontWeight:"400"},P="#526cff",pe="#DBEAFE",Ee="600",z="#f1f5f9",ge=10,q='<svg width="12" height="12" viewBox="0 0 24 24" style="vertical-align:middle;margin-left:4px"><path d="M6 9l6 6 6-6" stroke="currentColor" stroke-width="2" fill="none"/></svg>',ve='<svg width="12" height="12" viewBox="0 0 24 24" style="vertical-align:middle;margin-left:4px"><path d="M18 15l-6-6-6 6" stroke="currentColor" stroke-width="2" fill="none"/></svg>',O="data-chevron",he=12,N="data-layer-dropdown",ye=2,Le=2;function U(e,n){for(let o of Object.keys(n))e.style.setProperty(o.replace(/[A-Z]/g,s=>`-${s.toLowerCase()}`),n[o])}function Ie(e){return e.tagName}function j(e,n){let o={element:e,tagName:e.tagName.toLowerCase(),selectorId:w(e)};return n!==void 0&&(o.depth=n),o}function Te(e,n,o){let s=[];function a(c,d){if(!(d>n))for(let u=0;u<c.children.length;u++){let y=c.children[u];if(G(y)){let g={element:y,tagName:y.tagName.toLowerCase(),selectorId:w(y)};o!==void 0&&(g.depth=o+d-1),s.push(g),a(y,d+1)}else a(y,d)}}return a(e,1),s}function Fe(e){let n=[],o=e.parentElement;for(;o&&o!==document.documentElement&&o!==document.body&&n.length<ye;)G(o)&&n.push(j(o)),o=o.parentElement;return n.reverse(),n}function Ge(e,n){return n.forEach((o,s)=>{e.push({...o,depth:s})}),n.length}function be(e,n,o){e.push(j(n,o));let s=Te(n,Le,o+1);e.push(...s)}function Xe(e){return e.at(-1)?.element??null}function Ye(e,n){let o=Te(e,1);return o.some(s=>s.element===n)||o.push(j(n)),o}function ze(e,n,o,s){let a=w(o),c=new Set;for(let d of n)if(d.element===o)be(e,o,s),a&&c.add(a);else{let u=d.selectorId;if(u!=null){if(u===a||c.has(u))continue;c.add(u)}e.push({...d,depth:s})}}function we(e){let n=Fe(e),o=[],s=Ge(o,n),a=Xe(n);if(a){let c=Ye(a,e);ze(o,c,e,s)}else be(o,e,s);return o}var H=null,K=null,_=null,k=null,R=null;function qe(e,n,{onSelect:o,onHover:s,onHoverEnd:a}){let c=document.createElement("div");c.textContent=Ie(e),U(c,me);let d=e.depth??0;return d>0&&(c.style.paddingLeft=`${he+d*ge}px`),n&&(c.style.color=P,c.style.backgroundColor=pe,c.style.fontWeight=Ee),c.addEventListener("mouseenter",()=>{n||(c.style.backgroundColor=z),s&&s(e)}),c.addEventListener("mouseleave",()=>{n||(c.style.backgroundColor="transparent"),a&&a()}),c.addEventListener("click",u=>{u.stopPropagation(),u.preventDefault(),o(e)}),c}function Ue(e,n,o){let s=document.createElement("div");return s.setAttribute(N,"true"),s.setAttribute(T,"true"),U(s,fe),e.forEach(a=>{let c=a.element===n;s.appendChild(qe(a,c,o))}),s}function Ce(e){if(e.querySelector(`[${O}]`))return;let n=document.createElement("span");n.setAttribute(O,"true"),n.style.display="inline-flex",n.innerHTML=q,e.appendChild(n),e.style.display="inline-flex",e.style.alignItems="center",e.style.cursor="pointer",e.style.userSelect="none",e.style.whiteSpace="nowrap",e.style.pointerEvents="auto",e.setAttribute(N,"true"),e.setAttribute(T,"true")}function je(e,n,o,{onSelect:s,onHover:a,onHoverEnd:c}){let d=Array.from(e.children),u=n.findIndex(g=>g.element===o),y=g=>{if(u>=0&&u<d.length){let v=d[u];v.style.color!==P&&(v.style.backgroundColor="transparent")}if(u=g,u>=0&&u<d.length){let v=d[u];v.style.color!==P&&(v.style.backgroundColor=z),v.scrollIntoView({block:"nearest"}),a&&u>=0&&u<n.length&&a(n[u])}};R=g=>{g.key==="ArrowDown"?(g.preventDefault(),g.stopPropagation(),y(u<d.length-1?u+1:0)):g.key==="ArrowUp"?(g.preventDefault(),g.stopPropagation(),y(u>0?u-1:d.length-1)):g.key==="Enter"&&u>=0&&u<n.length&&(g.preventDefault(),g.stopPropagation(),c&&c(),s(n[u]),x())},document.addEventListener("keydown",R,!0)}function Ke(e,n){let o=!0;_=s=>{if(o){o=!1;return}let a=s.target;!e.contains(a)&&a!==n&&x()},document.addEventListener("mousedown",_,!0)}function Se(e,n,o,s){x();let a=Ue(n,o,{...s,onSelect:u=>{s.onHoverEnd&&s.onHoverEnd(),s.onSelect(u),x()}}),c=e.parentElement;if(!c)return;a.style.top=`${e.offsetTop+e.offsetHeight+2}px`,a.style.left=`${e.offsetLeft}px`,c.appendChild(a),H=a,K=e;let d=e.querySelector(`[${O}]`);d&&(d.innerHTML=ve),k=s.onHoverEnd??null,je(a,n,o,s),Ke(a,e)}function x(){let e=K?.querySelector(`[${O}]`);e&&(e.innerHTML=q),K=null,k&&(k(),k=null),H&&H.parentNode&&H.remove(),H=null,_&&(document.removeEventListener("mousedown",_,!0),_=null),R&&(document.removeEventListener("keydown",R,!0),R=null)}function xe(){return H!==null}function Me(e){let n=null,o=null,s=null,a=()=>{n&&n.parentNode&&n.remove(),n=null},c=L=>{a(),w(L.element)!==e.getSelectedElementId()&&(n=e.createPreviewOverlay(L.element))},d=L=>{a(),x(),o&&(document.removeEventListener("keydown",o,!0),o=null),s=null;let i=e.selectElement(L.element);g(i,L.element)},u=()=>{o&&(document.removeEventListener("keydown",o,!0),o=null),s&&(d(s),s=null)},y=(L,i,m,I,C)=>{L.stopPropagation(),L.preventDefault(),xe()?(x(),u()):(s={element:m,tagName:m.tagName.toLowerCase(),selectorId:C},e.onDeselect(),o=h=>{h.key==="Escape"&&(h.stopPropagation(),x(),u())},document.addEventListener("keydown",o,!0),Se(i,I,m,{onSelect:d,onHover:c,onHoverEnd:a}))},g=(L,i)=>{if(!L)return;let m=L.querySelector("div");if(!m)return;let I=we(i);if(I.length<=1)return;let C=w(i);Ce(m),m.addEventListener("click",h=>{y(h,m,i,I,C)})};return{attachToOverlay:g,cleanup:()=>{a(),x()}}}var Z="visual-edit-focus-styles",Ze=["div","p","h1","h2","h3","h4","h5","h6","span","li","td","a","button","label"],J=e=>!!e.dataset.arrField,Je=e=>!(!Ze.includes(e.tagName.toLowerCase())||!e.textContent?.trim()||e.querySelector("img, video, canvas, svg")||e.children?.length>0),De=()=>{if(document.getElementById(Z))return;let e=document.createElement("style");e.id=Z,e.textContent=`
|
|
12
|
+
[data-selected="true"][contenteditable="true"]:focus {
|
|
13
|
+
outline: none !important;
|
|
14
|
+
}
|
|
15
|
+
`,document.head.appendChild(e)},Ae=()=>{document.getElementById(Z)?.remove()},He=e=>{let n=document.createRange();n.selectNodeContents(e);let o=window.getSelection();o?.removeAllRanges(),o?.addRange(n)},Qe=e=>!(e instanceof HTMLElement)||!Je(e)?!1:J(e)?!0:e.dataset.dynamicContent!=="true",Q=e=>!(e instanceof HTMLElement)||e.dataset.selected!=="true"?!1:Qe(e);var et=500;function ee(e){let n=null,o=null,s=!1,a=new WeakMap,c=()=>{let i=e.getSelectedElementId();if(!i)return;let m=e.findElementsById(i);e.getSelectedOverlays().forEach((C,h)=>{h<m.length&&m[h]&&e.positionOverlay(C,m[h])})},d=i=>{let m=i.dataset.originalTextContent,I=i.textContent,C=i,h=i.getBoundingClientRect(),M={type:"inline-edit",elementInfo:{tagName:i.tagName,classes:C.className?.baseVal||i.className||"",visualSelectorId:e.getSelectedElementId(),content:I,dataSourceLocation:i.dataset.sourceLocation,isDynamicContent:i.dataset.dynamicContent==="true",linenumber:i.dataset.linenumber,filename:i.dataset.filename,position:{top:h.top,left:h.left,right:h.right,bottom:h.bottom,width:h.width,height:h.height,centerX:h.left+h.width/2,centerY:h.top+h.height/2}},originalContent:m,newContent:I};J(i)&&(M.arrIndex=i.dataset.arrIndex,M.arrVariableName=i.dataset.arrVariableName,M.arrField=i.dataset.arrField),window.parent.postMessage(M,"*"),i.dataset.originalTextContent=I||""},u=i=>{o&&clearTimeout(o),o=setTimeout(()=>d(i),et)},y=i=>{c(),u(i)},g=function(){y(this)},v=i=>{De(),i.dataset.originalTextContent=i.textContent||"",i.dataset.originalCursor=i.style.cursor,i.contentEditable="true",i.setAttribute(T,"true");let m=new AbortController;a.set(i,m),i.addEventListener("input",g,{signal:m.signal}),i.style.cursor="text",He(i),setTimeout(()=>{i.isConnected&&i.focus()},0)},L=i=>{let m=a.get(i);m&&(m.abort(),a.delete(i)),i.isConnected&&(Ae(),i.contentEditable="false",i.removeAttribute(T),delete i.dataset.originalTextContent,i.dataset.originalCursor!==void 0&&(i.style.cursor=i.dataset.originalCursor,delete i.dataset.originalCursor))};return{get enabled(){return s},set enabled(i){s=i},isEditing(){return n!==null},getCurrentElement(){return n},canEdit(i){return Q(i)},startEditing(i){n=i,e.getSelectedOverlays().forEach(m=>{m.style.display="none"}),v(i),window.parent.postMessage({type:"content-editing-started",visualSelectorId:e.getSelectedElementId()},"*")},stopEditing(){if(!n)return;o&&(clearTimeout(o),o=null),L(n),e.getSelectedOverlays().forEach(m=>{m.style.display=""}),c(),window.parent.postMessage({type:"content-editing-ended",visualSelectorId:e.getSelectedElementId()},"*"),n=null},markElementsSelected(i){i.forEach(m=>{m instanceof HTMLElement&&(m.dataset.selected="true")})},clearSelectedMarks(i){i&&e.findElementsById(i).forEach(m=>{m instanceof HTMLElement&&delete m.dataset.selected})},handleToggleMessage(i){if(!s)return;let m=e.findElementsById(i.dataSourceLocation);if(m.length===0||!(m[0]instanceof HTMLElement))return;let I=m[0];if(i.inlineEditingMode){if(!Q(I))return;e.getSelectedElementId()!==i.dataSourceLocation&&(this.stopEditing(),e.clearSelection(),this.markElementsSelected(m),e.createSelectionOverlays(m,i.dataSourceLocation)),this.startEditing(I)}else n===I&&this.stopEditing()},cleanup(){this.stopEditing()}}}var B=50;function tt(){let e=!1,n=!1,o=!1,s=[],a=[],c=[],d=null,u=null,y=(r=!1)=>{let t=document.createElement("div");return t.style.position="absolute",t.style.pointerEvents="none",t.style.transition="all 0.1s ease-in-out",t.style.zIndex="9999",r?t.style.border="2px solid #2563EB":(t.style.border="2px solid #95a5fc",t.style.backgroundColor="rgba(99, 102, 241, 0.05)"),t},g=(r,t,l=!1)=>{if(!t||!e)return;t.offsetWidth;let p=t.getBoundingClientRect();r.style.top=`${p.top+window.scrollY}px`,r.style.left=`${p.left+window.scrollX}px`,r.style.width=`${p.width}px`,r.style.height=`${p.height}px`;let E=r.querySelector("div");E||(E=document.createElement("div"),E.textContent=t.tagName.toLowerCase(),E.style.position="absolute",E.style.left="-2px",E.style.padding="2px 8px",E.style.fontSize="11px",E.style.fontWeight=l?"500":"400",E.style.color=l?"#ffffff":"#526cff",E.style.backgroundColor=l?"#2563EB":"#DBEAFE",E.style.borderRadius="3px",E.style.minWidth="24px",E.style.textAlign="center",r.appendChild(E)),ie(E,p)},v=ee({findElementsById:S,getSelectedElementId:()=>d,getSelectedOverlays:()=>a,positionOverlay:g,clearSelection:()=>{v.clearSelectedMarks(d),m(),d=null,u=null},createSelectionOverlays:(r,t)=>{r.forEach(l=>{let f=y(!0);document.body.appendChild(f),a.push(f),g(f,l,!0)}),d=t}}),L=()=>{v.clearSelectedMarks(d),m(),d=null,u=null},i=()=>{s.forEach(r=>{r&&r.parentNode&&r.remove()}),s=[],c=[]},m=()=>{a.forEach(r=>{r&&r.parentNode&&r.remove()}),a=[]},I=["p","h1","h2","h3","h4","h5","h6","span","a","label"],C=r=>{let t=r,l=r.getBoundingClientRect(),f=r,p=I.includes(r.tagName?.toLowerCase()),E=t.closest("[data-arr-variable-name]"),b=E?.dataset?.arrVariableName||null,A=E?.dataset?.arrIndex,Ve=A!=null?parseInt(A,10):null,$e=t.dataset?.arrField||null;window.parent.postMessage({type:"element-selected",tagName:r.tagName,classes:f.className?.baseVal||r.className||"",visualSelectorId:w(r),content:p?t.innerText:void 0,dataSourceLocation:t.dataset.sourceLocation,isDynamicContent:t.dataset.dynamicContent==="true",linenumber:t.dataset.linenumber,filename:t.dataset.filename,position:{top:l.top,left:l.left,right:l.right,bottom:l.bottom,width:l.width,height:l.height,centerX:l.left+l.width/2,centerY:l.top+l.height/2},attributes:ae(r,X),isTextElement:p,staticArrayName:b,staticArrayIndex:Ve,staticArrayField:$e},"*")},h=r=>{let t=w(r);return m(),S(t||null).forEach(f=>{let p=y(!0);document.body.appendChild(p),a.push(p),g(p,f,!0)}),d=t||null,u=r,i(),C(r),a[0]},M=()=>{d=null,window.parent.postMessage({type:"unselect-element"},"*")},W=null,D=null,V=()=>{i(),W=null},Oe=r=>{let t=S(r);i(),t.forEach(l=>{let f=y(!1);document.body.appendChild(f),s.push(f),g(f,l)}),c=t,W=r},te=r=>{!e||n||v.isEditing()||D===null&&(D=requestAnimationFrame(()=>{if(D=null,o){V();return}let t=ue(r.clientX,r.clientY,d);if(!t){V();return}W!==t&&Oe(t)}))},$=()=>{D!==null&&(cancelAnimationFrame(D),D=null),V()},ne=r=>{if(!e)return;let t=r.target;if(t.closest(`[${N}]`)||v.enabled&&t instanceof HTMLElement&&t.contentEditable==="true")return;if(v.isEditing()){r.preventDefault(),r.stopPropagation(),r.stopImmediatePropagation(),v.stopEditing();return}if(o){r.preventDefault(),r.stopPropagation(),r.stopImmediatePropagation(),window.parent.postMessage({type:"close-dropdowns"},"*");return}r.preventDefault(),r.stopPropagation(),r.stopImmediatePropagation();let l=Y(r.clientX,r.clientY);if(!l)return;let f=l,p=w(l);if(d===p&&f.dataset.selected==="true"&&v.enabled&&v.canEdit(f)){v.startEditing(f);return}v.stopEditing(),v.enabled&&v.markElementsSelected(S(p));let b=h(l);oe.attachToOverlay(b,l)},Ne=()=>{v.stopEditing(),L()},_e=(r,t)=>{let l=S(r);l.length!==0&&(le(l,t),setTimeout(()=>{d===r&&a.forEach((f,p)=>{p<l.length&&g(f,l[p])}),c.length>0&&c[0]?.dataset?.visualSelectorId===r&&s.forEach((E,b)=>{b<c.length&&g(E,c[b])})},B))},Re=(r,t,l)=>{let f=S(r);f.length!==0&&(se(f,t,l),setTimeout(()=>{d===r&&a.forEach((p,E)=>{E<f.length&&g(p,f[E])})},B))},Pe=(r,t,l)=>{let f=S(r);f.length!==0&&(l!=null&&(f=f.filter(p=>p.dataset.arrIndex===String(l))),f.forEach(p=>{p.innerText=t}),setTimeout(()=>{d===r&&a.forEach((p,E)=>{E<f.length&&g(p,f[E])})},B))},oe=Me({createPreviewOverlay:r=>{let t=y(!1);return t.style.zIndex="9998",document.body.appendChild(t),g(t,r),t},getSelectedElementId:()=>d,selectElement:h,onDeselect:M}),ke=r=>{e=r,r?(document.body.style.cursor="crosshair",de(),document.addEventListener("mousemove",te),document.addEventListener("mouseleave",$),document.addEventListener("click",ne,!0)):(ce(),v.stopEditing(),L(),oe.cleanup(),$(),document.body.style.cursor="default",document.removeEventListener("mousemove",te),document.removeEventListener("mouseleave",$),document.removeEventListener("click",ne,!0))},re=()=>{if(d){let r=u;if(r&&r.isConnected){let t=r.getBoundingClientRect(),l=window.innerHeight,f=window.innerWidth,p=t.top<l&&t.bottom>0&&t.left<f&&t.right>0,E={top:t.top,left:t.left,right:t.right,bottom:t.bottom,width:t.width,height:t.height,centerX:t.left+t.width/2,centerY:t.top+t.height/2};window.parent.postMessage({type:"element-position-update",position:E,isInViewport:p,visualSelectorId:d},"*")}}},Be=r=>{let t=r.data;switch(t.type){case"toggle-visual-edit-mode":ke(t.data.enabled),t.data.specs?.newInlineEditEnabled!==void 0&&(v.enabled=t.data.specs.newInlineEditEnabled);break;case"update-classes":t.data&&t.data.classes!==void 0?_e(t.data.visualSelectorId,t.data.classes):console.warn("[VisualEditAgent] Invalid update-classes message:",t);break;case"update-attribute":t.data&&t.data.visualSelectorId&&t.data.attribute!==void 0&&t.data.value!==void 0?Re(t.data.visualSelectorId,t.data.attribute,t.data.value):console.warn("[VisualEditAgent] Invalid update-attribute message:",t);break;case"unselect-element":Ne();break;case"refresh-page":window.location.reload();break;case"update-content":t.data&&t.data.content!==void 0?Pe(t.data.visualSelectorId,t.data.content,t.data.arrIndex):console.warn("[VisualEditAgent] Invalid update-content message:",t);break;case"request-element-position":if(d&&u&&u.isConnected){let l=u.getBoundingClientRect(),f=window.innerHeight,p=window.innerWidth,E=l.top<f&&l.bottom>0&&l.left<p&&l.right>0,b={top:l.top,left:l.left,right:l.right,bottom:l.bottom,width:l.width,height:l.height,centerX:l.left+l.width/2,centerY:l.top+l.height/2};window.parent.postMessage({type:"element-position-update",position:b,isInViewport:E,visualSelectorId:d},"*")}break;case"popover-drag-state":t.data&&t.data.isDragging!==void 0&&(n=t.data.isDragging,t.data.isDragging&&i());break;case"dropdown-state":t.data&&t.data.isOpen!==void 0&&(o=t.data.isOpen,t.data.isOpen&&i());break;case"update-theme-variables":if(t.data?.variables){let l=t.data.mode==="dark"?document.querySelector(".dark"):document.documentElement;if(l)for(let[f,p]of Object.entries(t.data.variables))l.style.setProperty(f,p)}break;case"toggle-inline-edit-mode":t.data&&v.handleToggleMessage(t.data);break;default:break}},F=()=>{if(d){let r=S(d);a.forEach((t,l)=>{l<r.length&&g(t,r[l])})}c.length>0&&s.forEach((r,t)=>{t<c.length&&g(r,c[t])})};document.querySelectorAll("[data-linenumber]:not([data-visual-selector-id])").forEach((r,t)=>{let l=r,f=`visual-id-${l.dataset.filename}-${l.dataset.linenumber}-${t}`;l.dataset.visualSelectorId=f});let We=new MutationObserver(r=>{r.some(l=>{let f=E=>{if(E.nodeType===Node.ELEMENT_NODE){let b=E;if(b.dataset&&b.dataset.visualSelectorId)return!0;for(let A=0;A<b.children.length;A++)if(f(b.children[A]))return!0}return!1};return l.type==="attributes"&&(l.attributeName==="style"||l.attributeName==="class"||l.attributeName==="width"||l.attributeName==="height")&&f(l.target)})&&setTimeout(F,B)});window.addEventListener("message",Be),window.addEventListener("scroll",re,!0),document.addEventListener("scroll",re,!0),window.addEventListener("resize",F),window.addEventListener("scroll",F),We.observe(document.body,{attributes:!0,childList:!0,subtree:!0,attributeFilter:["style","class","width","height"]}),window.parent.postMessage({type:"visual-edit-agent-ready"},"*")}export{tt as setupVisualEditAgent};
|
|
16
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/injections/utils.ts","../../src/injections/layer-dropdown/consts.ts","../../src/injections/layer-dropdown/utils.ts","../../src/injections/layer-dropdown/dropdown-ui.ts","../../src/injections/layer-dropdown/controller.ts","../../src/capabilities/inline-edit/dom-utils.ts","../../src/capabilities/inline-edit/controller.ts","../../src/injections/visual-edit-agent.ts"],"sourcesContent":["const LABEL_HEIGHT = 27;\n\n/**\n * Positions an element-tag label relative to its highlighted overlay.\n *\n * Strategy (in priority order):\n * 1. If the element is near the viewport top AND tall enough (>= 2x label height),\n * place the label **inside** the element at the top-left.\n * 2. If the element is near the viewport top but too short, place the label\n * **below** the element.\n * 3. Otherwise, place the label **above** the element (default).\n *\n * For full-width elements (spanning nearly the entire viewport), the left offset\n * is nudged inward (6px) to prevent clipping against the viewport edge.\n *\n * @param label - The label div to position (style.top and style.left are set).\n * @param rect - The bounding client rect of the highlighted element.\n */\nexport function positionLabel(label: HTMLDivElement, rect: DOMRect): void {\n const nearTop = rect.top < LABEL_HEIGHT;\n const tallEnough = rect.height >= LABEL_HEIGHT * 2;\n const isFullWidth = rect.width >= window.innerWidth - 4;\n const edgeLeft = isFullWidth ? \"8px\" : \"-2px\";\n const insideLeft = isFullWidth ? \"8px\" : \"4px\";\n\n if (nearTop && tallEnough) {\n label.style.top = \"2px\";\n label.style.left = insideLeft;\n } else if (nearTop) {\n label.style.top = `${rect.height + 2}px`;\n label.style.left = edgeLeft;\n } else {\n label.style.top = `-${LABEL_HEIGHT}px`;\n label.style.left = edgeLeft;\n }\n}\n\n/** Check if an element has instrumentation attributes */\nexport function isInstrumentedElement(element: Element): boolean {\n const htmlEl = element as HTMLElement;\n return !!(\n htmlEl.dataset?.sourceLocation || htmlEl.dataset?.visualSelectorId\n );\n}\n\n/** Get the selector ID from an element's data attributes (prefers source-location) */\nexport function getElementSelectorId(element: Element): string | null {\n const htmlEl = element as HTMLElement;\n return (\n htmlEl.dataset?.sourceLocation ||\n htmlEl.dataset?.visualSelectorId ||\n null\n );\n}\n\nexport const ALLOWED_ATTRIBUTES: string[] = [\"src\"];\n\nexport const PLUGIN_ELEMENT_ATTR = \"data-vite-plugin-element\";\n\n/** Find elements by ID - first try data-source-location, fallback to data-visual-selector-id */\nexport function findElementsById(id: string | null): Element[] {\n if (!id) return [];\n const sourceElements = Array.from(\n document.querySelectorAll(`[data-source-location=\"${id}\"]`)\n );\n if (sourceElements.length > 0) {\n return sourceElements;\n }\n return Array.from(\n document.querySelectorAll(`[data-visual-selector-id=\"${id}\"]`)\n );\n}\n\n/**\n * Update element classes by visual selector ID.\n * Uses setAttribute instead of className to support both HTML and SVG elements.\n */\nexport function updateElementClasses(elements: Element[], classes: string): void {\n elements.forEach((element) => {\n element.setAttribute(\"class\", classes);\n });\n}\n\n/** Set a single attribute on all provided elements. */\nexport function updateElementAttribute(elements: Element[], attribute: string, value: string): void {\n if (!ALLOWED_ATTRIBUTES.includes(attribute)) {\n return;\n }\n\n elements.forEach((element) => {\n element.setAttribute(attribute, value);\n });\n}\n\n/** Collect attribute values from an element for a given allowlist. */\nexport function collectAllowedAttributes(element: Element, allowedAttributes: string[]): Record<string, string> {\n const attributes: Record<string, string> = {};\n for (const attr of allowedAttributes) {\n const val = element.getAttribute(attr);\n if (val !== null) {\n attributes[attr] = val;\n }\n }\n return attributes;\n}\n\n/**\n * Freeze all CSS animations and transitions on the page by injecting\n * scoped styles under `[data-visual-edit-active]` and programmatically\n * finishing (or pausing) every running animation.\n *\n * Plugin-owned elements (`[data-vite-plugin-element]`) are excluded so\n * the plugin UI stays animated.\n */\nexport function stopAnimations(): void {\n if (document.getElementById('freeze-animations')) return;\n\n document.documentElement.setAttribute('data-visual-edit-active', '');\n\n const animStyle = document.createElement('style');\n animStyle.id = 'freeze-animations';\n animStyle.textContent = `\n [data-visual-edit-active] *:not([${PLUGIN_ELEMENT_ATTR}]):not([${PLUGIN_ELEMENT_ATTR}] *),\n [data-visual-edit-active] *:not([${PLUGIN_ELEMENT_ATTR}]):not([${PLUGIN_ELEMENT_ATTR}] *)::before,\n [data-visual-edit-active] *:not([${PLUGIN_ELEMENT_ATTR}]):not([${PLUGIN_ELEMENT_ATTR}] *)::after {\n animation-play-state: paused !important;\n transition: none !important;\n }\n `;\n\n const pointerStyle = document.createElement('style');\n pointerStyle.id = 'freeze-pointer-events';\n pointerStyle.textContent = `\n [data-visual-edit-active] * { pointer-events: none !important; }\n [${PLUGIN_ELEMENT_ATTR}], [${PLUGIN_ELEMENT_ATTR}] * { pointer-events: auto !important; }\n `;\n\n const target = document.head || document.documentElement;\n target.appendChild(animStyle);\n target.appendChild(pointerStyle);\n\n document.getAnimations().forEach((a) => {\n // Skip animations on plugin UI elements\n const animTarget = (a.effect as KeyframeEffect)?.target;\n if (animTarget instanceof Element && animTarget.closest(`[${PLUGIN_ELEMENT_ATTR}]`)) return;\n\n try {\n a.finish(); // fast-forward to end state\n } catch {\n a.pause(); // finish() throws on infinite animations — pause instead\n }\n });\n}\n\n/**\n * Resume all previously frozen animations and remove the injected\n * freeze styles. Cleans up the `data-visual-edit-active` attribute\n * from `<html>` so scoped selectors no longer match.\n */\nexport function resumeAnimations(): void {\n const animStyle = document.getElementById('freeze-animations');\n if (!animStyle) return;\n\n animStyle.remove();\n document.getElementById('freeze-pointer-events')?.remove();\n document.documentElement.removeAttribute('data-visual-edit-active');\n\n document.getAnimations().forEach((a) => {\n if (a.playState === 'paused') {\n try { a.play(); } catch { /* animation target may have been removed */ }\n }\n });\n}\n\n/**\n * Hit-test the page at (`x`, `y`) and walk up the DOM to find the\n * nearest ancestor that carries instrumentation attributes\n * (`data-source-location` or `data-visual-selector-id`).\n *\n * Temporarily disables the pointer-events freeze sheet so the\n * browser's native `elementFromPoint` can reach the real target.\n */\nexport function findInstrumentedElement(x: number, y: number): Element | null {\n const pointerStyle = document.getElementById('freeze-pointer-events') as HTMLStyleElement | null;\n if (pointerStyle) pointerStyle.disabled = true;\n\n const el = document.elementFromPoint(x, y);\n\n if (pointerStyle) pointerStyle.disabled = false;\n\n return el?.closest('[data-source-location], [data-visual-selector-id]') ?? null;\n}\n\n/**\n * Resolve which element should be hovered at (`x`, `y`), skipping the\n * currently selected element. Returns the selector ID of the hovered\n * element, or `null` if the point is empty or hits the selected element.\n */\nexport function resolveHoverTarget(x: number, y: number, selectedElementId: string | null): string | null {\n const element = findInstrumentedElement(x, y);\n if (!element) return null;\n\n const selectorId = getElementSelectorId(element);\n\n if (selectorId === selectedElementId) return null;\n\n return selectorId;\n}\n","/** Style constants for the layer dropdown UI */\n\nexport const DROPDOWN_CONTAINER_STYLES: Record<string, string> = {\n position: \"absolute\",\n backgroundColor: \"#ffffff\",\n border: \"1px solid #e2e8f0\",\n borderRadius: \"6px\",\n boxShadow: \"0 4px 12px rgba(0, 0, 0, 0.15)\",\n fontSize: \"12px\",\n minWidth: \"120px\",\n maxHeight: \"200px\",\n overflowY: \"auto\",\n zIndex: \"10001\",\n padding: \"4px 0\",\n pointerEvents: \"auto\",\n};\n\nexport const DROPDOWN_ITEM_BASE_STYLES: Record<string, string> = {\n padding: \"4px 12px\",\n cursor: \"pointer\",\n color: \"#334155\",\n backgroundColor: \"transparent\",\n whiteSpace: \"nowrap\",\n lineHeight: \"1.5\",\n fontWeight: \"400\",\n};\n\nexport const DROPDOWN_ITEM_ACTIVE_COLOR = \"#526cff\";\nexport const DROPDOWN_ITEM_ACTIVE_BG = \"#DBEAFE\";\nexport const DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT = \"600\";\n\nexport const DROPDOWN_ITEM_HOVER_BG = \"#f1f5f9\";\n\nexport const DEPTH_INDENT_PX = 10;\n\n/** SVG chevron shown when dropdown is collapsed (click to expand) */\nexport const CHEVRON_COLLAPSED = `<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" style=\"vertical-align:middle;margin-left:4px\"><path d=\"M6 9l6 6 6-6\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"/></svg>`;\n/** SVG chevron shown when dropdown is expanded (click to collapse) */\nexport const CHEVRON_EXPANDED = `<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" style=\"vertical-align:middle;margin-left:4px\"><path d=\"M18 15l-6-6-6 6\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"/></svg>`;\n\nexport const CHEVRON_ATTR = \"data-chevron\";\n\nexport const BASE_PADDING_PX = 12;\n\nexport const LAYER_DROPDOWN_ATTR = \"data-layer-dropdown\";\n\n/** Max instrumented ancestors to show above the selected element */\nexport const MAX_PARENT_DEPTH = 2;\n\n/** Max instrumented depth levels to show below the selected element */\nexport const MAX_CHILD_DEPTH = 2;\n","/** DOM utilities for the layer-dropdown module */\n\nimport { isInstrumentedElement, getElementSelectorId } from \"../utils.js\";\nimport { MAX_PARENT_DEPTH, MAX_CHILD_DEPTH } from \"./consts.js\";\n\nimport type { LayerInfo } from \"./types.js\";\n\n/** Apply a style map to an element */\nexport function applyStyles(element: HTMLElement, styles: Record<string, string>): void {\n for (const key of Object.keys(styles)) {\n element.style.setProperty(\n key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`),\n styles[key]!\n );\n }\n}\n\n/** Display name for a layer — just the real tag name */\nexport function getLayerDisplayName(layer: LayerInfo): string {\n return layer.tagName;\n}\n\nfunction toLayerInfo(element: Element, depth?: number): LayerInfo {\n const info: LayerInfo = {\n element,\n tagName: element.tagName.toLowerCase(),\n selectorId: getElementSelectorId(element),\n };\n if (depth !== undefined) info.depth = depth;\n return info;\n}\n\n/**\n * Collect instrumented descendants up to `maxDepth` instrumented nesting levels.\n * Non-instrumented wrappers are walked through without counting toward depth.\n * Results are in DOM order.\n * When `startDepth` is provided, assigns `depth` to each item during collection.\n */\nexport function getInstrumentedDescendants(\n parent: Element,\n maxDepth: number,\n startDepth?: number\n): LayerInfo[] {\n const result: LayerInfo[] = [];\n\n function walk(el: Element, instrDepth: number): void {\n if (instrDepth > maxDepth) return;\n for (let i = 0; i < el.children.length; i++) {\n const child = el.children[i]!;\n if (isInstrumentedElement(child)) {\n const info: LayerInfo = {\n element: child,\n tagName: child.tagName.toLowerCase(),\n selectorId: getElementSelectorId(child),\n };\n if (startDepth !== undefined) {\n info.depth = startDepth + instrDepth - 1;\n }\n result.push(info);\n walk(child, instrDepth + 1);\n } else {\n walk(child, instrDepth);\n }\n }\n }\n\n walk(parent, 1);\n return result;\n}\n\n/** Collect instrumented ancestors from selected element up to MAX_PARENT_DEPTH (outermost first). */\nfunction collectInstrumentedParents(selectedElement: Element): LayerInfo[] {\n const parents: LayerInfo[] = [];\n let current = selectedElement.parentElement;\n while (\n current &&\n current !== document.documentElement &&\n current !== document.body &&\n parents.length < MAX_PARENT_DEPTH\n ) {\n if (isInstrumentedElement(current)) {\n parents.push(toLayerInfo(current));\n }\n current = current.parentElement;\n }\n parents.reverse();\n return parents;\n}\n\n/** Add parents to chain with depth 0, 1, …; returns depth of selected (parents.length). */\nfunction addParentsToChain(chain: LayerInfo[], parents: LayerInfo[]): number {\n parents.forEach((p, i) => {\n chain.push({ ...p, depth: i });\n });\n return parents.length;\n}\n\n/** Add selected element and its descendants at the given depth. */\nfunction addSelfAndDescendantsToChain(\n chain: LayerInfo[],\n selectedElement: Element,\n selfDepth: number\n): void {\n chain.push(toLayerInfo(selectedElement, selfDepth));\n const descendants = getInstrumentedDescendants(\n selectedElement,\n MAX_CHILD_DEPTH,\n selfDepth + 1\n );\n chain.push(...descendants);\n}\n\n/** Get the innermost instrumented parent's DOM element, or null if none. */\nfunction getImmediateInstrParent(parents: LayerInfo[]): Element | null {\n return parents.at(-1)?.element ?? null;\n}\n\n/** Collect instrumented siblings of the selected element from its parent (DOM order). */\nfunction collectSiblings(parent: Element, selectedElement: Element): LayerInfo[] {\n const siblings = getInstrumentedDescendants(parent, 1);\n if (!siblings.some((s) => s.element === selectedElement)) {\n siblings.push(toLayerInfo(selectedElement));\n }\n return siblings;\n}\n\n/** Add siblings at selfDepth, expanding children only for the selected element. */\nfunction appendSiblingsWithSelected(\n chain: LayerInfo[],\n siblings: LayerInfo[],\n selectedElement: Element,\n selfDepth: number\n): void {\n const selectedSelectorId = getElementSelectorId(selectedElement);\n const seen = new Set<string>();\n for (const sibling of siblings) {\n if (sibling.element === selectedElement) {\n addSelfAndDescendantsToChain(chain, selectedElement, selfDepth);\n if (selectedSelectorId) seen.add(selectedSelectorId);\n } else {\n const id = sibling.selectorId;\n if (id != null) {\n if (id === selectedSelectorId || seen.has(id)) continue;\n seen.add(id);\n }\n chain.push({ ...sibling, depth: selfDepth });\n }\n }\n}\n\n/**\n * Build the layer chain for the dropdown:\n *\n * Parents – up to MAX_PARENT_DEPTH instrumented ancestors, outer → inner.\n * Siblings – instrumented children of the immediate parent, at the same depth.\n * Current – the selected element (highlighted), with children expanded.\n * Children – instrumented descendants within MAX_CHILD_DEPTH levels, DOM order.\n *\n * Each item carries a `depth` for visual indentation.\n */\nexport function buildLayerChain(selectedElement: Element): LayerInfo[] {\n const parents = collectInstrumentedParents(selectedElement);\n const chain: LayerInfo[] = [];\n const selfDepth = addParentsToChain(chain, parents);\n\n const instrParent = getImmediateInstrParent(parents);\n if (instrParent) {\n const siblings = collectSiblings(instrParent, selectedElement);\n appendSiblingsWithSelected(chain, siblings, selectedElement, selfDepth);\n } else {\n addSelfAndDescendantsToChain(chain, selectedElement, selfDepth);\n }\n\n return chain;\n}\n","/** Dropdown UI component for layer navigation */\n\nimport {\n DROPDOWN_CONTAINER_STYLES,\n DROPDOWN_ITEM_BASE_STYLES,\n DROPDOWN_ITEM_ACTIVE_COLOR,\n DROPDOWN_ITEM_ACTIVE_BG,\n DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT,\n DROPDOWN_ITEM_HOVER_BG,\n DEPTH_INDENT_PX,\n BASE_PADDING_PX,\n CHEVRON_COLLAPSED,\n CHEVRON_EXPANDED,\n CHEVRON_ATTR,\n LAYER_DROPDOWN_ATTR,\n} from \"./consts.js\";\nimport { applyStyles, getLayerDisplayName } from \"./utils.js\";\nimport type { LayerInfo, DropdownCallbacks } from \"./types.js\";\nimport { PLUGIN_ELEMENT_ATTR } from \"../utils.js\";\n\nlet activeDropdown: HTMLDivElement | null = null;\nlet activeLabel: HTMLDivElement | null = null;\nlet outsideMousedownHandler: ((e: MouseEvent) => void) | null = null;\nlet activeOnHoverEnd: (() => void) | null = null;\nlet activeKeydownHandler: ((e: KeyboardEvent) => void) | null = null;\n\nfunction createDropdownItem(\n layer: LayerInfo,\n isActive: boolean,\n { onSelect, onHover, onHoverEnd }: DropdownCallbacks\n): HTMLDivElement {\n const item = document.createElement(\"div\");\n item.textContent = getLayerDisplayName(layer);\n applyStyles(item, DROPDOWN_ITEM_BASE_STYLES);\n\n const depth = layer.depth ?? 0;\n if (depth > 0) {\n item.style.paddingLeft = `${BASE_PADDING_PX + depth * DEPTH_INDENT_PX}px`;\n }\n\n if (isActive) {\n item.style.color = DROPDOWN_ITEM_ACTIVE_COLOR;\n item.style.backgroundColor = DROPDOWN_ITEM_ACTIVE_BG;\n item.style.fontWeight = DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT;\n }\n\n item.addEventListener(\"mouseenter\", () => {\n if (!isActive) item.style.backgroundColor = DROPDOWN_ITEM_HOVER_BG;\n if (onHover) onHover(layer);\n });\n\n item.addEventListener(\"mouseleave\", () => {\n if (!isActive) item.style.backgroundColor = \"transparent\";\n if (onHoverEnd) onHoverEnd();\n });\n\n item.addEventListener(\"click\", (e: MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n onSelect(layer);\n });\n\n return item;\n}\n\n/** Create the dropdown DOM element with layer items */\nexport function createDropdownElement(\n layers: LayerInfo[],\n currentElement: Element | null,\n callbacks: DropdownCallbacks\n): HTMLDivElement {\n const container = document.createElement(\"div\");\n container.setAttribute(LAYER_DROPDOWN_ATTR, \"true\");\n container.setAttribute(PLUGIN_ELEMENT_ATTR, \"true\");\n applyStyles(container, DROPDOWN_CONTAINER_STYLES);\n\n layers.forEach((layer) => {\n const isActive = layer.element === currentElement;\n container.appendChild(createDropdownItem(layer, isActive, callbacks));\n });\n\n return container;\n}\n\n/** Add chevron indicator and pointer-events to the label */\nexport function enhanceLabelWithChevron(label: HTMLDivElement): void {\n if (label.querySelector(`[${CHEVRON_ATTR}]`)) return;\n\n const chevron = document.createElement(\"span\");\n chevron.setAttribute(CHEVRON_ATTR, \"true\");\n chevron.style.display = \"inline-flex\";\n chevron.innerHTML = CHEVRON_COLLAPSED;\n label.appendChild(chevron);\n\n label.style.display = \"inline-flex\";\n label.style.alignItems = \"center\";\n label.style.cursor = \"pointer\";\n label.style.userSelect = \"none\";\n label.style.whiteSpace = \"nowrap\";\n label.style.pointerEvents = \"auto\";\n label.setAttribute(LAYER_DROPDOWN_ATTR, \"true\");\n label.setAttribute(PLUGIN_ELEMENT_ATTR, \"true\");\n}\n\nfunction setupKeyboardNavigation(\n dropdown: HTMLDivElement,\n layers: LayerInfo[],\n currentElement: Element | null,\n { onSelect, onHover, onHoverEnd }: DropdownCallbacks\n): void {\n const items = Array.from(dropdown.children) as HTMLDivElement[];\n let focusedIndex = layers.findIndex((l) => l.element === currentElement);\n\n const setFocusedItem = (index: number) => {\n if (focusedIndex >= 0 && focusedIndex < items.length) {\n const prev = items[focusedIndex]!;\n if (prev.style.color !== DROPDOWN_ITEM_ACTIVE_COLOR) {\n prev.style.backgroundColor = \"transparent\";\n }\n }\n focusedIndex = index;\n if (focusedIndex >= 0 && focusedIndex < items.length) {\n const cur = items[focusedIndex]!;\n if (cur.style.color !== DROPDOWN_ITEM_ACTIVE_COLOR) {\n cur.style.backgroundColor = DROPDOWN_ITEM_HOVER_BG;\n }\n cur.scrollIntoView({ block: \"nearest\" });\n if (onHover && focusedIndex >= 0 && focusedIndex < layers.length) {\n onHover(layers[focusedIndex]!);\n }\n }\n };\n\n activeKeydownHandler = (e: KeyboardEvent) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n e.stopPropagation();\n setFocusedItem(focusedIndex < items.length - 1 ? focusedIndex + 1 : 0);\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n e.stopPropagation();\n setFocusedItem(focusedIndex > 0 ? focusedIndex - 1 : items.length - 1);\n } else if (e.key === \"Enter\" && focusedIndex >= 0 && focusedIndex < layers.length) {\n e.preventDefault();\n e.stopPropagation();\n if (onHoverEnd) onHoverEnd();\n onSelect(layers[focusedIndex]!);\n closeDropdown();\n }\n };\n document.addEventListener(\"keydown\", activeKeydownHandler, true);\n}\n\nfunction setupOutsideClickHandler(\n dropdown: HTMLDivElement,\n label: HTMLDivElement\n): void {\n let skipFirst = true;\n outsideMousedownHandler = (e: MouseEvent) => {\n if (skipFirst) { skipFirst = false; return; }\n const target = e.target as Node;\n if (!dropdown.contains(target) && target !== label) {\n closeDropdown();\n }\n };\n document.addEventListener(\"mousedown\", outsideMousedownHandler, true);\n}\n\n/** Show the dropdown below the label element */\nexport function showDropdown(\n label: HTMLDivElement,\n layers: LayerInfo[],\n currentElement: Element | null,\n callbacks: DropdownCallbacks\n): void {\n closeDropdown();\n\n const dropdown = createDropdownElement(\n layers,\n currentElement,\n {\n ...callbacks,\n onSelect: (layer) => {\n if (callbacks.onHoverEnd) callbacks.onHoverEnd();\n callbacks.onSelect(layer);\n closeDropdown();\n },\n }\n );\n\n const overlay = label.parentElement;\n if (!overlay) return;\n\n dropdown.style.top = `${label.offsetTop + label.offsetHeight + 2}px`;\n dropdown.style.left = `${label.offsetLeft}px`;\n\n overlay.appendChild(dropdown);\n activeDropdown = dropdown;\n activeLabel = label;\n const chevronEl = label.querySelector(`[${CHEVRON_ATTR}]`);\n if (chevronEl) {\n chevronEl.innerHTML = CHEVRON_EXPANDED;\n }\n activeOnHoverEnd = callbacks.onHoverEnd ?? null;\n\n setupKeyboardNavigation(dropdown, layers, currentElement, callbacks);\n setupOutsideClickHandler(dropdown, label);\n}\n\n/** Close the active dropdown and clean up listeners */\nexport function closeDropdown(): void {\n const chevronEl = activeLabel?.querySelector(`[${CHEVRON_ATTR}]`);\n if (chevronEl) {\n chevronEl.innerHTML = CHEVRON_COLLAPSED;\n }\n activeLabel = null;\n\n if (activeOnHoverEnd) {\n activeOnHoverEnd();\n activeOnHoverEnd = null;\n }\n\n if (activeDropdown && activeDropdown.parentNode) {\n activeDropdown.remove();\n }\n activeDropdown = null;\n\n if (outsideMousedownHandler) {\n document.removeEventListener(\"mousedown\", outsideMousedownHandler, true);\n outsideMousedownHandler = null;\n }\n\n if (activeKeydownHandler) {\n document.removeEventListener(\"keydown\", activeKeydownHandler, true);\n activeKeydownHandler = null;\n }\n}\n\n/** Check if a dropdown is currently visible */\nexport function isDropdownOpen(): boolean {\n return activeDropdown !== null;\n}\n","/** Controller that encapsulates layer-dropdown integration logic */\n\nimport { getElementSelectorId } from \"../utils.js\";\nimport { buildLayerChain } from \"./utils.js\";\nimport {\n enhanceLabelWithChevron,\n showDropdown,\n closeDropdown,\n isDropdownOpen,\n} from \"./dropdown-ui.js\";\nimport type { LayerInfo, LayerControllerConfig, LayerController } from \"./types.js\";\n\nexport function createLayerController(config: LayerControllerConfig): LayerController {\n let layerPreviewOverlay: HTMLDivElement | null = null;\n let escapeHandler: ((e: KeyboardEvent) => void) | null = null;\n let dropdownSourceLayer: LayerInfo | null = null;\n\n const clearLayerPreview = () => {\n if (layerPreviewOverlay && layerPreviewOverlay.parentNode) {\n layerPreviewOverlay.remove();\n }\n layerPreviewOverlay = null;\n };\n\n const showLayerPreview = (layer: LayerInfo) => {\n clearLayerPreview();\n if (getElementSelectorId(layer.element) === config.getSelectedElementId()) return;\n\n layerPreviewOverlay = config.createPreviewOverlay(layer.element);\n };\n\n const selectLayer = (layer: LayerInfo) => {\n clearLayerPreview();\n closeDropdown();\n if (escapeHandler) {\n document.removeEventListener(\"keydown\", escapeHandler, true);\n escapeHandler = null;\n }\n dropdownSourceLayer = null;\n\n const firstOverlay = config.selectElement(layer.element);\n attachToOverlay(firstOverlay, layer.element);\n };\n\n const restoreSelection = () => {\n if (escapeHandler) {\n document.removeEventListener(\"keydown\", escapeHandler, true);\n escapeHandler = null;\n }\n if (dropdownSourceLayer) {\n selectLayer(dropdownSourceLayer);\n dropdownSourceLayer = null;\n }\n };\n\n const handleLabelClick = (e: MouseEvent, label: HTMLDivElement, element: Element, layers: LayerInfo[], currentId: string | null) => {\n e.stopPropagation();\n e.preventDefault();\n if (isDropdownOpen()) {\n closeDropdown();\n restoreSelection();\n } else {\n dropdownSourceLayer = {\n element,\n tagName: element.tagName.toLowerCase(),\n selectorId: currentId,\n };\n config.onDeselect();\n\n escapeHandler = (ev: KeyboardEvent) => {\n if (ev.key === \"Escape\") {\n ev.stopPropagation();\n closeDropdown();\n restoreSelection();\n }\n };\n document.addEventListener(\"keydown\", escapeHandler, true);\n\n showDropdown(label, layers, element, { onSelect: selectLayer, onHover: showLayerPreview, onHoverEnd: clearLayerPreview });\n }\n };\n\n const attachToOverlay = (\n overlay: HTMLDivElement | undefined,\n element: Element\n ) => {\n if (!overlay) return;\n\n const label = overlay.querySelector(\"div\") as HTMLDivElement | null;\n if (!label) return;\n\n const layers = buildLayerChain(element);\n if (layers.length <= 1) return;\n\n const currentId = getElementSelectorId(element);\n enhanceLabelWithChevron(label);\n\n label.addEventListener(\"click\", (e: MouseEvent) => {\n handleLabelClick(e, label, element, layers, currentId);\n });\n };\n\n const cleanup = () => {\n clearLayerPreview();\n closeDropdown();\n };\n\n return { attachToOverlay, cleanup };\n}\n","const FOCUS_STYLE_ID = \"visual-edit-focus-styles\";\n\nconst EDITABLE_TAGS = [\n \"div\", \"p\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\",\n \"span\", \"li\", \"td\", \"a\", \"button\", \"label\",\n];\n\nexport const isStaticArrayTextElement = (element: HTMLElement): boolean => {\n return !!element.dataset.arrField;\n};\n\nconst passesStructuralChecks = (element: HTMLElement): boolean => {\n if (!EDITABLE_TAGS.includes(element.tagName.toLowerCase())) return false;\n if (!element.textContent?.trim()) return false;\n if (element.querySelector(\"img, video, canvas, svg\")) return false;\n if (element.children?.length > 0) return false;\n return true;\n};\n\nexport const injectFocusOutlineCSS = () => {\n if (document.getElementById(FOCUS_STYLE_ID)) return;\n\n const style = document.createElement(\"style\");\n style.id = FOCUS_STYLE_ID;\n style.textContent = `\n [data-selected=\"true\"][contenteditable=\"true\"]:focus {\n outline: none !important;\n }\n `;\n document.head.appendChild(style);\n};\n\nexport const removeFocusOutlineCSS = () => {\n document.getElementById(FOCUS_STYLE_ID)?.remove();\n};\n\nexport const selectText = (element: HTMLElement) => {\n const range = document.createRange();\n range.selectNodeContents(element);\n const selection = window.getSelection();\n selection?.removeAllRanges();\n selection?.addRange(range);\n};\n\nexport const isEditableTextElement = (element: Element): boolean => {\n if (!(element instanceof HTMLElement)) return false;\n if (!passesStructuralChecks(element)) return false;\n if (isStaticArrayTextElement(element)) return true;\n if (element.dataset.dynamicContent === \"true\") return false;\n return true;\n};\n\nexport const shouldEnterInlineEditingMode = (element: Element): boolean => {\n if (!(element instanceof HTMLElement) || element.dataset.selected !== \"true\") {\n return false;\n }\n return isEditableTextElement(element);\n};\n","import type { InlineEditHost, InlineEditController } from \"./types.js\";\nimport {\n injectFocusOutlineCSS,\n removeFocusOutlineCSS,\n selectText,\n shouldEnterInlineEditingMode,\n isStaticArrayTextElement,\n} from \"./dom-utils.js\";\nimport { PLUGIN_ELEMENT_ATTR } from \"../../injections/utils.js\";\n\nconst DEBOUNCE_MS = 500;\n\nexport function createInlineEditController(\n host: InlineEditHost\n): InlineEditController {\n let currentEditingElement: HTMLElement | null = null;\n let debouncedSendTimeout: ReturnType<typeof setTimeout> | null = null;\n let enabled = false;\n const listenerAbortControllers = new WeakMap<HTMLElement, AbortController>();\n\n // --- Private helpers ---\n\n const repositionOverlays = () => {\n const selectedId = host.getSelectedElementId();\n if (!selectedId) return;\n const elements = host.findElementsById(selectedId);\n const overlays = host.getSelectedOverlays();\n overlays.forEach((overlay, i) => {\n if (i < elements.length && elements[i]) {\n host.positionOverlay(overlay, elements[i]);\n }\n });\n };\n\n const reportEdit = (element: HTMLElement) => {\n const originalContent = element.dataset.originalTextContent;\n const newContent = element.textContent;\n\n const svgElement = element as unknown as SVGElement;\n const rect = element.getBoundingClientRect();\n\n const message: Record<string, unknown> = {\n type: \"inline-edit\",\n elementInfo: {\n tagName: element.tagName,\n classes:\n (svgElement.className as unknown as SVGAnimatedString)?.baseVal ||\n element.className ||\n \"\",\n visualSelectorId: host.getSelectedElementId(),\n content: newContent,\n dataSourceLocation: element.dataset.sourceLocation,\n isDynamicContent: element.dataset.dynamicContent === \"true\",\n linenumber: element.dataset.linenumber,\n filename: element.dataset.filename,\n position: {\n top: rect.top,\n left: rect.left,\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n centerX: rect.left + rect.width / 2,\n centerY: rect.top + rect.height / 2,\n },\n },\n originalContent,\n newContent,\n };\n\n if (isStaticArrayTextElement(element)) {\n message.arrIndex = element.dataset.arrIndex;\n message.arrVariableName = element.dataset.arrVariableName;\n message.arrField = element.dataset.arrField;\n }\n\n window.parent.postMessage(message, \"*\");\n\n element.dataset.originalTextContent = newContent || \"\";\n };\n\n const debouncedReport = (element: HTMLElement) => {\n if (debouncedSendTimeout) clearTimeout(debouncedSendTimeout);\n debouncedSendTimeout = setTimeout(() => reportEdit(element), DEBOUNCE_MS);\n };\n\n const onTextInput = (element: HTMLElement) => {\n repositionOverlays();\n debouncedReport(element);\n };\n\n const handleInputEvent = function (this: HTMLElement) {\n onTextInput(this);\n };\n\n const makeEditable = (element: HTMLElement) => {\n injectFocusOutlineCSS();\n\n element.dataset.originalTextContent = element.textContent || \"\";\n element.dataset.originalCursor = element.style.cursor;\n element.contentEditable = \"true\";\n element.setAttribute(PLUGIN_ELEMENT_ATTR, \"true\");\n\n const abortController = new AbortController();\n listenerAbortControllers.set(element, abortController);\n element.addEventListener(\"input\", handleInputEvent, {\n signal: abortController.signal,\n });\n\n element.style.cursor = \"text\";\n selectText(element);\n setTimeout(() => {\n if (element.isConnected) {\n element.focus();\n }\n }, 0);\n };\n\n const makeNonEditable = (element: HTMLElement) => {\n const abortController = listenerAbortControllers.get(element);\n if (abortController) {\n abortController.abort();\n listenerAbortControllers.delete(element);\n }\n\n if (!element.isConnected) return;\n\n removeFocusOutlineCSS();\n element.contentEditable = \"false\";\n element.removeAttribute(PLUGIN_ELEMENT_ATTR);\n delete element.dataset.originalTextContent;\n\n if (element.dataset.originalCursor !== undefined) {\n element.style.cursor = element.dataset.originalCursor;\n delete element.dataset.originalCursor;\n }\n };\n\n // --- Public API ---\n\n return {\n get enabled() {\n return enabled;\n },\n set enabled(value: boolean) {\n enabled = value;\n },\n\n isEditing() {\n return currentEditingElement !== null;\n },\n\n getCurrentElement() {\n return currentEditingElement;\n },\n\n canEdit(element: Element) {\n return shouldEnterInlineEditingMode(element);\n },\n\n startEditing(element: HTMLElement) {\n currentEditingElement = element;\n\n host.getSelectedOverlays().forEach((o) => {\n o.style.display = \"none\";\n });\n\n makeEditable(element);\n\n window.parent.postMessage(\n {\n type: \"content-editing-started\",\n visualSelectorId: host.getSelectedElementId(),\n },\n \"*\"\n );\n },\n\n stopEditing() {\n if (!currentEditingElement) return;\n\n if (debouncedSendTimeout) {\n clearTimeout(debouncedSendTimeout);\n debouncedSendTimeout = null;\n }\n\n const element = currentEditingElement;\n makeNonEditable(element);\n\n host.getSelectedOverlays().forEach((o) => {\n o.style.display = \"\";\n });\n\n repositionOverlays();\n\n window.parent.postMessage(\n {\n type: \"content-editing-ended\",\n visualSelectorId: host.getSelectedElementId(),\n },\n \"*\"\n );\n\n currentEditingElement = null;\n },\n\n markElementsSelected(elements: Element[]) {\n elements.forEach((el) => {\n if (el instanceof HTMLElement) {\n el.dataset.selected = \"true\";\n }\n });\n },\n\n clearSelectedMarks(elementId: string | null) {\n if (!elementId) return;\n host.findElementsById(elementId).forEach((el) => {\n if (el instanceof HTMLElement) {\n delete el.dataset.selected;\n }\n });\n },\n\n handleToggleMessage(data: { dataSourceLocation: string; inlineEditingMode: boolean }) {\n if (!enabled) return;\n\n const elements = host.findElementsById(data.dataSourceLocation);\n if (elements.length === 0 || !(elements[0] instanceof HTMLElement)) return;\n\n const element = elements[0];\n\n if (data.inlineEditingMode) {\n if (!shouldEnterInlineEditingMode(element)) return;\n\n // Select the element first if not already selected\n if (host.getSelectedElementId() !== data.dataSourceLocation) {\n this.stopEditing();\n host.clearSelection();\n this.markElementsSelected(elements);\n host.createSelectionOverlays(elements, data.dataSourceLocation);\n }\n this.startEditing(element);\n } else {\n if (currentEditingElement === element) {\n this.stopEditing();\n }\n }\n },\n\n cleanup() {\n this.stopEditing();\n },\n };\n}\n","import { findElementsById, updateElementClasses, updateElementAttribute, collectAllowedAttributes, ALLOWED_ATTRIBUTES, getElementSelectorId, stopAnimations, resumeAnimations, findInstrumentedElement, resolveHoverTarget, positionLabel } from \"./utils.js\";\nimport { createLayerController } from \"./layer-dropdown/controller.js\";\nimport { LAYER_DROPDOWN_ATTR } from \"./layer-dropdown/consts.js\";\nimport { createInlineEditController } from \"../capabilities/inline-edit/index.js\";\n\nconst REPOSITION_DELAY_MS = 50;\n\nexport function setupVisualEditAgent() {\n // State variables (replacing React useState/useRef)\n let isVisualEditMode = false;\n let isPopoverDragging = false;\n let isDropdownOpen = false;\n let hoverOverlays: HTMLDivElement[] = [];\n let selectedOverlays: HTMLDivElement[] = [];\n let currentHighlightedElements: Element[] = [];\n let selectedElementId: string | null = null;\n let selectedElement: Element | null = null;\n\n // Create overlay element\n const createOverlay = (isSelected = false): HTMLDivElement => {\n const overlay = document.createElement(\"div\");\n overlay.style.position = \"absolute\";\n overlay.style.pointerEvents = \"none\";\n overlay.style.transition = \"all 0.1s ease-in-out\";\n overlay.style.zIndex = \"9999\";\n\n if (isSelected) {\n overlay.style.border = \"2px solid #2563EB\";\n } else {\n overlay.style.border = \"2px solid #95a5fc\";\n overlay.style.backgroundColor = \"rgba(99, 102, 241, 0.05)\";\n }\n\n return overlay;\n };\n\n // Position overlay relative to element\n const positionOverlay = (\n overlay: HTMLDivElement,\n element: Element,\n isSelected = false\n ) => {\n if (!element || !isVisualEditMode) return;\n\n const htmlElement = element as HTMLElement;\n // Force layout recalculation\n void htmlElement.offsetWidth;\n\n const rect = element.getBoundingClientRect();\n overlay.style.top = `${rect.top + window.scrollY}px`;\n overlay.style.left = `${rect.left + window.scrollX}px`;\n overlay.style.width = `${rect.width}px`;\n overlay.style.height = `${rect.height}px`;\n\n // Check if label already exists in overlay\n let label = overlay.querySelector(\"div\") as HTMLDivElement | null;\n\n if (!label) {\n label = document.createElement(\"div\");\n label.textContent = element.tagName.toLowerCase();\n label.style.position = \"absolute\";\n label.style.left = \"-2px\";\n label.style.padding = \"2px 8px\";\n label.style.fontSize = \"11px\";\n label.style.fontWeight = isSelected ? \"500\" : \"400\";\n label.style.color = isSelected ? \"#ffffff\" : \"#526cff\";\n label.style.backgroundColor = isSelected ? \"#2563EB\" : \"#DBEAFE\";\n label.style.borderRadius = \"3px\";\n label.style.minWidth = \"24px\";\n label.style.textAlign = \"center\";\n overlay.appendChild(label);\n }\n\n positionLabel(label, rect);\n };\n\n // --- Inline edit controller ---\n const inlineEdit = createInlineEditController({\n findElementsById,\n getSelectedElementId: () => selectedElementId,\n getSelectedOverlays: () => selectedOverlays,\n positionOverlay,\n clearSelection: () => {\n inlineEdit.clearSelectedMarks(selectedElementId);\n clearSelectedOverlays();\n selectedElementId = null;\n selectedElement = null;\n },\n createSelectionOverlays: (elements, elementId) => {\n elements.forEach((el) => {\n const overlay = createOverlay(true);\n document.body.appendChild(overlay);\n selectedOverlays.push(overlay);\n positionOverlay(overlay, el, true);\n });\n selectedElementId = elementId;\n },\n });\n\n const clearSelection = () => {\n inlineEdit.clearSelectedMarks(selectedElementId);\n clearSelectedOverlays();\n selectedElementId = null;\n selectedElement = null;\n };\n\n // Clear hover overlays\n const clearHoverOverlays = () => {\n hoverOverlays.forEach((overlay) => {\n if (overlay && overlay.parentNode) {\n overlay.remove();\n }\n });\n hoverOverlays = [];\n currentHighlightedElements = [];\n };\n\n const clearSelectedOverlays = () => {\n selectedOverlays.forEach((overlay) => {\n if (overlay && overlay.parentNode) {\n overlay.remove();\n }\n });\n selectedOverlays = [];\n };\n\n const TEXT_TAGS = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span', 'a', 'label'];\n\n const notifyElementSelected = (element: Element) => {\n const htmlElement = element as HTMLElement;\n const rect = element.getBoundingClientRect();\n const svgElement = element as SVGElement;\n const isTextElement = TEXT_TAGS.includes(element.tagName?.toLowerCase());\n\n const arrEl = htmlElement.closest(\"[data-arr-variable-name]\") as HTMLElement | null;\n const staticArrayName = arrEl?.dataset?.arrVariableName || null;\n const rawIdx = arrEl?.dataset?.arrIndex;\n const staticArrayIndex = rawIdx != null ? parseInt(rawIdx, 10) : null;\n const staticArrayField = htmlElement.dataset?.arrField || null;\n\n window.parent.postMessage({\n type: \"element-selected\",\n tagName: element.tagName,\n classes:\n (svgElement.className as unknown as SVGAnimatedString)?.baseVal ||\n element.className ||\n \"\",\n visualSelectorId: getElementSelectorId(element),\n content: isTextElement ? htmlElement.innerText : undefined,\n dataSourceLocation: htmlElement.dataset.sourceLocation,\n isDynamicContent: htmlElement.dataset.dynamicContent === \"true\",\n linenumber: htmlElement.dataset.linenumber,\n filename: htmlElement.dataset.filename,\n position: {\n top: rect.top,\n left: rect.left,\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n centerX: rect.left + rect.width / 2,\n centerY: rect.top + rect.height / 2,\n },\n attributes: collectAllowedAttributes(element, ALLOWED_ATTRIBUTES),\n isTextElement,\n staticArrayName,\n staticArrayIndex,\n staticArrayField,\n }, \"*\");\n };\n\n // Select an element: create overlays, update state, notify parent\n const selectElement = (element: Element): HTMLDivElement | undefined => {\n const visualSelectorId = getElementSelectorId(element);\n\n clearSelectedOverlays();\n\n const elements = findElementsById(visualSelectorId || null);\n elements.forEach((el) => {\n const overlay = createOverlay(true);\n document.body.appendChild(overlay);\n selectedOverlays.push(overlay);\n positionOverlay(overlay, el, true);\n });\n\n selectedElementId = visualSelectorId || null;\n selectedElement = element;\n clearHoverOverlays();\n notifyElementSelected(element);\n\n return selectedOverlays[0];\n };\n\n const notifyDeselection = (): void => {\n selectedElementId = null;\n window.parent.postMessage({ type: \"unselect-element\" }, \"*\");\n };\n\n // Hover detection via mousemove + elementFromPoint (since app elements have pointer-events: none)\n let lastHoveredSelectorId: string | null = null;\n let pendingMouseMoveRaf: number | null = null;\n\n const clearHoverState = () => {\n clearHoverOverlays();\n lastHoveredSelectorId = null;\n };\n\n const applyHoverOverlays = (selectorId: string) => {\n const elements = findElementsById(selectorId);\n clearHoverOverlays();\n\n elements.forEach((el) => {\n const overlay = createOverlay(false);\n document.body.appendChild(overlay);\n hoverOverlays.push(overlay);\n positionOverlay(overlay, el);\n });\n\n currentHighlightedElements = elements;\n lastHoveredSelectorId = selectorId;\n };\n\n const handleMouseMove = (e: MouseEvent) => {\n if (!isVisualEditMode || isPopoverDragging || inlineEdit.isEditing()) return;\n\n if (pendingMouseMoveRaf !== null) return;\n pendingMouseMoveRaf = requestAnimationFrame(() => {\n pendingMouseMoveRaf = null;\n\n if (isDropdownOpen) { clearHoverState(); return; }\n\n const selectorId = resolveHoverTarget(e.clientX, e.clientY, selectedElementId);\n if (!selectorId) { clearHoverState(); return; }\n if (lastHoveredSelectorId === selectorId) return;\n\n applyHoverOverlays(selectorId);\n });\n };\n\n // Clear hover overlays when mouse leaves the viewport\n const handleMouseLeave = () => {\n if (pendingMouseMoveRaf !== null) {\n cancelAnimationFrame(pendingMouseMoveRaf);\n pendingMouseMoveRaf = null;\n }\n clearHoverState();\n };\n\n // Handle element click\n const handleElementClick = (e: MouseEvent) => {\n if (!isVisualEditMode) return;\n\n const target = e.target as Element;\n\n // Let layer dropdown clicks pass through without interference\n if (target.closest(`[${LAYER_DROPDOWN_ATTR}]`)) return;\n\n // Let clicks inside the editable element pass through to the browser\n // so the user can reposition the cursor and select text naturally.\n if (inlineEdit.enabled && target instanceof HTMLElement && target.contentEditable === \"true\") {\n return;\n }\n\n // Clicking outside the editable element exits inline editing mode.\n if (inlineEdit.isEditing()) {\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n inlineEdit.stopEditing();\n return;\n }\n\n // Close dropdowns when clicking anywhere in iframe if a dropdown is open\n if (isDropdownOpen) {\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n\n window.parent.postMessage({ type: \"close-dropdowns\" }, \"*\");\n return;\n }\n\n // Prevent default behavior immediately when in visual edit mode\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n\n const element = findInstrumentedElement(e.clientX, e.clientY);\n if (!element) {\n return;\n }\n\n const htmlElement = element as HTMLElement;\n const visualSelectorId = getElementSelectorId(element);\n\n const isAlreadySelected =\n selectedElementId === visualSelectorId &&\n htmlElement.dataset.selected === \"true\";\n\n if (isAlreadySelected && inlineEdit.enabled && inlineEdit.canEdit(htmlElement)) {\n inlineEdit.startEditing(htmlElement);\n return;\n }\n\n inlineEdit.stopEditing();\n\n if (inlineEdit.enabled) {\n inlineEdit.markElementsSelected(findElementsById(visualSelectorId));\n }\n\n const selectedOverlay = selectElement(element);\n layerController.attachToOverlay(selectedOverlay, element);\n };\n\n const unselectElement = () => {\n inlineEdit.stopEditing();\n clearSelection();\n };\n\n const updateElementClassesAndReposition = (visualSelectorId: string, classes: string) => {\n const elements = findElementsById(visualSelectorId);\n if (elements.length === 0) return;\n\n updateElementClasses(elements, classes);\n\n // Use a small delay to allow the browser to recalculate layout before repositioning\n setTimeout(() => {\n // Reposition selected overlays\n if (selectedElementId === visualSelectorId) {\n selectedOverlays.forEach((overlay, index) => {\n if (index < elements.length) {\n positionOverlay(overlay, elements[index]!);\n }\n });\n }\n\n // Reposition hover overlays if needed\n if (currentHighlightedElements.length > 0) {\n const hoveredElement = currentHighlightedElements[0] as HTMLElement;\n const hoveredId = hoveredElement?.dataset?.visualSelectorId;\n if (hoveredId === visualSelectorId) {\n hoverOverlays.forEach((overlay, index) => {\n if (index < currentHighlightedElements.length) {\n positionOverlay(overlay, currentHighlightedElements[index]!);\n }\n });\n }\n }\n }, REPOSITION_DELAY_MS);\n };\n\n // Update element attribute by visual selector ID\n const updateElementAttributeAndReposition = (\n visualSelectorId: string,\n attribute: string,\n value: string\n ) => {\n const elements = findElementsById(visualSelectorId);\n if (elements.length === 0) return;\n\n updateElementAttribute(elements, attribute, value);\n\n // Reposition overlays after attribute change (e.g. image src swap can affect layout)\n setTimeout(() => {\n if (selectedElementId === visualSelectorId) {\n selectedOverlays.forEach((overlay, index) => {\n if (index < elements.length) {\n positionOverlay(overlay, elements[index]!);\n }\n });\n }\n }, REPOSITION_DELAY_MS);\n };\n\n const updateElementContent = (visualSelectorId: string, content: string, arrIndex?: number) => {\n let elements = findElementsById(visualSelectorId);\n\n if (elements.length === 0) {\n return;\n }\n\n if (arrIndex != null) {\n elements = elements.filter(\n (el) => (el as HTMLElement).dataset.arrIndex === String(arrIndex)\n );\n }\n\n elements.forEach((element) => {\n (element as HTMLElement).innerText = content;\n });\n\n setTimeout(() => {\n if (selectedElementId === visualSelectorId) {\n selectedOverlays.forEach((overlay, index) => {\n if (index < elements.length) {\n positionOverlay(overlay, elements[index]!);\n }\n });\n }\n }, REPOSITION_DELAY_MS);\n };\n\n // --- Layer dropdown controller ---\n const layerController = createLayerController({\n createPreviewOverlay: (element: Element) => {\n const overlay = createOverlay(false);\n overlay.style.zIndex = \"9998\";\n document.body.appendChild(overlay);\n positionOverlay(overlay, element);\n return overlay;\n },\n getSelectedElementId: () => selectedElementId,\n selectElement,\n onDeselect: notifyDeselection,\n });\n\n // Toggle visual edit mode\n const toggleVisualEditMode = (isEnabled: boolean) => {\n isVisualEditMode = isEnabled;\n\n if (!isEnabled) {\n resumeAnimations();\n inlineEdit.stopEditing();\n clearSelection();\n layerController.cleanup();\n handleMouseLeave();\n document.body.style.cursor = \"default\";\n\n document.removeEventListener(\"mousemove\", handleMouseMove);\n document.removeEventListener(\"mouseleave\", handleMouseLeave);\n document.removeEventListener(\"click\", handleElementClick, true);\n } else {\n document.body.style.cursor = \"crosshair\";\n stopAnimations();\n document.addEventListener(\"mousemove\", handleMouseMove);\n document.addEventListener(\"mouseleave\", handleMouseLeave);\n document.addEventListener(\"click\", handleElementClick, true);\n }\n };\n\n // Handle scroll events to update popover position\n const handleScroll = () => {\n if (selectedElementId) {\n const element = selectedElement;\n if (element && element.isConnected) {\n const rect = element.getBoundingClientRect();\n\n const viewportHeight = window.innerHeight;\n const viewportWidth = window.innerWidth;\n const isInViewport =\n rect.top < viewportHeight &&\n rect.bottom > 0 &&\n rect.left < viewportWidth &&\n rect.right > 0;\n\n const elementPosition = {\n top: rect.top,\n left: rect.left,\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n centerX: rect.left + rect.width / 2,\n centerY: rect.top + rect.height / 2,\n };\n\n window.parent.postMessage(\n {\n type: \"element-position-update\",\n position: elementPosition,\n isInViewport: isInViewport,\n visualSelectorId: selectedElementId,\n },\n \"*\"\n );\n }\n }\n };\n\n // Handle messages from parent window\n const handleMessage = (event: MessageEvent) => {\n const message = event.data;\n\n switch (message.type) {\n case \"toggle-visual-edit-mode\":\n toggleVisualEditMode(message.data.enabled);\n if (message.data.specs?.newInlineEditEnabled !== undefined) {\n inlineEdit.enabled = message.data.specs.newInlineEditEnabled;\n }\n break;\n\n case \"update-classes\":\n if (message.data && message.data.classes !== undefined) {\n updateElementClassesAndReposition(\n message.data.visualSelectorId,\n message.data.classes\n );\n } else {\n console.warn(\n \"[VisualEditAgent] Invalid update-classes message:\",\n message\n );\n }\n break;\n\n case \"update-attribute\":\n if (\n message.data &&\n message.data.visualSelectorId &&\n message.data.attribute !== undefined &&\n message.data.value !== undefined\n ) {\n updateElementAttributeAndReposition(\n message.data.visualSelectorId,\n message.data.attribute,\n message.data.value\n );\n } else {\n console.warn(\n \"[VisualEditAgent] Invalid update-attribute message:\",\n message\n );\n }\n break;\n\n case \"unselect-element\":\n unselectElement();\n break;\n\n case \"refresh-page\":\n window.location.reload();\n break;\n\n case \"update-content\":\n if (message.data && message.data.content !== undefined) {\n updateElementContent(\n message.data.visualSelectorId,\n message.data.content,\n message.data.arrIndex\n );\n } else {\n console.warn(\n \"[VisualEditAgent] Invalid update-content message:\",\n message\n );\n }\n break;\n\n case \"request-element-position\":\n if (selectedElementId && selectedElement && selectedElement.isConnected) {\n const rect = selectedElement.getBoundingClientRect();\n\n const viewportHeight = window.innerHeight;\n const viewportWidth = window.innerWidth;\n const isInViewport =\n rect.top < viewportHeight &&\n rect.bottom > 0 &&\n rect.left < viewportWidth &&\n rect.right > 0;\n\n const elementPosition = {\n top: rect.top,\n left: rect.left,\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n centerX: rect.left + rect.width / 2,\n centerY: rect.top + rect.height / 2,\n };\n\n window.parent.postMessage(\n {\n type: \"element-position-update\",\n position: elementPosition,\n isInViewport: isInViewport,\n visualSelectorId: selectedElementId,\n },\n \"*\"\n );\n }\n break;\n\n case \"popover-drag-state\":\n if (message.data && message.data.isDragging !== undefined) {\n isPopoverDragging = message.data.isDragging;\n if (message.data.isDragging) {\n clearHoverOverlays();\n }\n }\n break;\n\n case \"dropdown-state\":\n if (message.data && message.data.isOpen !== undefined) {\n isDropdownOpen = message.data.isOpen;\n if (message.data.isOpen) {\n clearHoverOverlays();\n }\n }\n break;\n\n case \"update-theme-variables\":\n if (message.data?.variables) {\n const target = message.data.mode === 'dark'\n ? document.querySelector('.dark') as HTMLElement\n : document.documentElement;\n if (target) {\n for (const [name, value] of Object.entries(message.data.variables)) {\n target.style.setProperty(name, value as string);\n }\n }\n }\n break;\n\n case \"toggle-inline-edit-mode\":\n if (message.data) {\n inlineEdit.handleToggleMessage(message.data);\n }\n break;\n\n default:\n break;\n }\n };\n\n // Handle window resize to reposition overlays\n const handleResize = () => {\n if (selectedElementId) {\n const elements = findElementsById(selectedElementId);\n selectedOverlays.forEach((overlay, index) => {\n if (index < elements.length) {\n positionOverlay(overlay, elements[index]!);\n }\n });\n }\n\n if (currentHighlightedElements.length > 0) {\n hoverOverlays.forEach((overlay, index) => {\n if (index < currentHighlightedElements.length) {\n positionOverlay(overlay, currentHighlightedElements[index]!);\n }\n });\n }\n };\n\n // Initialize: Add IDs to elements that don't have them but have linenumbers\n const elementsWithLineNumber = document.querySelectorAll(\n \"[data-linenumber]:not([data-visual-selector-id])\"\n );\n elementsWithLineNumber.forEach((el, index) => {\n const htmlEl = el as HTMLElement;\n const id = `visual-id-${htmlEl.dataset.filename}-${htmlEl.dataset.linenumber}-${index}`;\n htmlEl.dataset.visualSelectorId = id;\n });\n\n // Create mutation observer to detect layout changes\n const mutationObserver = new MutationObserver((mutations) => {\n const needsUpdate = mutations.some((mutation) => {\n const hasVisualId = (node: Node): boolean => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const el = node as HTMLElement;\n if (el.dataset && el.dataset.visualSelectorId) {\n return true;\n }\n for (let i = 0; i < el.children.length; i++) {\n if (hasVisualId(el.children[i]!)) {\n return true;\n }\n }\n }\n return false;\n };\n\n const isLayoutChange =\n mutation.type === \"attributes\" &&\n (mutation.attributeName === \"style\" ||\n mutation.attributeName === \"class\" ||\n mutation.attributeName === \"width\" ||\n mutation.attributeName === \"height\");\n\n return isLayoutChange && hasVisualId(mutation.target);\n });\n\n if (needsUpdate) {\n setTimeout(handleResize, REPOSITION_DELAY_MS);\n }\n });\n\n // Set up event listeners\n window.addEventListener(\"message\", handleMessage);\n window.addEventListener(\"scroll\", handleScroll, true);\n document.addEventListener(\"scroll\", handleScroll, true);\n window.addEventListener(\"resize\", handleResize);\n window.addEventListener(\"scroll\", handleResize);\n\n // Start observing DOM mutations\n mutationObserver.observe(document.body, {\n attributes: true,\n childList: true,\n subtree: true,\n attributeFilter: [\"style\", \"class\", \"width\", \"height\"],\n });\n\n // Send ready message to parent\n window.parent.postMessage({ type: \"visual-edit-agent-ready\" }, \"*\");\n}"],"mappings":"AAkBO,SAASA,GAAcC,EAAuBC,EAAqB,CACxE,IAAMC,EAAUD,EAAK,IAAM,GACrBE,EAAaF,EAAK,QAAU,GAC5BG,EAAcH,EAAK,OAAS,OAAO,WAAa,EAChDI,EAAWD,EAAc,MAAQ,OACjCE,EAAaF,EAAc,MAAQ,MAErCF,GAAWC,GACbH,EAAM,MAAM,IAAM,MAClBA,EAAM,MAAM,KAAOM,GACVJ,GACTF,EAAM,MAAM,IAAM,GAAGC,EAAK,OAAS,CAAC,KACpCD,EAAM,MAAM,KAAOK,IAEnBL,EAAM,MAAM,IAAM,QAClBA,EAAM,MAAM,KAAOK,EAEvB,CAGO,SAASE,EAAsBC,EAA2B,CAC/D,IAAMC,EAASD,EACf,MAAO,CAAC,EACNC,EAAO,SAAS,gBAAkBA,EAAO,SAAS,iBAEtD,CAGO,SAASC,EAAqBF,EAAiC,CACpE,IAAMC,EAASD,EACf,OACEC,EAAO,SAAS,gBAChBA,EAAO,SAAS,kBAChB,IAEJ,CAEO,IAAME,EAA+B,CAAC,KAAK,EAErCC,EAAsB,2BAG5B,SAASC,EAAiBC,EAA8B,CAC7D,GAAI,CAACA,EAAI,MAAO,CAAC,EACjB,IAAMC,EAAiB,MAAM,KAC3B,SAAS,iBAAiB,0BAA0BD,CAAE,IAAI,CAC5D,EACA,OAAIC,EAAe,OAAS,EACnBA,EAEF,MAAM,KACX,SAAS,iBAAiB,6BAA6BD,CAAE,IAAI,CAC/D,CACF,CAMO,SAASE,GAAqBC,EAAqBC,EAAuB,CAC/ED,EAAS,QAAST,GAAY,CAC5BA,EAAQ,aAAa,QAASU,CAAO,CACvC,CAAC,CACH,CAGO,SAASC,GAAuBF,EAAqBG,EAAmBC,EAAqB,CAC7FV,EAAmB,SAASS,CAAS,GAI1CH,EAAS,QAAST,GAAY,CAC5BA,EAAQ,aAAaY,EAAWC,CAAK,CACvC,CAAC,CACH,CAGO,SAASC,GAAyBd,EAAkBe,EAAqD,CAC9G,IAAMC,EAAqC,CAAC,EAC5C,QAAWC,KAAQF,EAAmB,CACpC,IAAMG,EAAMlB,EAAQ,aAAaiB,CAAI,EACjCC,IAAQ,OACVF,EAAWC,CAAI,EAAIC,EAEvB,CACA,OAAOF,CACT,CAUO,SAASG,IAAuB,CACrC,GAAI,SAAS,eAAe,mBAAmB,EAAG,OAElD,SAAS,gBAAgB,aAAa,0BAA2B,EAAE,EAEnE,IAAMC,EAAY,SAAS,cAAc,OAAO,EAChDA,EAAU,GAAK,oBACfA,EAAU,YAAc;AAAA,uCACahB,CAAmB,WAAWA,CAAmB;AAAA,uCACjDA,CAAmB,WAAWA,CAAmB;AAAA,uCACjDA,CAAmB,WAAWA,CAAmB;AAAA;AAAA;AAAA;AAAA,IAMtF,IAAMiB,EAAe,SAAS,cAAc,OAAO,EACnDA,EAAa,GAAK,wBAClBA,EAAa,YAAc;AAAA;AAAA,OAEtBjB,CAAmB,OAAOA,CAAmB;AAAA,IAGlD,IAAMkB,EAAS,SAAS,MAAQ,SAAS,gBACzCA,EAAO,YAAYF,CAAS,EAC5BE,EAAO,YAAYD,CAAY,EAE/B,SAAS,cAAc,EAAE,QAASE,GAAM,CAEtC,IAAMC,EAAcD,EAAE,QAA2B,OACjD,GAAI,EAAAC,aAAsB,SAAWA,EAAW,QAAQ,IAAIpB,CAAmB,GAAG,GAElF,GAAI,CACFmB,EAAE,OAAO,CACX,MAAQ,CACNA,EAAE,MAAM,CACV,CACF,CAAC,CACH,CAOO,SAASE,IAAyB,CACvC,IAAML,EAAY,SAAS,eAAe,mBAAmB,EACxDA,IAELA,EAAU,OAAO,EACjB,SAAS,eAAe,uBAAuB,GAAG,OAAO,EACzD,SAAS,gBAAgB,gBAAgB,yBAAyB,EAElE,SAAS,cAAc,EAAE,QAASG,GAAM,CACtC,GAAIA,EAAE,YAAc,SAClB,GAAI,CAAEA,EAAE,KAAK,CAAG,MAAQ,CAA+C,CAE3E,CAAC,EACH,CAUO,SAASG,EAAwBC,EAAWC,EAA2B,CAC5E,IAAMP,EAAe,SAAS,eAAe,uBAAuB,EAChEA,IAAcA,EAAa,SAAW,IAE1C,IAAMQ,EAAK,SAAS,iBAAiBF,EAAGC,CAAC,EAEzC,OAAIP,IAAcA,EAAa,SAAW,IAEnCQ,GAAI,QAAQ,mDAAmD,GAAK,IAC7E,CAOO,SAASC,GAAmBH,EAAWC,EAAWG,EAAiD,CACxG,IAAM/B,EAAU0B,EAAwBC,EAAGC,CAAC,EAC5C,GAAI,CAAC5B,EAAS,OAAO,KAErB,IAAMgC,EAAa9B,EAAqBF,CAAO,EAE/C,OAAIgC,IAAeD,EAA0B,KAEtCC,CACT,CC7MO,IAAMC,GAAoD,CAC/D,SAAU,WACV,gBAAiB,UACjB,OAAQ,oBACR,aAAc,MACd,UAAW,iCACX,SAAU,OACV,SAAU,QACV,UAAW,QACX,UAAW,OACX,OAAQ,QACR,QAAS,QACT,cAAe,MACjB,EAEaC,GAAoD,CAC/D,QAAS,WACT,OAAQ,UACR,MAAO,UACP,gBAAiB,cACjB,WAAY,SACZ,WAAY,MACZ,WAAY,KACd,EAEaC,EAA6B,UAC7BC,GAA0B,UAC1BC,GAAmC,MAEnCC,EAAyB,UAEzBC,GAAkB,GAGlBC,EAAoB,kLAEpBC,GAAmB,qLAEnBC,EAAe,eAEfC,GAAkB,GAElBC,EAAsB,sBAGtBC,GAAmB,EAGnBC,GAAkB,EC1CxB,SAASC,EAAYC,EAAsBC,EAAsC,CACtF,QAAWC,KAAO,OAAO,KAAKD,CAAM,EAClCD,EAAQ,MAAM,YACZE,EAAI,QAAQ,SAAWC,GAAM,IAAIA,EAAE,YAAY,CAAC,EAAE,EAClDF,EAAOC,CAAG,CACZ,CAEJ,CAGO,SAASE,GAAoBC,EAA0B,CAC5D,OAAOA,EAAM,OACf,CAEA,SAASC,EAAYN,EAAkBO,EAA2B,CAChE,IAAMC,EAAkB,CACtB,QAAAR,EACA,QAASA,EAAQ,QAAQ,YAAY,EACrC,WAAYS,EAAqBT,CAAO,CAC1C,EACA,OAAIO,IAAU,SAAWC,EAAK,MAAQD,GAC/BC,CACT,CAQO,SAASE,GACdC,EACAC,EACAC,EACa,CACb,IAAMC,EAAsB,CAAC,EAE7B,SAASC,EAAKC,EAAaC,EAA0B,CACnD,GAAI,EAAAA,EAAaL,GACjB,QAASM,EAAI,EAAGA,EAAIF,EAAG,SAAS,OAAQE,IAAK,CAC3C,IAAMC,EAAQH,EAAG,SAASE,CAAC,EAC3B,GAAIE,EAAsBD,CAAK,EAAG,CAChC,IAAMX,EAAkB,CACtB,QAASW,EACT,QAASA,EAAM,QAAQ,YAAY,EACnC,WAAYV,EAAqBU,CAAK,CACxC,EACIN,IAAe,SACjBL,EAAK,MAAQK,EAAaI,EAAa,GAEzCH,EAAO,KAAKN,CAAI,EAChBO,EAAKI,EAAOF,EAAa,CAAC,CAC5B,MACEF,EAAKI,EAAOF,CAAU,CAE1B,CACF,CAEA,OAAAF,EAAKJ,EAAQ,CAAC,EACPG,CACT,CAGA,SAASO,GAA2BC,EAAuC,CACzE,IAAMC,EAAuB,CAAC,EAC1BC,EAAUF,EAAgB,cAC9B,KACEE,GACAA,IAAY,SAAS,iBACrBA,IAAY,SAAS,MACrBD,EAAQ,OAASE,IAEbL,EAAsBI,CAAO,GAC/BD,EAAQ,KAAKjB,EAAYkB,CAAO,CAAC,EAEnCA,EAAUA,EAAQ,cAEpB,OAAAD,EAAQ,QAAQ,EACTA,CACT,CAGA,SAASG,GAAkBC,EAAoBJ,EAA8B,CAC3E,OAAAA,EAAQ,QAAQ,CAACK,EAAGV,IAAM,CACxBS,EAAM,KAAK,CAAE,GAAGC,EAAG,MAAOV,CAAE,CAAC,CAC/B,CAAC,EACMK,EAAQ,MACjB,CAGA,SAASM,GACPF,EACAL,EACAQ,EACM,CACNH,EAAM,KAAKrB,EAAYgB,EAAiBQ,CAAS,CAAC,EAClD,IAAMC,EAAcrB,GAClBY,EACAU,GACAF,EAAY,CACd,EACAH,EAAM,KAAK,GAAGI,CAAW,CAC3B,CAGA,SAASE,GAAwBV,EAAsC,CACrE,OAAOA,EAAQ,GAAG,EAAE,GAAG,SAAW,IACpC,CAGA,SAASW,GAAgBvB,EAAiBW,EAAuC,CAC/E,IAAMa,EAAWzB,GAA2BC,EAAQ,CAAC,EACrD,OAAKwB,EAAS,KAAM,GAAM,EAAE,UAAYb,CAAe,GACrDa,EAAS,KAAK7B,EAAYgB,CAAe,CAAC,EAErCa,CACT,CAGA,SAASC,GACPT,EACAQ,EACAb,EACAQ,EACM,CACN,IAAMO,EAAqB5B,EAAqBa,CAAe,EACzDgB,EAAO,IAAI,IACjB,QAAWC,KAAWJ,EACpB,GAAII,EAAQ,UAAYjB,EACtBO,GAA6BF,EAAOL,EAAiBQ,CAAS,EAC1DO,GAAoBC,EAAK,IAAID,CAAkB,MAC9C,CACL,IAAMG,EAAKD,EAAQ,WACnB,GAAIC,GAAM,KAAM,CACd,GAAIA,IAAOH,GAAsBC,EAAK,IAAIE,CAAE,EAAG,SAC/CF,EAAK,IAAIE,CAAE,CACb,CACAb,EAAM,KAAK,CAAE,GAAGY,EAAS,MAAOT,CAAU,CAAC,CAC7C,CAEJ,CAYO,SAASW,GAAgBnB,EAAuC,CACrE,IAAMC,EAAUF,GAA2BC,CAAe,EACpDK,EAAqB,CAAC,EACtBG,EAAYJ,GAAkBC,EAAOJ,CAAO,EAE5CmB,EAAcT,GAAwBV,CAAO,EACnD,GAAImB,EAAa,CACf,IAAMP,EAAWD,GAAgBQ,EAAapB,CAAe,EAC7Dc,GAA2BT,EAAOQ,EAAUb,EAAiBQ,CAAS,CACxE,MACED,GAA6BF,EAAOL,EAAiBQ,CAAS,EAGhE,OAAOH,CACT,CC1JA,IAAIgB,EAAwC,KACxCC,EAAqC,KACrCC,EAA4D,KAC5DC,EAAwC,KACxCC,EAA4D,KAEhE,SAASC,GACPC,EACAC,EACA,CAAE,SAAAC,EAAU,QAAAC,EAAS,WAAAC,CAAW,EAChB,CAChB,IAAMC,EAAO,SAAS,cAAc,KAAK,EACzCA,EAAK,YAAcC,GAAoBN,CAAK,EAC5CO,EAAYF,EAAMG,EAAyB,EAE3C,IAAMC,EAAQT,EAAM,OAAS,EAC7B,OAAIS,EAAQ,IACVJ,EAAK,MAAM,YAAc,GAAGK,GAAkBD,EAAQE,EAAe,MAGnEV,IACFI,EAAK,MAAM,MAAQO,EACnBP,EAAK,MAAM,gBAAkBQ,GAC7BR,EAAK,MAAM,WAAaS,IAG1BT,EAAK,iBAAiB,aAAc,IAAM,CACnCJ,IAAUI,EAAK,MAAM,gBAAkBU,GACxCZ,GAASA,EAAQH,CAAK,CAC5B,CAAC,EAEDK,EAAK,iBAAiB,aAAc,IAAM,CACnCJ,IAAUI,EAAK,MAAM,gBAAkB,eACxCD,GAAYA,EAAW,CAC7B,CAAC,EAEDC,EAAK,iBAAiB,QAAUW,GAAkB,CAChDA,EAAE,gBAAgB,EAClBA,EAAE,eAAe,EACjBd,EAASF,CAAK,CAChB,CAAC,EAEMK,CACT,CAGO,SAASY,GACdC,EACAC,EACAC,EACgB,CAChB,IAAMC,EAAY,SAAS,cAAc,KAAK,EAC9C,OAAAA,EAAU,aAAaC,EAAqB,MAAM,EAClDD,EAAU,aAAaE,EAAqB,MAAM,EAClDhB,EAAYc,EAAWG,EAAyB,EAEhDN,EAAO,QAASlB,GAAU,CACxB,IAAMC,EAAWD,EAAM,UAAYmB,EACnCE,EAAU,YAAYtB,GAAmBC,EAAOC,EAAUmB,CAAS,CAAC,CACtE,CAAC,EAEMC,CACT,CAGO,SAASI,GAAwBC,EAA6B,CACnE,GAAIA,EAAM,cAAc,IAAIC,CAAY,GAAG,EAAG,OAE9C,IAAMC,EAAU,SAAS,cAAc,MAAM,EAC7CA,EAAQ,aAAaD,EAAc,MAAM,EACzCC,EAAQ,MAAM,QAAU,cACxBA,EAAQ,UAAYC,EACpBH,EAAM,YAAYE,CAAO,EAEzBF,EAAM,MAAM,QAAU,cACtBA,EAAM,MAAM,WAAa,SACzBA,EAAM,MAAM,OAAS,UACrBA,EAAM,MAAM,WAAa,OACzBA,EAAM,MAAM,WAAa,SACzBA,EAAM,MAAM,cAAgB,OAC5BA,EAAM,aAAaJ,EAAqB,MAAM,EAC9CI,EAAM,aAAaH,EAAqB,MAAM,CAChD,CAEA,SAASO,GACPC,EACAb,EACAC,EACA,CAAE,SAAAjB,EAAU,QAAAC,EAAS,WAAAC,CAAW,EAC1B,CACN,IAAM4B,EAAQ,MAAM,KAAKD,EAAS,QAAQ,EACtCE,EAAef,EAAO,UAAWgB,GAAMA,EAAE,UAAYf,CAAc,EAEjEgB,EAAkBC,GAAkB,CACxC,GAAIH,GAAgB,GAAKA,EAAeD,EAAM,OAAQ,CACpD,IAAMK,EAAOL,EAAMC,CAAY,EAC3BI,EAAK,MAAM,QAAUzB,IACvByB,EAAK,MAAM,gBAAkB,cAEjC,CAEA,GADAJ,EAAeG,EACXH,GAAgB,GAAKA,EAAeD,EAAM,OAAQ,CACpD,IAAMM,EAAMN,EAAMC,CAAY,EAC1BK,EAAI,MAAM,QAAU1B,IACtB0B,EAAI,MAAM,gBAAkBvB,GAE9BuB,EAAI,eAAe,CAAE,MAAO,SAAU,CAAC,EACnCnC,GAAW8B,GAAgB,GAAKA,EAAef,EAAO,QACxDf,EAAQe,EAAOe,CAAY,CAAE,CAEjC,CACF,EAEAnC,EAAwBkB,GAAqB,CACvCA,EAAE,MAAQ,aACZA,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EAClBmB,EAAeF,EAAeD,EAAM,OAAS,EAAIC,EAAe,EAAI,CAAC,GAC5DjB,EAAE,MAAQ,WACnBA,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EAClBmB,EAAeF,EAAe,EAAIA,EAAe,EAAID,EAAM,OAAS,CAAC,GAC5DhB,EAAE,MAAQ,SAAWiB,GAAgB,GAAKA,EAAef,EAAO,SACzEF,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EACdZ,GAAYA,EAAW,EAC3BF,EAASgB,EAAOe,CAAY,CAAE,EAC9BM,EAAc,EAElB,EACA,SAAS,iBAAiB,UAAWzC,EAAsB,EAAI,CACjE,CAEA,SAAS0C,GACPT,EACAL,EACM,CACN,IAAIe,EAAY,GAChB7C,EAA2BoB,GAAkB,CAC3C,GAAIyB,EAAW,CAAEA,EAAY,GAAO,MAAQ,CAC5C,IAAMC,EAAS1B,EAAE,OACb,CAACe,EAAS,SAASW,CAAM,GAAKA,IAAWhB,GAC3Ca,EAAc,CAElB,EACA,SAAS,iBAAiB,YAAa3C,EAAyB,EAAI,CACtE,CAGO,SAAS+C,GACdjB,EACAR,EACAC,EACAC,EACM,CACNmB,EAAc,EAEd,IAAMR,EAAWd,GACfC,EACAC,EACA,CACE,GAAGC,EACH,SAAWpB,GAAU,CACfoB,EAAU,YAAYA,EAAU,WAAW,EAC/CA,EAAU,SAASpB,CAAK,EACxBuC,EAAc,CAChB,CACF,CACF,EAEMK,EAAUlB,EAAM,cACtB,GAAI,CAACkB,EAAS,OAEdb,EAAS,MAAM,IAAM,GAAGL,EAAM,UAAYA,EAAM,aAAe,CAAC,KAChEK,EAAS,MAAM,KAAO,GAAGL,EAAM,UAAU,KAEzCkB,EAAQ,YAAYb,CAAQ,EAC5BrC,EAAiBqC,EACjBpC,EAAc+B,EACd,IAAMmB,EAAYnB,EAAM,cAAc,IAAIC,CAAY,GAAG,EACrDkB,IACFA,EAAU,UAAYC,IAExBjD,EAAmBuB,EAAU,YAAc,KAE3CU,GAAwBC,EAAUb,EAAQC,EAAgBC,CAAS,EACnEoB,GAAyBT,EAAUL,CAAK,CAC1C,CAGO,SAASa,GAAsB,CACpC,IAAMM,EAAYlD,GAAa,cAAc,IAAIgC,CAAY,GAAG,EAC5DkB,IACFA,EAAU,UAAYhB,GAExBlC,EAAc,KAEVE,IACFA,EAAiB,EACjBA,EAAmB,MAGjBH,GAAkBA,EAAe,YACnCA,EAAe,OAAO,EAExBA,EAAiB,KAEbE,IACF,SAAS,oBAAoB,YAAaA,EAAyB,EAAI,EACvEA,EAA0B,MAGxBE,IACF,SAAS,oBAAoB,UAAWA,EAAsB,EAAI,EAClEA,EAAuB,KAE3B,CAGO,SAASiD,IAA0B,CACxC,OAAOrD,IAAmB,IAC5B,CCrOO,SAASsD,GAAsBC,EAAgD,CACpF,IAAIC,EAA6C,KAC7CC,EAAqD,KACrDC,EAAwC,KAEtCC,EAAoB,IAAM,CAC1BH,GAAuBA,EAAoB,YAC7CA,EAAoB,OAAO,EAE7BA,EAAsB,IACxB,EAEMI,EAAoBC,GAAqB,CAC7CF,EAAkB,EACdG,EAAqBD,EAAM,OAAO,IAAMN,EAAO,qBAAqB,IAExEC,EAAsBD,EAAO,qBAAqBM,EAAM,OAAO,EACjE,EAEME,EAAeF,GAAqB,CACxCF,EAAkB,EAClBK,EAAc,EACVP,IACF,SAAS,oBAAoB,UAAWA,EAAe,EAAI,EAC3DA,EAAgB,MAElBC,EAAsB,KAEtB,IAAMO,EAAeV,EAAO,cAAcM,EAAM,OAAO,EACvDK,EAAgBD,EAAcJ,EAAM,OAAO,CAC7C,EAEMM,EAAmB,IAAM,CACzBV,IACF,SAAS,oBAAoB,UAAWA,EAAe,EAAI,EAC3DA,EAAgB,MAEdC,IACFK,EAAYL,CAAmB,EAC/BA,EAAsB,KAE1B,EAEMU,EAAmB,CAACC,EAAeC,EAAuBC,EAAkBC,EAAqBC,IAA6B,CAClIJ,EAAE,gBAAgB,EAClBA,EAAE,eAAe,EACbK,GAAe,GACjBV,EAAc,EACdG,EAAiB,IAEjBT,EAAsB,CACpB,QAAAa,EACA,QAASA,EAAQ,QAAQ,YAAY,EACrC,WAAYE,CACd,EACAlB,EAAO,WAAW,EAElBE,EAAiBkB,GAAsB,CACjCA,EAAG,MAAQ,WACbA,EAAG,gBAAgB,EACnBX,EAAc,EACdG,EAAiB,EAErB,EACA,SAAS,iBAAiB,UAAWV,EAAe,EAAI,EAExDmB,GAAaN,EAAOE,EAAQD,EAAS,CAAE,SAAUR,EAAa,QAASH,EAAkB,WAAYD,CAAkB,CAAC,EAE5H,EAEMO,EAAkB,CACtBW,EACAN,IACG,CACH,GAAI,CAACM,EAAS,OAEd,IAAMP,EAAQO,EAAQ,cAAc,KAAK,EACzC,GAAI,CAACP,EAAO,OAEZ,IAAME,EAASM,GAAgBP,CAAO,EACtC,GAAIC,EAAO,QAAU,EAAG,OAExB,IAAMC,EAAYX,EAAqBS,CAAO,EAC9CQ,GAAwBT,CAAK,EAE7BA,EAAM,iBAAiB,QAAUD,GAAkB,CACjDD,EAAiBC,EAAGC,EAAOC,EAASC,EAAQC,CAAS,CACvD,CAAC,CACH,EAOA,MAAO,CAAE,gBAAAP,EAAiB,QALV,IAAM,CACpBP,EAAkB,EAClBK,EAAc,CAChB,CAEkC,CACpC,CC5GA,IAAMgB,EAAiB,2BAEjBC,GAAgB,CACpB,MAAO,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAC1C,OAAQ,KAAM,KAAM,IAAK,SAAU,OACrC,EAEaC,EAA4BC,GAChC,CAAC,CAACA,EAAQ,QAAQ,SAGrBC,GAA0BD,GAC1B,GAACF,GAAc,SAASE,EAAQ,QAAQ,YAAY,CAAC,GACrD,CAACA,EAAQ,aAAa,KAAK,GAC3BA,EAAQ,cAAc,yBAAyB,GAC/CA,EAAQ,UAAU,OAAS,GAIpBE,GAAwB,IAAM,CACzC,GAAI,SAAS,eAAeL,CAAc,EAAG,OAE7C,IAAMM,EAAQ,SAAS,cAAc,OAAO,EAC5CA,EAAM,GAAKN,EACXM,EAAM,YAAc;AAAA;AAAA;AAAA;AAAA,IAKpB,SAAS,KAAK,YAAYA,CAAK,CACjC,EAEaC,GAAwB,IAAM,CACzC,SAAS,eAAeP,CAAc,GAAG,OAAO,CAClD,EAEaQ,GAAcL,GAAyB,CAClD,IAAMM,EAAQ,SAAS,YAAY,EACnCA,EAAM,mBAAmBN,CAAO,EAChC,IAAMO,EAAY,OAAO,aAAa,EACtCA,GAAW,gBAAgB,EAC3BA,GAAW,SAASD,CAAK,CAC3B,EAEaE,GAAyBR,GAChC,EAAEA,aAAmB,cACrB,CAACC,GAAuBD,CAAO,EAAU,GACzCD,EAAyBC,CAAO,EAAU,GAC1CA,EAAQ,QAAQ,iBAAmB,OAI5BS,EAAgCT,GACvC,EAAEA,aAAmB,cAAgBA,EAAQ,QAAQ,WAAa,OAC7D,GAEFQ,GAAsBR,CAAO,EC9CtC,IAAMU,GAAc,IAEb,SAASC,GACdC,EACsB,CACtB,IAAIC,EAA4C,KAC5CC,EAA6D,KAC7DC,EAAU,GACRC,EAA2B,IAAI,QAI/BC,EAAqB,IAAM,CAC/B,IAAMC,EAAaN,EAAK,qBAAqB,EAC7C,GAAI,CAACM,EAAY,OACjB,IAAMC,EAAWP,EAAK,iBAAiBM,CAAU,EAChCN,EAAK,oBAAoB,EACjC,QAAQ,CAACQ,EAASC,IAAM,CAC3BA,EAAIF,EAAS,QAAUA,EAASE,CAAC,GACnCT,EAAK,gBAAgBQ,EAASD,EAASE,CAAC,CAAC,CAE7C,CAAC,CACH,EAEMC,EAAcC,GAAyB,CAC3C,IAAMC,EAAkBD,EAAQ,QAAQ,oBAClCE,EAAaF,EAAQ,YAErBG,EAAaH,EACbI,EAAOJ,EAAQ,sBAAsB,EAErCK,EAAmC,CACvC,KAAM,cACN,YAAa,CACX,QAASL,EAAQ,QACjB,QACGG,EAAW,WAA4C,SACxDH,EAAQ,WACR,GACF,iBAAkBX,EAAK,qBAAqB,EAC5C,QAASa,EACT,mBAAoBF,EAAQ,QAAQ,eACpC,iBAAkBA,EAAQ,QAAQ,iBAAmB,OACrD,WAAYA,EAAQ,QAAQ,WAC5B,SAAUA,EAAQ,QAAQ,SAC1B,SAAU,CACR,IAAKI,EAAK,IACV,KAAMA,EAAK,KACX,MAAOA,EAAK,MACZ,OAAQA,EAAK,OACb,MAAOA,EAAK,MACZ,OAAQA,EAAK,OACb,QAASA,EAAK,KAAOA,EAAK,MAAQ,EAClC,QAASA,EAAK,IAAMA,EAAK,OAAS,CACpC,CACF,EACA,gBAAAH,EACA,WAAAC,CACF,EAEII,EAAyBN,CAAO,IAClCK,EAAQ,SAAWL,EAAQ,QAAQ,SACnCK,EAAQ,gBAAkBL,EAAQ,QAAQ,gBAC1CK,EAAQ,SAAWL,EAAQ,QAAQ,UAGrC,OAAO,OAAO,YAAYK,EAAS,GAAG,EAEtCL,EAAQ,QAAQ,oBAAsBE,GAAc,EACtD,EAEMK,EAAmBP,GAAyB,CAC5CT,GAAsB,aAAaA,CAAoB,EAC3DA,EAAuB,WAAW,IAAMQ,EAAWC,CAAO,EAAGb,EAAW,CAC1E,EAEMqB,EAAeR,GAAyB,CAC5CN,EAAmB,EACnBa,EAAgBP,CAAO,CACzB,EAEMS,EAAmB,UAA6B,CACpDD,EAAY,IAAI,CAClB,EAEME,EAAgBV,GAAyB,CAC7CW,GAAsB,EAEtBX,EAAQ,QAAQ,oBAAsBA,EAAQ,aAAe,GAC7DA,EAAQ,QAAQ,eAAiBA,EAAQ,MAAM,OAC/CA,EAAQ,gBAAkB,OAC1BA,EAAQ,aAAaY,EAAqB,MAAM,EAEhD,IAAMC,EAAkB,IAAI,gBAC5BpB,EAAyB,IAAIO,EAASa,CAAe,EACrDb,EAAQ,iBAAiB,QAASS,EAAkB,CAClD,OAAQI,EAAgB,MAC1B,CAAC,EAEDb,EAAQ,MAAM,OAAS,OACvBc,GAAWd,CAAO,EAClB,WAAW,IAAM,CACXA,EAAQ,aACVA,EAAQ,MAAM,CAElB,EAAG,CAAC,CACN,EAEMe,EAAmBf,GAAyB,CAChD,IAAMa,EAAkBpB,EAAyB,IAAIO,CAAO,EACxDa,IACFA,EAAgB,MAAM,EACtBpB,EAAyB,OAAOO,CAAO,GAGpCA,EAAQ,cAEbgB,GAAsB,EACtBhB,EAAQ,gBAAkB,QAC1BA,EAAQ,gBAAgBY,CAAmB,EAC3C,OAAOZ,EAAQ,QAAQ,oBAEnBA,EAAQ,QAAQ,iBAAmB,SACrCA,EAAQ,MAAM,OAASA,EAAQ,QAAQ,eACvC,OAAOA,EAAQ,QAAQ,gBAE3B,EAIA,MAAO,CACL,IAAI,SAAU,CACZ,OAAOR,CACT,EACA,IAAI,QAAQyB,EAAgB,CAC1BzB,EAAUyB,CACZ,EAEA,WAAY,CACV,OAAO3B,IAA0B,IACnC,EAEA,mBAAoB,CAClB,OAAOA,CACT,EAEA,QAAQU,EAAkB,CACxB,OAAOkB,EAA6BlB,CAAO,CAC7C,EAEA,aAAaA,EAAsB,CACjCV,EAAwBU,EAExBX,EAAK,oBAAoB,EAAE,QAAS8B,GAAM,CACxCA,EAAE,MAAM,QAAU,MACpB,CAAC,EAEDT,EAAaV,CAAO,EAEpB,OAAO,OAAO,YACZ,CACE,KAAM,0BACN,iBAAkBX,EAAK,qBAAqB,CAC9C,EACA,GACF,CACF,EAEA,aAAc,CACZ,GAAI,CAACC,EAAuB,OAExBC,IACF,aAAaA,CAAoB,EACjCA,EAAuB,MAIzBwB,EADgBzB,CACO,EAEvBD,EAAK,oBAAoB,EAAE,QAAS8B,GAAM,CACxCA,EAAE,MAAM,QAAU,EACpB,CAAC,EAEDzB,EAAmB,EAEnB,OAAO,OAAO,YACZ,CACE,KAAM,wBACN,iBAAkBL,EAAK,qBAAqB,CAC9C,EACA,GACF,EAEAC,EAAwB,IAC1B,EAEA,qBAAqBM,EAAqB,CACxCA,EAAS,QAASwB,GAAO,CACnBA,aAAc,cAChBA,EAAG,QAAQ,SAAW,OAE1B,CAAC,CACH,EAEA,mBAAmBC,EAA0B,CACtCA,GACLhC,EAAK,iBAAiBgC,CAAS,EAAE,QAASD,GAAO,CAC3CA,aAAc,aAChB,OAAOA,EAAG,QAAQ,QAEtB,CAAC,CACH,EAEA,oBAAoBE,EAAkE,CACpF,GAAI,CAAC9B,EAAS,OAEd,IAAMI,EAAWP,EAAK,iBAAiBiC,EAAK,kBAAkB,EAC9D,GAAI1B,EAAS,SAAW,GAAK,EAAEA,EAAS,CAAC,YAAa,aAAc,OAEpE,IAAMI,EAAUJ,EAAS,CAAC,EAE1B,GAAI0B,EAAK,kBAAmB,CAC1B,GAAI,CAACJ,EAA6BlB,CAAO,EAAG,OAGxCX,EAAK,qBAAqB,IAAMiC,EAAK,qBACvC,KAAK,YAAY,EACjBjC,EAAK,eAAe,EACpB,KAAK,qBAAqBO,CAAQ,EAClCP,EAAK,wBAAwBO,EAAU0B,EAAK,kBAAkB,GAEhE,KAAK,aAAatB,CAAO,CAC3B,MACMV,IAA0BU,GAC5B,KAAK,YAAY,CAGvB,EAEA,SAAU,CACR,KAAK,YAAY,CACnB,CACF,CACF,CCxPA,IAAMuB,EAAsB,GAErB,SAASC,IAAuB,CAErC,IAAIC,EAAmB,GACnBC,EAAoB,GACpBC,EAAiB,GACjBC,EAAkC,CAAC,EACnCC,EAAqC,CAAC,EACtCC,EAAwC,CAAC,EACzCC,EAAmC,KACnCC,EAAkC,KAGhCC,EAAgB,CAACC,EAAa,KAA0B,CAC5D,IAAMC,EAAU,SAAS,cAAc,KAAK,EAC5C,OAAAA,EAAQ,MAAM,SAAW,WACzBA,EAAQ,MAAM,cAAgB,OAC9BA,EAAQ,MAAM,WAAa,uBAC3BA,EAAQ,MAAM,OAAS,OAEnBD,EACFC,EAAQ,MAAM,OAAS,qBAEvBA,EAAQ,MAAM,OAAS,oBACvBA,EAAQ,MAAM,gBAAkB,4BAG3BA,CACT,EAGMC,EAAkB,CACtBD,EACAE,EACAH,EAAa,KACV,CACH,GAAI,CAACG,GAAW,CAACZ,EAAkB,OAEfY,EAEH,YAEjB,IAAMC,EAAOD,EAAQ,sBAAsB,EAC3CF,EAAQ,MAAM,IAAM,GAAGG,EAAK,IAAM,OAAO,OAAO,KAChDH,EAAQ,MAAM,KAAO,GAAGG,EAAK,KAAO,OAAO,OAAO,KAClDH,EAAQ,MAAM,MAAQ,GAAGG,EAAK,KAAK,KACnCH,EAAQ,MAAM,OAAS,GAAGG,EAAK,MAAM,KAGrC,IAAIC,EAAQJ,EAAQ,cAAc,KAAK,EAElCI,IACHA,EAAQ,SAAS,cAAc,KAAK,EACpCA,EAAM,YAAcF,EAAQ,QAAQ,YAAY,EAChDE,EAAM,MAAM,SAAW,WACvBA,EAAM,MAAM,KAAO,OACnBA,EAAM,MAAM,QAAU,UACtBA,EAAM,MAAM,SAAW,OACvBA,EAAM,MAAM,WAAaL,EAAa,MAAQ,MAC9CK,EAAM,MAAM,MAAQL,EAAa,UAAY,UAC7CK,EAAM,MAAM,gBAAkBL,EAAa,UAAY,UACvDK,EAAM,MAAM,aAAe,MAC3BA,EAAM,MAAM,SAAW,OACvBA,EAAM,MAAM,UAAY,SACxBJ,EAAQ,YAAYI,CAAK,GAG3BC,GAAcD,EAAOD,CAAI,CAC3B,EAGMG,EAAaC,GAA2B,CAC5C,iBAAAC,EACA,qBAAsB,IAAMZ,EAC5B,oBAAqB,IAAMF,EAC3B,gBAAAO,EACA,eAAgB,IAAM,CACpBK,EAAW,mBAAmBV,CAAiB,EAC/Ca,EAAsB,EACtBb,EAAoB,KACpBC,EAAkB,IACpB,EACA,wBAAyB,CAACa,EAAUC,IAAc,CAChDD,EAAS,QAASE,GAAO,CACvB,IAAMZ,EAAUF,EAAc,EAAI,EAClC,SAAS,KAAK,YAAYE,CAAO,EACjCN,EAAiB,KAAKM,CAAO,EAC7BC,EAAgBD,EAASY,EAAI,EAAI,CACnC,CAAC,EACDhB,EAAoBe,CACtB,CACF,CAAC,EAEKE,EAAiB,IAAM,CAC3BP,EAAW,mBAAmBV,CAAiB,EAC/Ca,EAAsB,EACtBb,EAAoB,KACpBC,EAAkB,IACpB,EAGMiB,EAAqB,IAAM,CAC/BrB,EAAc,QAASO,GAAY,CAC7BA,GAAWA,EAAQ,YACrBA,EAAQ,OAAO,CAEnB,CAAC,EACDP,EAAgB,CAAC,EACjBE,EAA6B,CAAC,CAChC,EAEMc,EAAwB,IAAM,CAClCf,EAAiB,QAASM,GAAY,CAChCA,GAAWA,EAAQ,YACrBA,EAAQ,OAAO,CAEnB,CAAC,EACDN,EAAmB,CAAC,CACtB,EAEMqB,EAAY,CAAC,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,OAAQ,IAAK,OAAO,EAE1EC,EAAyBd,GAAqB,CAClD,IAAMe,EAAcf,EACdC,EAAOD,EAAQ,sBAAsB,EACrCgB,EAAahB,EACbiB,EAAgBJ,EAAU,SAASb,EAAQ,SAAS,YAAY,CAAC,EAEjEkB,EAAQH,EAAY,QAAQ,0BAA0B,EACtDI,EAAkBD,GAAO,SAAS,iBAAmB,KACrDE,EAASF,GAAO,SAAS,SACzBG,GAAmBD,GAAU,KAAO,SAASA,EAAQ,EAAE,EAAI,KAC3DE,GAAmBP,EAAY,SAAS,UAAY,KAE1D,OAAO,OAAO,YAAY,CACxB,KAAM,mBACN,QAASf,EAAQ,QACjB,QACGgB,EAAW,WAA4C,SACxDhB,EAAQ,WACR,GACF,iBAAkBuB,EAAqBvB,CAAO,EAC9C,QAASiB,EAAgBF,EAAY,UAAY,OACjD,mBAAoBA,EAAY,QAAQ,eACxC,iBAAkBA,EAAY,QAAQ,iBAAmB,OACzD,WAAYA,EAAY,QAAQ,WAChC,SAAUA,EAAY,QAAQ,SAC9B,SAAU,CACR,IAAKd,EAAK,IACV,KAAMA,EAAK,KACX,MAAOA,EAAK,MACZ,OAAQA,EAAK,OACb,MAAOA,EAAK,MACZ,OAAQA,EAAK,OACb,QAASA,EAAK,KAAOA,EAAK,MAAQ,EAClC,QAASA,EAAK,IAAMA,EAAK,OAAS,CACpC,EACA,WAAYuB,GAAyBxB,EAASyB,CAAkB,EAChE,cAAAR,EACA,gBAAAE,EACA,iBAAAE,GACA,iBAAAC,EACF,EAAG,GAAG,CACR,EAGMI,EAAiB1B,GAAiD,CACtE,IAAM2B,EAAmBJ,EAAqBvB,CAAO,EAErD,OAAAO,EAAsB,EAELD,EAAiBqB,GAAoB,IAAI,EACjD,QAASjB,GAAO,CACvB,IAAMZ,EAAUF,EAAc,EAAI,EAClC,SAAS,KAAK,YAAYE,CAAO,EACjCN,EAAiB,KAAKM,CAAO,EAC7BC,EAAgBD,EAASY,EAAI,EAAI,CACnC,CAAC,EAEDhB,EAAoBiC,GAAoB,KACxChC,EAAkBK,EAClBY,EAAmB,EACnBE,EAAsBd,CAAO,EAEtBR,EAAiB,CAAC,CAC3B,EAEMoC,EAAoB,IAAY,CACpClC,EAAoB,KACpB,OAAO,OAAO,YAAY,CAAE,KAAM,kBAAmB,EAAG,GAAG,CAC7D,EAGImC,EAAuC,KACvCC,EAAqC,KAEnCC,EAAkB,IAAM,CAC5BnB,EAAmB,EACnBiB,EAAwB,IAC1B,EAEMG,GAAsBC,GAAuB,CACjD,IAAMzB,EAAWF,EAAiB2B,CAAU,EAC5CrB,EAAmB,EAEnBJ,EAAS,QAASE,GAAO,CACvB,IAAMZ,EAAUF,EAAc,EAAK,EACnC,SAAS,KAAK,YAAYE,CAAO,EACjCP,EAAc,KAAKO,CAAO,EAC1BC,EAAgBD,EAASY,CAAE,CAC7B,CAAC,EAEDjB,EAA6Be,EAC7BqB,EAAwBI,CAC1B,EAEMC,GAAmBC,GAAkB,CACrC,CAAC/C,GAAoBC,GAAqBe,EAAW,UAAU,GAE/D0B,IAAwB,OAC5BA,EAAsB,sBAAsB,IAAM,CAGhD,GAFAA,EAAsB,KAElBxC,EAAgB,CAAEyC,EAAgB,EAAG,MAAQ,CAEjD,IAAME,EAAaG,GAAmBD,EAAE,QAASA,EAAE,QAASzC,CAAiB,EAC7E,GAAI,CAACuC,EAAY,CAAEF,EAAgB,EAAG,MAAQ,CAC1CF,IAA0BI,GAE9BD,GAAmBC,CAAU,CAC/B,CAAC,EACH,EAGMI,EAAmB,IAAM,CACzBP,IAAwB,OAC1B,qBAAqBA,CAAmB,EACxCA,EAAsB,MAExBC,EAAgB,CAClB,EAGMO,GAAsBH,GAAkB,CAC5C,GAAI,CAAC/C,EAAkB,OAEvB,IAAMmD,EAASJ,EAAE,OAOjB,GAJII,EAAO,QAAQ,IAAIC,CAAmB,GAAG,GAIzCpC,EAAW,SAAWmC,aAAkB,aAAeA,EAAO,kBAAoB,OACpF,OAIF,GAAInC,EAAW,UAAU,EAAG,CAC1B+B,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EAClBA,EAAE,yBAAyB,EAC3B/B,EAAW,YAAY,EACvB,MACF,CAGA,GAAId,EAAgB,CAClB6C,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EAClBA,EAAE,yBAAyB,EAE3B,OAAO,OAAO,YAAY,CAAE,KAAM,iBAAkB,EAAG,GAAG,EAC1D,MACF,CAGAA,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EAClBA,EAAE,yBAAyB,EAE3B,IAAMnC,EAAUyC,EAAwBN,EAAE,QAASA,EAAE,OAAO,EAC5D,GAAI,CAACnC,EACH,OAGF,IAAMe,EAAcf,EACd2B,EAAmBJ,EAAqBvB,CAAO,EAMrD,GAHEN,IAAsBiC,GACtBZ,EAAY,QAAQ,WAAa,QAEVX,EAAW,SAAWA,EAAW,QAAQW,CAAW,EAAG,CAC9EX,EAAW,aAAaW,CAAW,EACnC,MACF,CAEAX,EAAW,YAAY,EAEnBA,EAAW,SACbA,EAAW,qBAAqBE,EAAiBqB,CAAgB,CAAC,EAGpE,IAAMe,EAAkBhB,EAAc1B,CAAO,EAC7C2C,GAAgB,gBAAgBD,EAAiB1C,CAAO,CAC1D,EAEM4C,GAAkB,IAAM,CAC5BxC,EAAW,YAAY,EACvBO,EAAe,CACjB,EAEMkC,GAAoC,CAAClB,EAA0BmB,IAAoB,CACvF,IAAMtC,EAAWF,EAAiBqB,CAAgB,EAC9CnB,EAAS,SAAW,IAExBuC,GAAqBvC,EAAUsC,CAAO,EAGtC,WAAW,IAAM,CAEXpD,IAAsBiC,GACxBnC,EAAiB,QAAQ,CAACM,EAASkD,IAAU,CACvCA,EAAQxC,EAAS,QACnBT,EAAgBD,EAASU,EAASwC,CAAK,CAAE,CAE7C,CAAC,EAICvD,EAA2B,OAAS,GACfA,EAA2B,CAAC,GACjB,SAAS,mBACzBkC,GAChBpC,EAAc,QAAQ,CAACO,EAASkD,IAAU,CACpCA,EAAQvD,EAA2B,QACrCM,EAAgBD,EAASL,EAA2BuD,CAAK,CAAE,CAE/D,CAAC,CAGP,EAAG9D,CAAmB,EACxB,EAGM+D,GAAsC,CAC1CtB,EACAuB,EACAC,IACG,CACH,IAAM3C,EAAWF,EAAiBqB,CAAgB,EAC9CnB,EAAS,SAAW,IAExB4C,GAAuB5C,EAAU0C,EAAWC,CAAK,EAGjD,WAAW,IAAM,CACXzD,IAAsBiC,GACxBnC,EAAiB,QAAQ,CAACM,EAASkD,IAAU,CACvCA,EAAQxC,EAAS,QACnBT,EAAgBD,EAASU,EAASwC,CAAK,CAAE,CAE7C,CAAC,CAEL,EAAG9D,CAAmB,EACxB,EAEMmE,GAAuB,CAAC1B,EAA0B2B,EAAiBC,IAAsB,CAC7F,IAAI/C,EAAWF,EAAiBqB,CAAgB,EAE5CnB,EAAS,SAAW,IAIpB+C,GAAY,OACd/C,EAAWA,EAAS,OACjBE,GAAQA,EAAmB,QAAQ,WAAa,OAAO6C,CAAQ,CAClE,GAGF/C,EAAS,QAASR,GAAY,CAC3BA,EAAwB,UAAYsD,CACvC,CAAC,EAED,WAAW,IAAM,CACX5D,IAAsBiC,GACxBnC,EAAiB,QAAQ,CAACM,EAASkD,IAAU,CACvCA,EAAQxC,EAAS,QACnBT,EAAgBD,EAASU,EAASwC,CAAK,CAAE,CAE7C,CAAC,CAEL,EAAG9D,CAAmB,EACxB,EAGMyD,GAAkBa,GAAsB,CAC5C,qBAAuBxD,GAAqB,CAC1C,IAAMF,EAAUF,EAAc,EAAK,EACnC,OAAAE,EAAQ,MAAM,OAAS,OACvB,SAAS,KAAK,YAAYA,CAAO,EACjCC,EAAgBD,EAASE,CAAO,EACzBF,CACT,EACA,qBAAsB,IAAMJ,EAC5B,cAAAgC,EACA,WAAYE,CACd,CAAC,EAGK6B,GAAwBC,GAAuB,CACnDtE,EAAmBsE,EAEdA,GAYH,SAAS,KAAK,MAAM,OAAS,YAC7BC,GAAe,EACf,SAAS,iBAAiB,YAAazB,EAAe,EACtD,SAAS,iBAAiB,aAAcG,CAAgB,EACxD,SAAS,iBAAiB,QAASC,GAAoB,EAAI,IAf3DsB,GAAiB,EACjBxD,EAAW,YAAY,EACvBO,EAAe,EACfgC,GAAgB,QAAQ,EACxBN,EAAiB,EACjB,SAAS,KAAK,MAAM,OAAS,UAE7B,SAAS,oBAAoB,YAAaH,EAAe,EACzD,SAAS,oBAAoB,aAAcG,CAAgB,EAC3D,SAAS,oBAAoB,QAASC,GAAoB,EAAI,EAQlE,EAGMuB,GAAe,IAAM,CACzB,GAAInE,EAAmB,CACrB,IAAMM,EAAUL,EAChB,GAAIK,GAAWA,EAAQ,YAAa,CAClC,IAAMC,EAAOD,EAAQ,sBAAsB,EAErC8D,EAAiB,OAAO,YACxBC,EAAgB,OAAO,WACvBC,EACJ/D,EAAK,IAAM6D,GACX7D,EAAK,OAAS,GACdA,EAAK,KAAO8D,GACZ9D,EAAK,MAAQ,EAETgE,EAAkB,CACtB,IAAKhE,EAAK,IACV,KAAMA,EAAK,KACX,MAAOA,EAAK,MACZ,OAAQA,EAAK,OACb,MAAOA,EAAK,MACZ,OAAQA,EAAK,OACb,QAASA,EAAK,KAAOA,EAAK,MAAQ,EAClC,QAASA,EAAK,IAAMA,EAAK,OAAS,CACpC,EAEA,OAAO,OAAO,YACZ,CACE,KAAM,0BACN,SAAUgE,EACV,aAAcD,EACd,iBAAkBtE,CACpB,EACA,GACF,CACF,CACF,CACF,EAGMwE,GAAiBC,GAAwB,CAC7C,IAAMC,EAAUD,EAAM,KAEtB,OAAQC,EAAQ,KAAM,CACpB,IAAK,0BACHX,GAAqBW,EAAQ,KAAK,OAAO,EACrCA,EAAQ,KAAK,OAAO,uBAAyB,SAC/ChE,EAAW,QAAUgE,EAAQ,KAAK,MAAM,sBAE1C,MAEF,IAAK,iBACCA,EAAQ,MAAQA,EAAQ,KAAK,UAAY,OAC3CvB,GACEuB,EAAQ,KAAK,iBACbA,EAAQ,KAAK,OACf,EAEA,QAAQ,KACN,oDACAA,CACF,EAEF,MAEF,IAAK,mBAEDA,EAAQ,MACRA,EAAQ,KAAK,kBACbA,EAAQ,KAAK,YAAc,QAC3BA,EAAQ,KAAK,QAAU,OAEvBnB,GACEmB,EAAQ,KAAK,iBACbA,EAAQ,KAAK,UACbA,EAAQ,KAAK,KACf,EAEA,QAAQ,KACN,sDACAA,CACF,EAEF,MAEF,IAAK,mBACHxB,GAAgB,EAChB,MAEF,IAAK,eACH,OAAO,SAAS,OAAO,EACvB,MAEF,IAAK,iBACCwB,EAAQ,MAAQA,EAAQ,KAAK,UAAY,OAC3Cf,GACEe,EAAQ,KAAK,iBACbA,EAAQ,KAAK,QACbA,EAAQ,KAAK,QACf,EAEA,QAAQ,KACN,oDACAA,CACF,EAEF,MAEF,IAAK,2BACH,GAAI1E,GAAqBC,GAAmBA,EAAgB,YAAa,CACvE,IAAMM,EAAON,EAAgB,sBAAsB,EAE7CmE,EAAiB,OAAO,YACxBC,EAAgB,OAAO,WACvBC,EACJ/D,EAAK,IAAM6D,GACX7D,EAAK,OAAS,GACdA,EAAK,KAAO8D,GACZ9D,EAAK,MAAQ,EAETgE,EAAkB,CACtB,IAAKhE,EAAK,IACV,KAAMA,EAAK,KACX,MAAOA,EAAK,MACZ,OAAQA,EAAK,OACb,MAAOA,EAAK,MACZ,OAAQA,EAAK,OACb,QAASA,EAAK,KAAOA,EAAK,MAAQ,EAClC,QAASA,EAAK,IAAMA,EAAK,OAAS,CACpC,EAEA,OAAO,OAAO,YACZ,CACE,KAAM,0BACN,SAAUgE,EACV,aAAcD,EACd,iBAAkBtE,CACpB,EACA,GACF,CACF,CACA,MAEF,IAAK,qBACC0E,EAAQ,MAAQA,EAAQ,KAAK,aAAe,SAC9C/E,EAAoB+E,EAAQ,KAAK,WAC7BA,EAAQ,KAAK,YACfxD,EAAmB,GAGvB,MAEF,IAAK,iBACCwD,EAAQ,MAAQA,EAAQ,KAAK,SAAW,SAC1C9E,EAAiB8E,EAAQ,KAAK,OAC1BA,EAAQ,KAAK,QACfxD,EAAmB,GAGvB,MAEF,IAAK,yBACH,GAAIwD,EAAQ,MAAM,UAAW,CAC3B,IAAM7B,EAAS6B,EAAQ,KAAK,OAAS,OACjC,SAAS,cAAc,OAAO,EAC9B,SAAS,gBACb,GAAI7B,EACF,OAAW,CAAC8B,EAAMlB,CAAK,IAAK,OAAO,QAAQiB,EAAQ,KAAK,SAAS,EAC/D7B,EAAO,MAAM,YAAY8B,EAAMlB,CAAe,CAGpD,CACA,MAEF,IAAK,0BACCiB,EAAQ,MACVhE,EAAW,oBAAoBgE,EAAQ,IAAI,EAE7C,MAEF,QACE,KACJ,CACF,EAGME,EAAe,IAAM,CACzB,GAAI5E,EAAmB,CACrB,IAAMc,EAAWF,EAAiBZ,CAAiB,EACnDF,EAAiB,QAAQ,CAACM,EAASkD,IAAU,CACvCA,EAAQxC,EAAS,QACnBT,EAAgBD,EAASU,EAASwC,CAAK,CAAE,CAE7C,CAAC,CACH,CAEIvD,EAA2B,OAAS,GACtCF,EAAc,QAAQ,CAACO,EAASkD,IAAU,CACpCA,EAAQvD,EAA2B,QACrCM,EAAgBD,EAASL,EAA2BuD,CAAK,CAAE,CAE/D,CAAC,CAEL,EAG+B,SAAS,iBACtC,kDACF,EACuB,QAAQ,CAACtC,EAAIsC,IAAU,CAC5C,IAAMuB,EAAS7D,EACT8D,EAAK,aAAaD,EAAO,QAAQ,QAAQ,IAAIA,EAAO,QAAQ,UAAU,IAAIvB,CAAK,GACrFuB,EAAO,QAAQ,iBAAmBC,CACpC,CAAC,EAGD,IAAMC,GAAmB,IAAI,iBAAkBC,GAAc,CACvCA,EAAU,KAAMC,GAAa,CAC/C,IAAMC,EAAeC,GAAwB,CAC3C,GAAIA,EAAK,WAAa,KAAK,aAAc,CACvC,IAAMnE,EAAKmE,EACX,GAAInE,EAAG,SAAWA,EAAG,QAAQ,iBAC3B,MAAO,GAET,QAASoE,EAAI,EAAGA,EAAIpE,EAAG,SAAS,OAAQoE,IACtC,GAAIF,EAAYlE,EAAG,SAASoE,CAAC,CAAE,EAC7B,MAAO,EAGb,CACA,MAAO,EACT,EASA,OANEH,EAAS,OAAS,eACjBA,EAAS,gBAAkB,SAC1BA,EAAS,gBAAkB,SAC3BA,EAAS,gBAAkB,SAC3BA,EAAS,gBAAkB,WAENC,EAAYD,EAAS,MAAM,CACtD,CAAC,GAGC,WAAWL,EAAcpF,CAAmB,CAEhD,CAAC,EAGD,OAAO,iBAAiB,UAAWgF,EAAa,EAChD,OAAO,iBAAiB,SAAUL,GAAc,EAAI,EACpD,SAAS,iBAAiB,SAAUA,GAAc,EAAI,EACtD,OAAO,iBAAiB,SAAUS,CAAY,EAC9C,OAAO,iBAAiB,SAAUA,CAAY,EAG9CG,GAAiB,QAAQ,SAAS,KAAM,CACtC,WAAY,GACZ,UAAW,GACX,QAAS,GACT,gBAAiB,CAAC,QAAS,QAAS,QAAS,QAAQ,CACvD,CAAC,EAGD,OAAO,OAAO,YAAY,CAAE,KAAM,yBAA0B,EAAG,GAAG,CACpE","names":["positionLabel","label","rect","nearTop","tallEnough","isFullWidth","edgeLeft","insideLeft","isInstrumentedElement","element","htmlEl","getElementSelectorId","ALLOWED_ATTRIBUTES","PLUGIN_ELEMENT_ATTR","findElementsById","id","sourceElements","updateElementClasses","elements","classes","updateElementAttribute","attribute","value","collectAllowedAttributes","allowedAttributes","attributes","attr","val","stopAnimations","animStyle","pointerStyle","target","a","animTarget","resumeAnimations","findInstrumentedElement","x","y","el","resolveHoverTarget","selectedElementId","selectorId","DROPDOWN_CONTAINER_STYLES","DROPDOWN_ITEM_BASE_STYLES","DROPDOWN_ITEM_ACTIVE_COLOR","DROPDOWN_ITEM_ACTIVE_BG","DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT","DROPDOWN_ITEM_HOVER_BG","DEPTH_INDENT_PX","CHEVRON_COLLAPSED","CHEVRON_EXPANDED","CHEVRON_ATTR","BASE_PADDING_PX","LAYER_DROPDOWN_ATTR","MAX_PARENT_DEPTH","MAX_CHILD_DEPTH","applyStyles","element","styles","key","m","getLayerDisplayName","layer","toLayerInfo","depth","info","getElementSelectorId","getInstrumentedDescendants","parent","maxDepth","startDepth","result","walk","el","instrDepth","i","child","isInstrumentedElement","collectInstrumentedParents","selectedElement","parents","current","MAX_PARENT_DEPTH","addParentsToChain","chain","p","addSelfAndDescendantsToChain","selfDepth","descendants","MAX_CHILD_DEPTH","getImmediateInstrParent","collectSiblings","siblings","appendSiblingsWithSelected","selectedSelectorId","seen","sibling","id","buildLayerChain","instrParent","activeDropdown","activeLabel","outsideMousedownHandler","activeOnHoverEnd","activeKeydownHandler","createDropdownItem","layer","isActive","onSelect","onHover","onHoverEnd","item","getLayerDisplayName","applyStyles","DROPDOWN_ITEM_BASE_STYLES","depth","BASE_PADDING_PX","DEPTH_INDENT_PX","DROPDOWN_ITEM_ACTIVE_COLOR","DROPDOWN_ITEM_ACTIVE_BG","DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT","DROPDOWN_ITEM_HOVER_BG","e","createDropdownElement","layers","currentElement","callbacks","container","LAYER_DROPDOWN_ATTR","PLUGIN_ELEMENT_ATTR","DROPDOWN_CONTAINER_STYLES","enhanceLabelWithChevron","label","CHEVRON_ATTR","chevron","CHEVRON_COLLAPSED","setupKeyboardNavigation","dropdown","items","focusedIndex","l","setFocusedItem","index","prev","cur","closeDropdown","setupOutsideClickHandler","skipFirst","target","showDropdown","overlay","chevronEl","CHEVRON_EXPANDED","isDropdownOpen","createLayerController","config","layerPreviewOverlay","escapeHandler","dropdownSourceLayer","clearLayerPreview","showLayerPreview","layer","getElementSelectorId","selectLayer","closeDropdown","firstOverlay","attachToOverlay","restoreSelection","handleLabelClick","e","label","element","layers","currentId","isDropdownOpen","ev","showDropdown","overlay","buildLayerChain","enhanceLabelWithChevron","FOCUS_STYLE_ID","EDITABLE_TAGS","isStaticArrayTextElement","element","passesStructuralChecks","injectFocusOutlineCSS","style","removeFocusOutlineCSS","selectText","range","selection","isEditableTextElement","shouldEnterInlineEditingMode","DEBOUNCE_MS","createInlineEditController","host","currentEditingElement","debouncedSendTimeout","enabled","listenerAbortControllers","repositionOverlays","selectedId","elements","overlay","i","reportEdit","element","originalContent","newContent","svgElement","rect","message","isStaticArrayTextElement","debouncedReport","onTextInput","handleInputEvent","makeEditable","injectFocusOutlineCSS","PLUGIN_ELEMENT_ATTR","abortController","selectText","makeNonEditable","removeFocusOutlineCSS","value","shouldEnterInlineEditingMode","o","el","elementId","data","REPOSITION_DELAY_MS","setupVisualEditAgent","isVisualEditMode","isPopoverDragging","isDropdownOpen","hoverOverlays","selectedOverlays","currentHighlightedElements","selectedElementId","selectedElement","createOverlay","isSelected","overlay","positionOverlay","element","rect","label","positionLabel","inlineEdit","createInlineEditController","findElementsById","clearSelectedOverlays","elements","elementId","el","clearSelection","clearHoverOverlays","TEXT_TAGS","notifyElementSelected","htmlElement","svgElement","isTextElement","arrEl","staticArrayName","rawIdx","staticArrayIndex","staticArrayField","getElementSelectorId","collectAllowedAttributes","ALLOWED_ATTRIBUTES","selectElement","visualSelectorId","notifyDeselection","lastHoveredSelectorId","pendingMouseMoveRaf","clearHoverState","applyHoverOverlays","selectorId","handleMouseMove","e","resolveHoverTarget","handleMouseLeave","handleElementClick","target","LAYER_DROPDOWN_ATTR","findInstrumentedElement","selectedOverlay","layerController","unselectElement","updateElementClassesAndReposition","classes","updateElementClasses","index","updateElementAttributeAndReposition","attribute","value","updateElementAttribute","updateElementContent","content","arrIndex","createLayerController","toggleVisualEditMode","isEnabled","stopAnimations","resumeAnimations","handleScroll","viewportHeight","viewportWidth","isInViewport","elementPosition","handleMessage","event","message","name","handleResize","htmlEl","id","mutationObserver","mutations","mutation","hasVisualId","node","i"]}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAGA,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAAE,EAClB,IAAI,EAAE,MAAM,GACX,MAAM,EAAE,CAmBV"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
export function filterPackagesInProject(packages, root) {
|
|
4
|
+
try {
|
|
5
|
+
const packageJsonPath = join(root, "package.json");
|
|
6
|
+
if (!existsSync(packageJsonPath)) {
|
|
7
|
+
return [];
|
|
8
|
+
}
|
|
9
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
10
|
+
const allDeps = {
|
|
11
|
+
...packageJson.dependencies,
|
|
12
|
+
...packageJson.devDependencies,
|
|
13
|
+
...packageJson.peerDependencies,
|
|
14
|
+
};
|
|
15
|
+
return packages.filter((pkg) => pkg in allDeps);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
console.warn("Failed to read project package.json:", error);
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,MAAM,UAAU,uBAAuB,CACrC,QAAkB,EAClB,IAAY;IAEZ,IAAI,CAAC;QACH,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;QACvE,MAAM,OAAO,GAAG;YACd,GAAG,WAAW,CAAC,YAAY;YAC3B,GAAG,WAAW,CAAC,eAAe;YAC9B,GAAG,WAAW,CAAC,gBAAgB;SAChC,CAAC;QAEF,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,OAAO,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;QAC5D,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visual-edit-plugin.d.ts","sourceRoot":"","sources":["../src/visual-edit-plugin.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAInC,wBAAgB,gBAAgB,IAwEzB,MAAM,CACZ"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { parse } from "@babel/parser";
|
|
2
|
+
import { default as traverse } from "@babel/traverse";
|
|
3
|
+
import { default as generate } from "@babel/generator";
|
|
4
|
+
import * as t from "@babel/types";
|
|
5
|
+
import { JSXProcessor } from "./jsx-processor.js";
|
|
6
|
+
import { JSXUtils } from "./jsx-utils.js";
|
|
7
|
+
export function visualEditPlugin() {
|
|
8
|
+
return {
|
|
9
|
+
name: "visual-edit-transform",
|
|
10
|
+
apply: (config) => config.mode === "development",
|
|
11
|
+
enforce: "pre",
|
|
12
|
+
order: "pre",
|
|
13
|
+
transformIndexHtml(html) {
|
|
14
|
+
const tailwindScript = ` <!-- Tailwind CSS CDN for visual editing -->\n <script src="https://cdn.tailwindcss.com"></script>\n `;
|
|
15
|
+
return html.replace("</head>", tailwindScript + "</head>");
|
|
16
|
+
},
|
|
17
|
+
transform(code, id) {
|
|
18
|
+
if (id.includes("node_modules") || id.includes("visual-edit-agent")) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
if (!id.match(/\.(jsx?|tsx?)$/)) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const filename = extractFilename(id);
|
|
25
|
+
try {
|
|
26
|
+
const ast = parse(code, {
|
|
27
|
+
sourceType: "module",
|
|
28
|
+
plugins: [
|
|
29
|
+
"jsx",
|
|
30
|
+
"typescript",
|
|
31
|
+
"decorators-legacy",
|
|
32
|
+
"classProperties",
|
|
33
|
+
"objectRestSpread",
|
|
34
|
+
"functionBind",
|
|
35
|
+
"exportDefaultFrom",
|
|
36
|
+
"exportNamespaceFrom",
|
|
37
|
+
"dynamicImport",
|
|
38
|
+
"nullishCoalescingOperator",
|
|
39
|
+
"optionalChaining",
|
|
40
|
+
"asyncGenerators",
|
|
41
|
+
"bigInt",
|
|
42
|
+
"optionalCatchBinding",
|
|
43
|
+
"throwExpressions",
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
JSXUtils.init(t);
|
|
47
|
+
const processor = new JSXProcessor(t, filename);
|
|
48
|
+
traverse.default(ast, {
|
|
49
|
+
JSXElement(path) {
|
|
50
|
+
const jsxElement = path.node;
|
|
51
|
+
if (t.isJSXFragment(jsxElement))
|
|
52
|
+
return;
|
|
53
|
+
processor.processJSXElement(path.get("openingElement"));
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
const result = generate.default(ast, {
|
|
57
|
+
compact: false,
|
|
58
|
+
concise: false,
|
|
59
|
+
retainLines: true,
|
|
60
|
+
});
|
|
61
|
+
return {
|
|
62
|
+
code: result.code,
|
|
63
|
+
map: null,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error("Failed to add source location to JSX:", error);
|
|
68
|
+
return {
|
|
69
|
+
code: code,
|
|
70
|
+
map: null,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function extractFilename(id) {
|
|
77
|
+
const pathParts = id.split("/");
|
|
78
|
+
const segmentIndex = findSegmentIndex(pathParts, ["pages", "components"]);
|
|
79
|
+
if (segmentIndex >= 0 && segmentIndex < pathParts.length - 1) {
|
|
80
|
+
const relevantParts = pathParts.slice(segmentIndex);
|
|
81
|
+
const last = relevantParts[relevantParts.length - 1];
|
|
82
|
+
relevantParts[relevantParts.length - 1] = stripExtension(last ?? "");
|
|
83
|
+
return relevantParts.join("/");
|
|
84
|
+
}
|
|
85
|
+
const lastPart = pathParts[pathParts.length - 1] ?? "";
|
|
86
|
+
return stripExtension(lastPart);
|
|
87
|
+
}
|
|
88
|
+
function findSegmentIndex(parts, segments) {
|
|
89
|
+
for (const segment of segments) {
|
|
90
|
+
const idx = parts.findIndex((part) => part === segment);
|
|
91
|
+
if (idx >= 0)
|
|
92
|
+
return idx;
|
|
93
|
+
}
|
|
94
|
+
return -1;
|
|
95
|
+
}
|
|
96
|
+
function stripExtension(filename) {
|
|
97
|
+
const dotIndex = filename.indexOf(".");
|
|
98
|
+
return dotIndex >= 0 ? filename.substring(0, dotIndex) : filename;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=visual-edit-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visual-edit-plugin.js","sourceRoot":"","sources":["../src/visual-edit-plugin.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@depup/base44__vite-plugin",
|
|
3
|
+
"version": "1.0.4-depup.0",
|
|
4
|
+
"description": "[DepUp] The Vite plugin for base44 based applications",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./dist/index.js",
|
|
9
|
+
"./bridge": "./dist/bridge.js",
|
|
10
|
+
"./compat/*": "./compat/*"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"src",
|
|
15
|
+
"compat",
|
|
16
|
+
"changes.json",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"build:bridge": "tsup",
|
|
22
|
+
"validate-exports": "node scripts/validate-exports.mjs",
|
|
23
|
+
"dev": "node dev-server.js",
|
|
24
|
+
"test:unit": "vitest run"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/babel__generator": "^7.27.0",
|
|
28
|
+
"@types/babel__traverse": "^7.28.0",
|
|
29
|
+
"@types/node": "^24.6.2",
|
|
30
|
+
"cors": "^2.8.5",
|
|
31
|
+
"express": "^4.21.2",
|
|
32
|
+
"jsdom": "^26.0.0",
|
|
33
|
+
"tsup": "^8.1.0",
|
|
34
|
+
"typescript": "^5.9.3",
|
|
35
|
+
"vite": "^7.1.9",
|
|
36
|
+
"vitest": "^3.0.0"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@babel/generator": "^7.29.1",
|
|
40
|
+
"@babel/parser": "^7.29.2",
|
|
41
|
+
"@babel/traverse": "^7.29.0",
|
|
42
|
+
"@babel/types": "^7.29.0"
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"depup",
|
|
46
|
+
"dependency-bumped",
|
|
47
|
+
"updated-deps",
|
|
48
|
+
"@base44/vite-plugin"
|
|
49
|
+
],
|
|
50
|
+
"depup": {
|
|
51
|
+
"changes": {
|
|
52
|
+
"@babel/generator": {
|
|
53
|
+
"from": "^7.28.5",
|
|
54
|
+
"to": "^7.29.1"
|
|
55
|
+
},
|
|
56
|
+
"@babel/parser": {
|
|
57
|
+
"from": "^7.28.5",
|
|
58
|
+
"to": "^7.29.2"
|
|
59
|
+
},
|
|
60
|
+
"@babel/traverse": {
|
|
61
|
+
"from": "^7.28.5",
|
|
62
|
+
"to": "^7.29.0"
|
|
63
|
+
},
|
|
64
|
+
"@babel/types": {
|
|
65
|
+
"from": "^7.28.5",
|
|
66
|
+
"to": "^7.29.0"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"depsUpdated": 4,
|
|
70
|
+
"originalPackage": "@base44/vite-plugin",
|
|
71
|
+
"originalVersion": "1.0.4",
|
|
72
|
+
"processedAt": "2026-03-17T16:30:55.430Z",
|
|
73
|
+
"smokeTest": "failed"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
|
|
3
|
+
// Make HTMLElement available in non-browser environments
|
|
4
|
+
const { HTMLElement = class {} } = globalThis;
|
|
5
|
+
|
|
6
|
+
export class ErrorOverlay extends HTMLElement {
|
|
7
|
+
static getOverlayHTML() {
|
|
8
|
+
return `
|
|
9
|
+
<div>
|
|
10
|
+
</div>
|
|
11
|
+
`;
|
|
12
|
+
}
|
|
13
|
+
close() {
|
|
14
|
+
(this as any).parentNode?.removeChild(this);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static sendErrorToParent(
|
|
18
|
+
error: Error,
|
|
19
|
+
title: string,
|
|
20
|
+
details: string | undefined,
|
|
21
|
+
componentName: string | undefined
|
|
22
|
+
) {
|
|
23
|
+
// Send error to parent using framewire
|
|
24
|
+
if (globalThis.window?.parent) {
|
|
25
|
+
try {
|
|
26
|
+
globalThis.window.parent?.postMessage(
|
|
27
|
+
{
|
|
28
|
+
type: "app_error",
|
|
29
|
+
error: { title, details, componentName, originalError: error, stack: error?.stack },
|
|
30
|
+
},
|
|
31
|
+
"*"
|
|
32
|
+
);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.warn(
|
|
35
|
+
"Failed to send error to iframe parent:",
|
|
36
|
+
(error as Error)?.message
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
constructor(error: Error) {
|
|
43
|
+
super();
|
|
44
|
+
|
|
45
|
+
const stack = error?.stack;
|
|
46
|
+
let componentName = stack?.match(/at\s+(\w+)\s+\(eval/)?.[1];
|
|
47
|
+
if (componentName === "eval") {
|
|
48
|
+
componentName = undefined;
|
|
49
|
+
}
|
|
50
|
+
const title = componentName
|
|
51
|
+
? `in ${componentName}: ${error.message?.toString()}`
|
|
52
|
+
: error.message?.toString();
|
|
53
|
+
const details = error?.stack;
|
|
54
|
+
|
|
55
|
+
// Call editor frame with the error (via post message)
|
|
56
|
+
ErrorOverlay.sendErrorToParent(error, title, details, componentName);
|
|
57
|
+
|
|
58
|
+
// Create the overlay element using HTML template
|
|
59
|
+
const overlay = document.createElement("div");
|
|
60
|
+
overlay.innerHTML = ErrorOverlay.getOverlayHTML();
|
|
61
|
+
|
|
62
|
+
// Add to DOM
|
|
63
|
+
document.body.appendChild(overlay);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// vite/react-plugin transpiles classes with _SomeClass, so we need to replace all _ErrorOverlay with ErrorOverlay
|
|
68
|
+
export const errorOverlayCode = ErrorOverlay.toString().replaceAll(
|
|
69
|
+
"_ErrorOverlay",
|
|
70
|
+
"ErrorOverlay"
|
|
71
|
+
);
|
package/src/bridge.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox bridge — bundled via tsup into dist/statics/index.mjs.
|
|
3
|
+
* Only the visual edit agent needs the bridge (for local dev iteration
|
|
4
|
+
* via ?sandbox-bridge=local). All other features load as individual
|
|
5
|
+
* sync script tags from node_modules.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export { setupVisualEditAgent } from "./injections/visual-edit-agent.js";
|