@1agh/maude 0.60.4 → 0.60.6

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.
Files changed (34) hide show
  1. package/apps/studio/annotations-layer.tsx +21 -12
  2. package/apps/studio/api.ts +54 -5
  3. package/apps/studio/build.ts +10 -0
  4. package/apps/studio/canvas-comment-mount.tsx +7 -1
  5. package/apps/studio/canvas-icons.tsx +30 -2
  6. package/apps/studio/canvas-lib.tsx +41 -6
  7. package/apps/studio/canvas-shell.tsx +39 -43
  8. package/apps/studio/client/app.jsx +20 -13
  9. package/apps/studio/dist/client.bundle.js +1 -1
  10. package/apps/studio/dist/comment-mount.js +2 -2
  11. package/apps/studio/dom-selection.ts +67 -0
  12. package/apps/studio/hmr-broadcast.ts +40 -2
  13. package/apps/studio/input-router.tsx +26 -2
  14. package/apps/studio/sync/agent.ts +64 -13
  15. package/apps/studio/sync/codec.ts +47 -0
  16. package/apps/studio/sync/cold-start.ts +96 -0
  17. package/apps/studio/sync/migrate-seed.ts +52 -7
  18. package/apps/studio/sync/projection.ts +10 -1
  19. package/apps/studio/test/canvas-meta-api.test.ts +114 -3
  20. package/apps/studio/test/canvas-wheel-delta.test.ts +42 -0
  21. package/apps/studio/test/canvas-zoom-floor.test.ts +73 -0
  22. package/apps/studio/test/comment-mount.test.ts +10 -1
  23. package/apps/studio/test/dom-selection.test.ts +69 -1
  24. package/apps/studio/test/hmr-broadcast.test.ts +6 -4
  25. package/apps/studio/test/hmr-classify.test.ts +18 -1
  26. package/apps/studio/test/input-router.test.ts +69 -0
  27. package/apps/studio/test/mode-toggle.test.tsx +226 -0
  28. package/apps/studio/test/sync-annotations-cold-start.test.ts +302 -0
  29. package/apps/studio/test/use-tool-mode.test.tsx +33 -3
  30. package/apps/studio/tool-palette.tsx +86 -24
  31. package/apps/studio/use-tool-mode.tsx +113 -14
  32. package/apps/studio/whats-new.json +45 -0
  33. package/package.json +8 -8
  34. package/plugins/design/templates/_shell.html +31 -0
@@ -1,4 +1,4 @@
1
- import{Component as vQ,createElement as g,Fragment as CQ,useCallback as x7,useEffect as f,useMemo as SQ,useRef as p,useState as $7}from"react";import{createRoot as RQ}from"react-dom/client";import{useCallback as k,useEffect as S,useMemo as s,useRef as R,useState as u}from"react";function H7(){if(typeof window>"u")return;try{let J=window.location.pathname;if(J==="/_canvas-shell.html"||J==="/_canvas-shell"){let Q=new URLSearchParams(window.location.search),$=Q.get("canvas")??"",Z=(Q.get("designRel")??".design").replace(/^\/+|\/+$/g,"");return $?`${Z}/${$}`:void 0}return decodeURIComponent(J).replace(/^\//,"")}catch{return}}function Z7(J){if(!J)return"";return(J.getAttribute("class")??"").trim().split(/\s+/).filter((Q)=>Q&&!Q.startsWith("dgn-")&&!Q.startsWith("dc-cv-")).join(" ")}function NJ(J,Q){if(!J)return"";let $=(J.innerText||J.textContent||"").replace(/\s+/g," ").trim();return $.length>Q?`${$.slice(0,Q-1)}…`:$}function _J(J){if(!J)return"";let Q=[],$=J;while($&&$.nodeType===1&&Q.length<8){let Z=$.getAttribute?.("data-dc-element");if(Z){Q.unshift(`[data-dc-element="${Z}"]`);break}let q=$.getAttribute?.("data-dc-screen");if(q){Q.unshift(`[data-dc-screen="${q}"]`);break}let G=$.nodeName.toLowerCase();if($.id){G=`#${$.id}`,Q.unshift(G);break}let K=Z7($).split(/\s+/).filter(Boolean).slice(0,2);if(K.length)G+=`.${K.join(".")}`;let z=1,H=$.previousElementSibling;while(H)z++,H=H.previousElementSibling;G+=`:nth-child(${z})`,Q.unshift(G),$=$.parentElement}return Q.join(" > ")}function R7(J){let Q=[],$=J;while($&&$.nodeType===1&&Q.length<8){let Z=$.nodeName.toLowerCase(),q=$.getAttribute?.("data-dc-element"),G=$.getAttribute?.("data-dc-screen");if(q)Z+=`[data-dc-element="${q}"]`;else if(G)Z+=`[data-dc-screen="${G}"]`;else if($.id)Z+=`#${$.id}`;let K=Z7($).split(/\s+/).filter(Boolean).slice(0,2);if(K.length&&!q&&!G)Z+=`.${K.join(".")}`;Q.unshift(Z),$=$.parentElement}return Q}function IJ(J){return J.replace(/[^a-zA-Z0-9_-]/g,(Q)=>`\\${Q}`)}function g7(J,Q){return Q?`[data-dc-screen="${Q}"] [data-cd-id="${J}"]`:`[data-cd-id="${J}"]`}function h7(J,Q,$){if(!$)return 0;try{let Z=J.querySelectorAll(Q);for(let q=0;q<Z.length;q++)if(Z[q]===$)return q}catch{}return 0}function f7(J,Q,$){if(!Q||!$)return 0;return h7(J,`[data-cd-id="${IJ(Q)}"]`,$)}function F7(J,Q){let $=(Z)=>{try{let q=J.querySelectorAll(Z);if(!q.length)return null;let G=Q.index&&Q.index>0&&Q.index<q.length?Q.index:0;return q[G]??q[0]}catch{return null}};if(Q.id){let Z=$(g7(Q.id,Q.artboardId));if(Z)return Z}if(Q.selector)return $(Q.selector);return null}function AJ(J,Q){let $=0,Z=Math.min(J.length,Q.length);for(let q=1;q<=Z;q++){if(J[J.length-q]!==Q[Q.length-q])break;$++}return $}function p7(J,Q){let $=Q.dom_path,Z=(Q.tag||"").toLowerCase();if(!$||$.length===0||!Z)return null;let q=J;if(Q.artboardId){let H=J.querySelector(`[data-dc-screen="${Q.artboardId}"]`);if(H)q=H}let G=(Q.classes||"").split(/\s+/).filter(Boolean),K=null,z=0;for(let H of Array.from(q.querySelectorAll("[data-cd-id]"))){if(H.tagName.toLowerCase()!==Z)continue;let j=AJ(R7(H),$);if(j===0)continue;let L=Z7(H).split(/\s+/).filter(Boolean),U=G.filter((F)=>L.includes(F)).length,B=j*10+U;if(B>z)z=B,K=H}return K}var S7=["display","flex-direction","flex-wrap","align-items","justify-content","gap","flex","flex-grow","flex-shrink","flex-basis","align-self","font-family","color","font-size","font-weight","line-height","letter-spacing","text-align","margin","margin-top","margin-right","margin-bottom","margin-left","padding","padding-top","padding-right","padding-bottom","padding-left","width","height","min-width","min-height","max-width","max-height","background-color","border-radius","border-top-left-radius","border-top-right-radius","border-bottom-left-radius","border-bottom-right-radius","border-width","border-style","border-color","box-shadow","opacity","position","top","right","bottom","left","z-index","transform","transform-origin","font-style","text-transform","text-decoration","white-space","overflow","object-fit","aspect-ratio","object-position"],OJ=/^(style|class|data-cd-id|data-dc-|data-dcid$)/;function TJ(J){if(!J||typeof window>"u"||!window.getComputedStyle)return{authored:{},computed:{},customStyles:{},attrs:{}};try{let Q=J.style,$=window.getComputedStyle(J),Z={},q={},G=new Set(S7);for(let B of S7){let F=Q.getPropertyValue(B);if(F)Z[B]=F.trim();let Y=$.getPropertyValue(B);if(Y)q[B]=Y.trim()}let K=/^(margin|padding|border)(-|$)/,z={};for(let B=0;B<Q.length;B++){let F=Q.item(B);if(!F||G.has(F)||K.test(F))continue;let Y=Q.getPropertyValue(F);if(Y)z[F]=Y.trim()}let H={};for(let B of Array.from(J.attributes)){if(OJ.test(B.name))continue;H[B.name]=B.value}if(J.hasAttribute("data-dc-screen")){for(let B of Array.from(J.attributes))if(B.name.startsWith("data-dc-")&&B.name!=="data-dcid")H[B.name]=B.value}let j=J.parentElement,L=j?window.getComputedStyle(j).display:"",U=j&&(L==="flex"||L==="inline-flex")?window.getComputedStyle(j).flexDirection:"";return{authored:Z,computed:q,customStyles:z,attrs:H,parentDisplay:L,parentFlexDirection:U}}catch{return{authored:{},computed:{},customStyles:{},attrs:{}}}}function P7(J,Q){let $=J.el,Z=$&&$.getBoundingClientRect?$.getBoundingClientRect():null,q=J.cdId,G=q?g7(q,J.artboardId):J.artboardId?`[data-dc-screen="${J.artboardId}"]`:_J($),K=q&&typeof document<"u"?h7(document,G,$):0;return{file:Q??H7(),id:q??void 0,selector:G,artboardId:J.artboardId,index:K,tag:$?.tagName.toLowerCase()??"",classes:Z7($),text:NJ($,240),dom_path:R7($),bounds:Z?{x:Math.round(Z.left),y:Math.round(Z.top),w:Math.round(Z.width),h:Math.round(Z.height)}:null,worldW:$ instanceof HTMLElement?Math.round($.offsetWidth):void 0,worldH:$ instanceof HTMLElement?Math.round($.offsetHeight):void 0,html:$?($.outerHTML??"").slice(0,4000):"",...(()=>{if($?.tagName?.toLowerCase()!=="img")return{};let z=/assets\/[0-9a-f]{8}\.[a-z0-9]+/i,H=$.getAttribute?.("data-photo-asset");if(H&&z.test(H))return{photoKind:"artboard-img",photoAsset:H};let j=$.getAttribute?.("src")||"",L=z.exec(j);return L?{photoKind:"artboard-img",photoAsset:L[0]}:{}})(),...TJ($)}}var q7=null;function G7(){if(typeof window>"u")return!1;if(q7===null)try{q7=new URLSearchParams(window.location.search).get("ro")==="1"}catch{q7=!1}return q7}import*as D7 from"lib0/decoding";import*as a from"lib0/encoding";import{createContext as wJ,useCallback as Q0,useContext as bJ,useEffect as $0,useMemo as V0,useReducer as Z0,useRef as q0,useState as G0}from"react";import{Awareness as W0,applyAwarenessUpdate as K0,encodeAwarenessUpdate as X0}from"y-protocols/awareness";import{readSyncMessage as U0,writeSyncStep1 as Y0,writeUpdate as H0}from"y-protocols/sync";import*as xJ from"yjs";import*as kJ from"yjs";var EJ=new WeakSet;function u7(J){return EJ.add(J),J}var oQ=u7(Object.freeze({maudeOrigin:"shell-edit"})),aQ=u7(Object.freeze({maudeOrigin:"sync-agent"}));import{jsx as D0}from"react/jsx-runtime";var yJ=wJ(null);function m7(){return bJ(yJ)}import{createContext as vJ,useCallback as l,useContext as j7,useEffect as CJ,useMemo as SJ,useRef as RJ,useState as gJ}from"react";import{jsx as M7,Fragment as pJ}from"react/jsx-runtime";var B7=vJ(null);function r(J){return J.id?`id:${J.id}`:`sel:${J.selector}`}function d7(J){let Q=[],$=new Set;for(let Z of J){let q=r(Z);if($.has(q))continue;$.add(q),Q.push(Z)}return Q}var hJ=50;function fJ({children:J,postTarget:Q}){let[$,Z]=gJ([]),q=RJ(null),G=l((B)=>{if(q.current)clearTimeout(q.current);q.current=setTimeout(()=>{q.current=null;let F=Q??(typeof window<"u"?window.parent:null);if(!F)return;let Y=B.length===0?null:B.length===1?B[0]??null:B;try{F.postMessage({dgn:"select-set",selection:Y},"*")}catch{}},hJ)},[Q]);CJ(()=>()=>{if(q.current)clearTimeout(q.current)},[]);let K=l((B)=>{let F=d7(Array.isArray(B)?B:[B]);Z(F),G(F)},[G]),z=l((B)=>{let F=Array.isArray(B)?B:[B];Z((Y)=>{let D=d7([...Y,...F]);return G(D),D})},[G]),H=l((B)=>{let F=r(B);Z((Y)=>{let D=Y.filter((_)=>r(_)!==F);return G(D),D})},[G]),j=l((B)=>{let F=r(B);Z((Y)=>{let D=Y.some((_)=>r(_)===F)?Y.filter((_)=>r(_)!==F):[...Y,B];return G(D),D})},[G]),L=l(()=>{Z([]),G([])},[G]),U=SJ(()=>({selected:$,replace:K,add:z,remove:H,toggle:j,clear:L}),[$,K,z,H,j,L]);return M7(B7.Provider,{value:U,children:J})}function i7({children:J}){if(j7(B7))return M7(pJ,{children:J});return M7(fJ,{children:J})}function W7(){let J=j7(B7);if(!J)throw Error("useSelectionSet must be used inside <SelectionSetProvider>");return J}function c7(){return j7(B7)}import{jsx as O,jsxs as x,Fragment as JQ}from"react/jsx-runtime";var uJ="/_client/comments-overlay.css";function mJ(){if(typeof document>"u")return;if(document.getElementById("cm-overlay-css"))return;let J=document.createElement("link");J.id="cm-overlay-css",J.rel="stylesheet",J.href=uJ,document.head.appendChild(J)}function dJ(){if(typeof window>"u")return null;try{let J=window.location.pathname;if(J==="/_canvas-shell.html"||J==="/_canvas-shell"){let Q=new URLSearchParams(window.location.search),$=Q.get("canvas")??"",Z=(Q.get("designRel")??".design").replace(/^\/+|\/+$/g,"");return $?`${Z}/${$}`:null}return decodeURIComponent(J).replace(/^\//,"")}catch{return null}}function iJ(J){if(!J.selector)return null;let Q=null;try{let $=document.querySelectorAll(J.selector),Z=J.index&&J.index>0&&J.index<$.length?J.index:0;Q=$[Z]??$[0]??null}catch{Q=null}if(Q&&J.tag&&Q.tagName.toLowerCase()!==J.tag.toLowerCase())Q=null;if(!Q&&J.dom_path?.length){let $=J.selector.match(/data-dc-screen="([^"]+)"/)?.[1];Q=p7(document,{artboardId:$,tag:J.tag,classes:J.classes,dom_path:J.dom_path})}return Q}function N7(J){let Q=iJ(J);if(!Q?.isConnected)return null;let $=Q.getBoundingClientRect();if($.width===0&&$.height===0)return null;return{x:$.left,y:$.top,w:$.width,h:$.height}}function o7(J,Q){let Z=typeof window<"u"?window.innerWidth:J.x+Q.w,q=typeof window<"u"?window.innerHeight:J.y+Q.h,G=J.x;if(G+Q.w+8>Z){let z=J.x-Q.w;G=z>=8?z:Math.max(8,Z-Q.w-8)}let K=J.y;if(K+Q.h+8>q){let z=J.y-Q.h;K=z>=8?z:Math.max(8,q-Q.h-8)}return{x:G,y:K}}function a7(){mJ();let J=c7(),[Q,$]=u([]),[Z,q]=u(null),[G,K]=u(null),z=s(()=>dJ(),[]);S(()=>{if(typeof document>"u")return;let W=document.getElementById("dgn-pin-layer");if(!W)return;let P=W.style.display;return W.style.display="none",()=>{W.style.display=P}},[]);let H=k((W)=>{if(!J)return;if(!W?.selector){J.clear();return}let P=W.selector.match(/data-cd-id="([^"]+)"/),N=P?P[1]:void 0,I,A;try{let M=document.querySelector(W.selector);if(M)I=M.tagName.toLowerCase(),A=(M.getAttribute("class")??"").split(/\s+/).filter((T)=>T&&!T.startsWith("dgn-")&&!T.startsWith("dc-cv-")).join(" ")}catch{}J.replace({file:z??void 0,id:N,selector:W.selector,tag:I,classes:A,bounds:W.bounds??void 0})},[J,z]),j=R(Q);j.current=Q;let L=m7();S(()=>{if(!L)return;let W=L.doc.getArray("comments"),P=()=>{$(W.toArray())};if(W.length>0)P();return W.observe(P),()=>{try{W.unobserve(P)}catch{}}},[L]),S(()=>{if(typeof window>"u")return;let W=(P)=>{let N=P.data;if(!N||typeof N!=="object"||!N.dgn)return;if(N.dgn==="comments-set"&&Array.isArray(N.comments))$(N.comments);else if(N.dgn==="comment-focus"){let I=typeof N.id==="string"?N.id:null;q(I);let A=I?j.current.find((M)=>M.id===I):void 0;H(A)}};return window.addEventListener("message",W),()=>window.removeEventListener("message",W)},[H]),S(()=>{if(typeof document>"u")return;let W=(P)=>{let N=P.detail;if(!N?.selection)return;K({selection:N.selection,clientX:typeof N.clientX==="number"?N.clientX:0,clientY:typeof N.clientY==="number"?N.clientY:0})};return document.addEventListener("cm:open-composer",W),()=>document.removeEventListener("cm:open-composer",W)},[]);let U=k(()=>{if(K(null),typeof window>"u")return;try{window.parent.postMessage({dgn:"force-clear"},"*")}catch{}},[]),B=k((W)=>{if(!G)return;let P=G.selection,N={file:P.file,selector:P.selector,index:P.index,dom_path:P.dom_path,tag:P.tag,classes:P.classes,bounds:P.bounds,html_excerpt:P.html,text:W};if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-submit",payload:N},"*")}catch{}U()},[G,U]);S(()=>{if(!z)return;let W=!1;return(async()=>{try{let P=await fetch(`/_comments?file=${encodeURIComponent(z)}`);if(!P.ok)return;let N=await P.json();if(W)return;if(Array.isArray(N.comments))$((I)=>I.length===0?N.comments??[]:I)}catch{}})(),()=>{W=!0}},[z]);let F=s(()=>{return Q.slice().sort((P,N)=>P.created.localeCompare(N.created)).filter((P)=>P.status!=="resolved")},[Q]),Y=s(()=>{let W=new Map;return Q.slice().sort((N,I)=>N.created.localeCompare(I.created)).forEach((N,I)=>{W.set(N.id,I+1)}),W},[Q]),D=k((W)=>{if(q(W),H(Q.find((P)=>P.id===W)),typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-click",id:W},"*")}catch{}},[Q,H]),_=k((W,P)=>{if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-patch",id:W,patch:P},"*")}catch{}},[]),V=k((W)=>{if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-delete",id:W},"*")}catch{}q((P)=>P===W?null:P)},[]),X=k(async(W,P)=>{if(typeof fetch>"u")return!1;try{let N=await fetch(`/_api/comments/${encodeURIComponent(W)}/reply`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({body:P})});if(!N.ok)return!1;let I=await N.json();return $((A)=>A.map((M)=>M.id===I.id?I:M)),!0}catch{return!1}},[]);return x("div",{className:"cm-layer","aria-hidden":!1,children:[F.map((W)=>{let P=Y.get(W.id)??0;return O(nJ,{comment:W,sequence:P,focused:Z===W.id,onClick:D,onOrphaned:V},W.id)}),G?O(oJ,{state:G,onSubmit:B,onCancel:U}):null,(()=>{if(!Z)return null;let W=F.find((P)=>P.id===Z);if(!W)return null;return O(aJ,{comment:W,sequence:Y.get(W.id)??0,onClose:()=>{q(null),J?.clear()},onPatch:(P)=>_(W.id,P),onDelete:()=>V(W.id),onReply:(P)=>X(W.id,P)})})()]})}var L7=null;async function cJ(){if(!L7)L7=(async()=>{try{let J=await fetch("/_api/git-committers");if(!J.ok)return[];let Q=await J.json();return Array.isArray(Q.committers)?Q.committers:[]}catch{return[]}})();return L7}function l7(J){return(J.trim().split(/\s+/)[0]??"").replace(/[^\w.-]/g,"").toLowerCase()}function lJ(J,Q){if(Q<=0||Q>J.length)return null;let $=Q-1;while($>=0){let Z=J[$]??"";if(Z==="@"){let q=$>0?J[$-1]:"";if($===0||/\s/.test(q??"")){let G=J.slice($+1,Q);return{start:$,end:Q,query:G}}return null}if(!/[\w.-]/.test(Z))return null;$-=1}return null}function s7({className:J,value:Q,onChange:$,onKeyDown:Z,placeholder:q,rows:G,disabled:K,textareaRef:z,ariaLabel:H}){let j=R(null),L=k((M)=>{if(j.current=M,z)z.current=M},[z]),[U,B]=u([]),[F,Y]=u(null),[D,_]=u(0),V=k(()=>{if(U.length>0)return;cJ().then((M)=>B(M))},[U.length]),X=s(()=>{if(!F)return[];let M=F.query.toLowerCase();return(!M?U:U.filter((E)=>E.name.toLowerCase().includes(M)||E.email.toLowerCase().includes(M))).slice(0,8)},[F,U]),W=k((M)=>{let T=M.selectionStart??M.value.length,E=lJ(M.value,T);Y(E),_(0)},[]),P=k((M)=>{$(M.target.value),W(M.target)},[$,W]),N=k((M)=>{if(!F)return;let T=j.current;if(!T)return;let E=`@${l7(M.name)}`,y=`${Q.slice(0,F.start)}${E} ${Q.slice(F.end)}`;$(y),Y(null);let w=F.start+E.length+1;requestAnimationFrame(()=>{T.focus(),T.setSelectionRange(w,w)})},[F,Q,$]),I=k((M)=>{if(F&&X.length>0){if(M.key==="ArrowDown"){M.preventDefault(),_((T)=>(T+1)%X.length);return}if(M.key==="ArrowUp"){M.preventDefault(),_((T)=>(T-1+X.length)%X.length);return}if(M.key==="Enter"||M.key==="Tab"){M.preventDefault();let T=X[D]??X[0];if(T)N(T);return}if(M.key==="Escape"){M.preventDefault(),Y(null);return}}Z?.(M)},[F,X,D,N,Z]),A=k((M)=>{W(M.currentTarget)},[W]);return x("div",{style:{position:"relative"},children:[O("textarea",{ref:L,className:J,value:Q,placeholder:q,rows:G,disabled:K,"aria-label":H,onChange:P,onKeyDown:I,onFocus:V,onSelect:A,onClick:A}),F&&X.length>0?O("ul",{className:"cm-mention-popup",role:"listbox","aria-label":"Mention suggestions",style:{left:0,top:"100%"},children:X.map((M,T)=>{return x("li",{role:"option","aria-selected":T===D,className:"cm-mention-popup__item",onMouseEnter:()=>_(T),onMouseDown:(y)=>{y.preventDefault(),N(M)},children:[x("span",{className:"cm-mention-popup__name",children:["@",l7(M.name)]}),O("span",{className:"cm-mention-popup__email",children:M.email})]},`${M.name}-${M.email}`)})}):null]})}var rJ=3000;function nJ({comment:J,sequence:Q,focused:$,onClick:Z,onOrphaned:q}){let G=R(null),K=R(null),z=R(null);S(()=>{let L=()=>{K.current=null;let U=G.current;if(!U)return;let B=N7(J);if(B)z.current=null;else{if(z.current==null)z.current=Date.now();else if(Date.now()-z.current>rJ)q(J.id);if(J.bounds)B={x:J.bounds.x,y:J.bounds.y,w:J.bounds.w,h:J.bounds.h}}if(!B){U.style.display="none",K.current=requestAnimationFrame(L);return}U.style.display="grid";let F=Math.round(B.x+B.w-12),Y=Math.round(B.y-12);U.style.left=`${F}px`,U.style.top=`${Y}px`,K.current=requestAnimationFrame(L)};return K.current=requestAnimationFrame(L),()=>{if(K.current!=null)cancelAnimationFrame(K.current)}},[J,q]);let H=J.author?.trim()||"unknown",j=`Comment ${Q} by ${H}`;return O("button",{ref:G,type:"button",className:"cm-pin","data-resolved":J.status==="resolved"?"true":"false","data-focused":$?"true":"false","data-comment-pin":J.id,"aria-label":j,"aria-expanded":$,title:J.text.slice(0,200),onClick:(L)=>{L.preventDefault(),L.stopPropagation(),Z(J.id)},children:Q})}function oJ({state:J,onSubmit:Q,onCancel:$}){let[Z,q]=u(""),G=R(null),K=R(null),z=R(null);S(()=>{let U=()=>{z.current=null;let B=K.current;if(!B)return;let F=eJ(J),Y=o7(F,{w:B.offsetWidth,h:B.offsetHeight});B.style.left=`${Math.round(Y.x)}px`,B.style.top=`${Math.round(Y.y)}px`,z.current=requestAnimationFrame(U)};return z.current=requestAnimationFrame(U),()=>{if(z.current!=null)cancelAnimationFrame(z.current)}},[J]),S(()=>{G.current?.focus()},[]);let H=k(()=>{let U=Z.trim();if(!U)return;Q(U)},[Z,Q]),j=k((U)=>{if(U.key==="Escape"){U.preventDefault(),$();return}if((U.metaKey||U.ctrlKey)&&U.key==="Enter")U.preventDefault(),H()},[$,H]),L=s(()=>{let U=J.selection.selector||"";if(!U)return J.selection.tag||"canvas";let B=U.match(/data-cd-id="([^"]+)"/);if(B)return`cd:${B[1]}`;return U.length>36?`${U.slice(0,33)}…`:U},[J.selection]);return x("div",{ref:K,className:"cm-composer",role:"dialog","aria-label":"New comment",onClick:(U)=>U.stopPropagation(),onPointerDown:(U)=>U.stopPropagation(),children:[x("div",{className:"cm-composer__head",children:[O("span",{children:"New comment"}),O("span",{className:"cm-composer__selector",children:L})]}),O(s7,{textareaRef:G,className:"cm-composer__textarea",value:Z,placeholder:"Type a comment. ⌘↵ to save · Esc to cancel · @name to tag",onChange:q,onKeyDown:j,rows:3,ariaLabel:"Comment body"}),x("div",{className:"cm-composer__actions",children:[O("button",{type:"button",className:"cm-btn",onClick:$,children:"Cancel"}),O("button",{type:"button",className:"cm-btn cm-btn--primary",disabled:!Z.trim(),onClick:H,children:"Save"})]})]})}function aJ({comment:J,sequence:Q,onClose:$,onPatch:Z,onDelete:q,onReply:G}){let K=R(null),z=R(null),H=R(null),[j,L]=u(""),[U,B]=u(!1);S(()=>{let V=()=>{H.current=null;let X=K.current;if(!X)return;let W=tJ(J),P=o7(W,{w:X.offsetWidth,h:X.offsetHeight});X.style.left=`${Math.round(P.x)}px`,X.style.top=`${Math.round(P.y)}px`,H.current=requestAnimationFrame(V)};return H.current=requestAnimationFrame(V),()=>{if(H.current!=null)cancelAnimationFrame(H.current)}},[J]),S(()=>{K.current?.focus();let V=J.id;return()=>{document.querySelector(`[data-comment-pin="${V}"]`)?.focus()}},[J.id]),S(()=>{if(typeof document>"u")return;let V=(X)=>{if(X.key!=="Escape")return;let W=K.current;if(!W)return;if(W.contains(X.target)||document.activeElement===W)X.preventDefault(),$()};return document.addEventListener("keydown",V),()=>document.removeEventListener("keydown",V)},[$]);let F=k(async()=>{let V=j.trim();if(!V||U)return;B(!0);let X=await G(V);if(B(!1),X)L(""),z.current?.focus()},[j,U,G]),Y=k((V)=>{if((V.metaKey||V.ctrlKey)&&V.key==="Enter")V.preventDefault(),F()},[F]),D=`cm-thread-head-${J.id}`,_=sJ(J.selector,"");return x("div",{ref:K,className:"cm-thread",role:"dialog","aria-labelledby":D,tabIndex:-1,onClick:(V)=>V.stopPropagation(),onPointerDown:(V)=>V.stopPropagation(),children:[x("div",{className:"cm-thread__head",id:D,children:[x("div",{className:"cm-thread__head-row",children:[O("span",{className:"cm-thread__seq","aria-hidden":"true",children:Q}),O("span",{className:"cm-thread__author",children:J.author?.trim()||"unknown"}),O("span",{className:"cm-thread__time",children:n7(J.created)}),O("button",{type:"button",className:"cm-thread__close","aria-label":"Close thread",title:"Close · Esc",onClick:$,children:"×"})]}),_?O("code",{className:"cm-thread__selector",children:_}):null]}),O("div",{className:"cm-thread__body",children:r7(J.text)}),(J.thread??[]).map((V)=>x("div",{className:"cm-thread__reply",children:[x("div",{className:"cm-thread__reply-head",children:[O("span",{className:"cm-thread__reply-author",children:V.author?.trim()||"unknown"}),O("span",{className:"cm-thread__reply-time",children:n7(V.created)})]}),O("div",{className:"cm-thread__reply-body",children:r7(V.body)})]},V.id)),!G7()&&x(JQ,{children:[x("div",{className:"cm-thread__reply-form",children:[O(s7,{textareaRef:z,className:"cm-thread__reply-textarea",value:j,placeholder:"Reply… ⌘↵ to send · @name to tag",onChange:L,onKeyDown:Y,rows:2,ariaLabel:"Reply",disabled:U}),O("div",{className:"cm-thread__reply-actions",children:O("button",{type:"button",className:"cm-btn cm-btn--primary",disabled:!j.trim()||U,onClick:()=>void F(),children:"Send"})})]}),x("div",{className:"cm-thread__actions",children:[J.status==="resolved"?O("button",{type:"button",className:"cm-btn",onClick:()=>Z({status:"open"}),children:"↺ Reopen"}):O("button",{type:"button",className:"cm-btn cm-btn--primary",onClick:()=>{Z({status:"resolved"}),$()},children:"✓ Resolve"}),O("button",{type:"button",className:"cm-btn cm-btn--danger",onClick:()=>{q(),$()},children:"Delete"})]})]})]})}function r7(J){if(!J)return null;let Q=/(@[\w][\w.-]*)/g;return J.split(Q).map((Z,q)=>{let G=`${q}:${Z}`;if(q%2===1)return O("strong",{"data-mention":"true",children:Z},G);return O("span",{children:Z},G)})}function n7(J){if(!J)return"";let Q=Date.parse(J);if(!Number.isFinite(Q))return"";let $=Math.round((Date.now()-Q)/1000);if($<60)return`${Math.max($,0)}s ago`;if($<3600)return`${Math.round($/60)}m ago`;if($<86400)return`${Math.round($/3600)}h ago`;return`${Math.round($/86400)}d ago`}function sJ(J,Q){if(!J)return Q;let $=J.match(/data-cd-id="([^"]+)"/);if($)return`cd:${$[1]}`;return J.length>36?`${J.slice(0,33)}…`:J}function tJ(J){let Q=J.selector?N7(J):null;if(Q)return{x:Q.x+Q.w-12,y:Q.y+16};if(J.bounds)return{x:J.bounds.x+J.bounds.w-12,y:J.bounds.y+16};return{x:16,y:16}}function eJ(J){if(J.clientX||J.clientY)return{x:J.clientX,y:J.clientY+8};if(J.selection.selector){let Q=N7(J.selection);if(Q)return{x:Q.x,y:Q.y+Q.h+8}}return{x:16,y:16}}import{useEffect as QQ}from"react";var $Q=new Set(["pen","highlighter","shape","rect","ellipse","arrow","sticky","text","section","eraser"]);function _7(J){return $Q.has(J)}var t=(J)=>!!(J.metaKey||J.ctrlKey);function e(J){if(J.type==="keydown"){if(J.isEditable)return{kind:"no-op"};if(J.metaKey||J.ctrlKey||J.altKey){if(J.key==="Escape")return{kind:"escape"};let $=(J.key||"").toLowerCase();if(!J.altKey&&(J.metaKey||J.ctrlKey)){if($==="z"&&J.shiftKey)return{kind:"redo"};if($==="z")return{kind:"undo"};if($==="y"&&!J.shiftKey)return{kind:"redo"}}return{kind:"no-op"}}let Q=(J.key||"").toLowerCase();if(Q==="v")return{kind:"tool",tool:"move"};if(Q==="h")return{kind:"tool",tool:"hand"};if(Q==="c")return{kind:"tool",tool:"comment"};if(Q==="b")return{kind:"tool",tool:"pen"};if(Q==="i")return{kind:"tool",tool:"highlighter"};if(Q==="r"||Q==="o")return{kind:"tool",tool:"shape"};if(Q==="a")return{kind:"tool",tool:"arrow"};if(Q==="n")return{kind:"tool",tool:"sticky"};if(Q==="t")return{kind:"tool",tool:"text"};if(Q==="s"&&J.shiftKey)return{kind:"tool",tool:"section"};if(Q==="e")return{kind:"tool",tool:"eraser"};if(J.key==="Escape")return{kind:"escape"};return{kind:"no-op"}}if(J.type==="contextmenu")return{kind:"context-menu",clientX:J.clientX??0,clientY:J.clientY??0};if(J.type==="pointermove"){if(_7(J.activeTool))return{kind:"no-op"};if(J.activeTool==="hand")return{kind:"no-op"};if(J.activeTool==="browse"){if(!t(J))return{kind:"no-op"};return{kind:"hover",deep:!0,clientX:J.clientX??0,clientY:J.clientY??0}}if(J.activeTool==="comment")return{kind:"hover",deep:!0,clientX:J.clientX??0,clientY:J.clientY??0};return{kind:"hover",deep:t(J),clientX:J.clientX??0,clientY:J.clientY??0}}if(J.type==="pointerdown"){if(J.button===2)return{kind:"context-menu",clientX:J.clientX??0,clientY:J.clientY??0};if(J.button===1||J.spaceHeld)return{kind:"no-op"};if(J.button!==0)return{kind:"no-op"};if(_7(J.activeTool)&&!t(J))return{kind:"no-op"};if(J.activeTool==="comment")return{kind:"drop-comment",clientX:J.clientX??0,clientY:J.clientY??0};if(J.activeTool==="hand")return{kind:"no-op"};if(J.activeTool==="browse"){if(!t(J))return{kind:"no-op"};return{kind:"select",mode:J.shiftKey?"add":"replace",deep:!0,clientX:J.clientX??0,clientY:J.clientY??0}}let Q=t(J);return{kind:"select",mode:!!J.shiftKey?"add":"replace",deep:Q,clientX:J.clientX??0,clientY:J.clientY??0}}return{kind:"no-op"}}function K7(J){if(!J||!J.tagName)return!1;let Q=J,$=Q.tagName;if($==="INPUT"||$==="TEXTAREA"||$==="SELECT")return!0;if(Q.isContentEditable)return!0;let Z=Q.getAttribute?.("contenteditable");if(Z==="true"||Z==="plaintext-only"||Z==="")return!0;return!1}function J7(J){if(!J||!J.closest)return!1;return!!J.closest(".cm-composer, .cm-thread, .cm-mention-popup, .cm-pin, [data-mediaref-player]")}function e7(J){if(!J||typeof J.closest!=="function")return!1;let Q=J;return!!Q.closest("[data-dc-screen]")&&!Q.closest(".dc-artboard-body")}function t7(J,Q,$){return J.kind==="select"&&!$.metaKey&&!$.ctrlKey&&e7(Q)}function VQ(J,Q,$){return J==="select"&&!$.metaKey&&!$.ctrlKey&&e7(Q)}function JJ(J){let{hostRef:Q,getActiveTool:$,isSpaceHeld:Z,callbacks:q,enabled:G=!0,claimableActions:K}=J;QQ(()=>{if(!G)return;let z=Q.current;if(!z)return;let H=(V)=>K&&V.kind!=="no-op"&&!K.has(V.kind)?{kind:"no-op"}:V,j=(V)=>{switch(V.kind){case"hover":q.onHover?.(V);break;case"select":q.onSelect?.(V);break;case"drop-comment":q.onDropComment?.(V);break;case"context-menu":q.onContextMenu?.(V);break;case"tool":q.onTool?.(V);break;case"escape":q.onEscape?.();break;case"undo":q.onUndo?.();break;case"redo":q.onRedo?.();break;case"no-op":break}},L=(V)=>{let X=H(e({type:"pointermove",button:V.button,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,clientX:V.clientX,clientY:V.clientY,spaceHeld:Z?.()??!1,activeTool:$()}));j(X)},U=(V)=>{if(J7(V.target))return;if(K7(V.target))return;let X=H(e({type:"pointerdown",button:V.button,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,clientX:V.clientX,clientY:V.clientY,spaceHeld:Z?.()??!1,activeTool:$()})),W=t7(X,V.target,V);if(X.kind!=="no-op"){if(V.preventDefault(),!W)V.stopImmediatePropagation()}j(X)},B=(V)=>{if(J7(V.target))return;if(K7(V.target))return;let X=H(e({type:"pointerdown",button:V.button,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,clientX:V.clientX,clientY:V.clientY,spaceHeld:Z?.()??!1,activeTool:$()})),W=t7(X,V.target,V);if(X.kind!=="no-op"){if(V.preventDefault(),!W)V.stopImmediatePropagation();if(X.kind==="select")try{window.focus()}catch{}}},F=(V)=>{if(J7(V.target))return;if(K7(V.target))return;let X=$(),W=V.metaKey||V.ctrlKey,P=X==="comment"?"drop-comment":X==="move"&&V.button===0?"select":(_7(X)||X==="browse")&&W&&V.button===0?"select":V.button===2?"context-menu":null;if(P&&(!K||K.has(P))){let N=VQ(P,V.target,V);if(V.preventDefault(),!N)V.stopImmediatePropagation()}},Y=(V)=>{let X=H(e({type:"contextmenu",clientX:V.clientX,clientY:V.clientY,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,activeTool:$()}));if(X.kind==="no-op")return;V.preventDefault(),V.stopImmediatePropagation(),j(X)},D=(V)=>{let X=H(e({type:"keydown",key:V.key,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,isEditable:K7(V.target),activeTool:$()}));if(X.kind==="tool"||X.kind==="escape"||X.kind==="undo"||X.kind==="redo")V.preventDefault();j(X)};z.addEventListener("pointermove",L,{passive:!0}),z.addEventListener("pointerdown",U,{capture:!0}),z.addEventListener("mousedown",B,{capture:!0}),z.addEventListener("click",F,{capture:!0}),z.addEventListener("contextmenu",Y,{capture:!0});let _=z.ownerDocument??document;return _.addEventListener("keydown",D,!0),()=>{z.removeEventListener("pointermove",L),z.removeEventListener("pointerdown",U,{capture:!0}),z.removeEventListener("mousedown",B,{capture:!0}),z.removeEventListener("click",F,{capture:!0}),z.removeEventListener("contextmenu",Y,{capture:!0}),_.removeEventListener("keydown",D,!0)}},[G,Q,$,Z,q,K])}function I7(J,Q,$,Z){let q=J.elementFromPoint(Q,$);if(!q)return null;if(q.closest?.(".dc-mm, .dc-zoom-tb, .dc-tool-palette, .dc-context-menu, .dc-cv-group-bbox"))return null;let G=q.closest?.("[data-dc-screen]")??null,K=G?.getAttribute("data-dc-screen")??null,z=q.closest?.(".dc-artboard-body")??null;if(!z){if(G&&K)return{el:G,cdId:null,artboardId:K};return null}if(q===z){if(G&&K)return{el:G,cdId:null,artboardId:K};return null}if(Z.deep){let B=q.getAttribute?.("data-cd-id")??null;return{el:q,cdId:B,artboardId:K}}let H=q,j=null;while(H&&H!==z){if(H.hasAttribute?.("data-cd-id"))j=H;H=H.parentElement}let L=j??q,U=L.getAttribute?.("data-cd-id")??null;return{el:L,cdId:U,artboardId:K}}import{useCallback as LQ,useEffect as GJ,useRef as z7}from"react";var ZQ=!1;function QJ(){return ZQ}import{createContext as YQ,useCallback as k7,useContext as ZJ,useEffect as HQ,useMemo as VJ,useState as E7}from"react";function m(J,Q,$,Z){return`url("data:image/svg+xml,${encodeURIComponent(J.trim())}") ${Q} ${$}, ${Z}`}var O7="width='24' height='24' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'",T7="#1f1f1f",A7="stroke='#ffffff' stroke-linejoin='round' stroke-linecap='round'";function i(J,Q,$){let Z=$?`<g transform='${$}'>`:"";return`<svg ${O7}>${Z}<path fill='#ffffff' d='${J}'/><path fill='${T7}' d='${Q}'/>${$?"</g>":""}</svg>`}var $J="translate(0,32) scale(1,-1)",qQ=m(i("M10.25 8.25 L10.05 8.65 10 9 10 23.1 10.05 23.4 10.25 23.75 10.8 24 11.45 23.85 11.6 23.7 11.75 23.45 14.65 19.8 14.85 19.65 14.95 19.5 15.4 19.2 15.95 19.1 21.05 19.1 21.2 19.1 21.35 19.05 21.65 18.9 21.9 18.6 22 18.3 22 17.9 21.9 17.65 21.75 17.35 21.65 17.3 21.55 17.15 11.5 8.25 11.25 8.05 10.95 8 10.6 8.05 10.25 8.25 M9.15 6.6 L9.7 6.25 10 6.15 10.95 6 11.9 6.15 13 6.9 22.9 15.65 23 15.8 23.2 15.95 23.75 16.75 24 17.9 24 18.3 23.9 18.95 23.8 19.25 23.6 19.7 23.1 20.35 22.75 20.6 22.1 20.9 22.05 20.95 22 20.95 21.2 21.1 21.05 21.1 16.2 21.1 16.1 21.25 16.05 21.25 13.4 24.6 13.05 25.15 12.9 25.3 12.55 25.55 Q11.6 26.15 10.55 26 L10.5 26 Q9.65 25.85 9 25.3 L8.45 24.65 8.4 24.5 8.15 24.05 8 23.1 8 9 Q8 8.45 8.15 8.05 L8.25 7.75 8.45 7.35 9.15 6.6","M10.25 8.25 L10.6 8.05 10.95 8 11.25 8.05 11.5 8.25 21.55 17.15 21.65 17.3 21.75 17.35 21.9 17.65 22 17.9 22 18.3 21.9 18.6 21.65 18.9 21.35 19.05 21.2 19.1 21.05 19.1 15.95 19.1 15.4 19.2 14.95 19.5 14.85 19.65 14.65 19.8 11.75 23.45 11.6 23.7 11.45 23.85 10.8 24 10.25 23.75 10.05 23.4 10 23.1 10 9 10.05 8.65 10.25 8.25"),8,5,"default"),GQ=m(i("M28.55 17.8 Q29.4 20.3 28.75 22.8 L28.7 23 28.15 24.55 28.05 24.75 Q26.4 28.2 22.75 29.4 L22.45 29.5 18 29.9 17.75 29.85 Q15.8 29.25 13.8 28.1 L13.45 27.95 Q12 27.05 10.35 26.8 L10.25 26.75 7.9 26.7 7.8 26.7 Q6.1 26.9 4.8 25.8 L4.75 25.8 4.65 25.7 4.6 25.65 Q3.25 24.5 3.05 22.85 L3 22.75 Q2.8 20.95 4 19.5 5.05 18.15 6.75 17.95 L8.4 17.9 7.5 15.55 7.3 15.2 7.2 15 5 10.95 Q3.9 9.15 4.3 7.75 L4.4 7.5 Q4.75 6.15 6.45 5.2 9 3.65 11 5 11.05 4.1 11.5 3.45 12.15 2.1 14.2 1.6 L14.35 1.6 Q18.05 0.6 19.6 4.4 L19.65 4.55 Q20.75 3.65 22.7 3.75 L22.75 3.75 Q26.75 4 27 8.15 L27 8.25 27 8.35 27 8.45 Q26.9 10.75 27.1 12.6 27.15 14.65 28.2 16.75 L28.55 17.8 M26.65 18.4 L26.1 16.8 26.1 16.85 Q24.8 13.7 25 8.35 L25 8.25 Q24.85 5.9 22.6 5.75 20.7 5.65 20.4 7.35 L20.1 7.95 19.5 8.2 18.85 8.05 18.45 7.5 17.75 5.15 Q16.85 2.95 14.7 3.55 L14.65 3.55 Q12.55 4.05 13.15 6.15 L13.85 8.75 13.75 9.45 13.25 9.95 12.55 9.95 12 9.55 10.9 7.7 Q9.5 5.7 7.45 6.9 6.5 7.45 6.25 8.15 6.1 8.9 6.7 9.85 9.2 13.9 10.8 18.65 L10.8 19.3 10.4 19.8 9.75 19.95 Q8.35 19.8 6.95 19.95 6.1 20.05 5.55 20.75 4.9 21.55 5 22.55 5.15 23.55 6 24.2 L6.05 24.25 Q6.75 24.85 7.65 24.7 L7.7 24.7 10.65 24.8 Q12.7 25.15 14.45 26.2 L14.5 26.2 Q16.4 27.35 18.3 27.9 L22.05 27.5 22.1 27.5 Q24.95 26.55 26.25 23.85 L26.8 22.3 Q27.3 20.35 26.65 18.4","M26.65 18.4 Q27.3 20.35 26.8 22.3 L26.25 23.85 Q24.95 26.55 22.1 27.5 L22.05 27.5 18.3 27.9 Q16.4 27.35 14.5 26.2 L14.45 26.2 Q12.7 25.15 10.65 24.8 L7.7 24.7 7.65 24.7 Q6.75 24.85 6.05 24.25 L6 24.2 Q5.15 23.55 5 22.55 4.9 21.55 5.55 20.75 6.1 20.05 6.95 19.95 8.35 19.8 9.75 19.95 L10.4 19.8 10.8 19.3 10.8 18.65 Q9.2 13.9 6.7 9.85 6.1 8.9 6.25 8.15 6.5 7.45 7.45 6.9 9.5 5.7 10.9 7.7 L12 9.55 12.55 9.95 13.25 9.95 13.75 9.45 13.85 8.75 13.15 6.15 Q12.55 4.05 14.65 3.55 L14.7 3.55 Q16.85 2.95 17.75 5.15 L18.45 7.5 18.85 8.05 19.5 8.2 20.1 7.95 20.4 7.35 Q20.7 5.65 22.6 5.75 24.85 5.9 25 8.25 L25 8.35 Q24.8 13.7 26.1 16.85 L26.1 16.8 26.65 18.4"),12,12,"grab"),BQ=m(i("M28 14 Q28 9.85 24.45 6.9 20.95 4 16 4 11.05 4 7.5 6.9 L7.45 7 Q4 9.9 4 14 4 18.15 7.55 21.05 L7.5 21.05 Q9.2 22.45 11.2 23.2 L15.3 27.3 16 27.6 16.7 27.3 20.85 23.2 Q22.7 22.45 24.3 21.15 L24.45 21.05 Q28 18.15 28 14 M25.75 5.35 Q30.05 8.95 30 14 30.05 19.05 25.75 22.6 L25.4 22.85 Q23.8 24.1 22 24.9 L18.1 28.75 18.15 28.75 Q17.2 29.6 16 29.6 14.8 29.6 13.85 28.75 L13.9 28.75 10 24.9 6.6 22.85 6.25 22.6 Q1.95 19.05 2 14 1.95 8.95 6.25 5.35 10.3 2 16 2 21.7 2 25.75 5.35","M28 14 Q28 18.15 24.45 21.05 L24.3 21.15 Q22.7 22.45 20.85 23.2 L16.7 27.3 16 27.6 15.3 27.3 11.2 23.2 Q9.2 22.45 7.5 21.05 L7.55 21.05 Q4 18.15 4 14 4 9.9 7.45 7 L7.5 6.9 Q11.05 4 16 4 20.95 4 24.45 6.9 28 9.85 28 14"),12,21,"crosshair"),WQ=m(i("M4 13.1 L4 6 Q4 5.15 4.6 4.6 5.15 4 6 4 L13.1 4 Q13.95 4 14.55 4.6 L28.65 18.75 Q29.8 19.9 29.75 21.45 L29.75 21.6 29.75 21.7 Q29.75 23.2 28.7 24.35 L24.45 28.65 24.35 28.75 Q23.15 29.85 21.65 29.8 L21.55 29.8 21.4 29.8 Q20.2 29.8 19.25 29.15 L18 29.35 Q16.6 29.4 15.25 28 L15.2 27.95 8.2 20.95 Q7.6 20.35 7.6 19.55 7.6 18.7 8.2 18.1 L4.6 14.5 Q4 13.9 4 13.1 M19.5 26.65 L20.1 27.25 Q20.7 27.85 21.5 27.8 22.35 27.85 23 27.25 L27.25 22.95 Q27.8 22.35 27.75 21.55 27.8 20.75 27.2 20.15 L13.1 6 6 6 6 13.1 12.35 19.45 9.6 19.5 16.65 26.55 Q18.05 28.05 19.5 26.65 M8.05 12.3 L8 8 12.25 8.05 13.8 9.6 9.6 13.85 8.05 12.3 M15.25 11.05 L23 18.8 18.8 23.05 11.05 15.3 15.25 11.05","M15.25 11.05 L11.05 15.3 18.8 23.05 23 18.8 15.25 11.05 M12.35 19.45 L6 13.1 6 6 13.1 6 27.2 20.15 Q27.8 20.75 27.75 21.55 27.8 22.35 27.25 22.95 L23 27.25 Q22.35 27.85 21.5 27.8 20.7 27.85 20.1 27.25 L19.5 26.65 12.35 19.45 M8.05 12.3 L9.6 13.85 13.8 9.6 12.25 8.05 8 8 8.05 12.3",$J),6,18,"crosshair"),KQ=m(i("M5.15 10.85 Q4 9.65 4 8.1 L4 7.95 4 7.85 Q3.95 6.2 5.1 5.15 6.25 4 7.85 4 L7.95 4 8.1 4 Q9.65 4 10.85 5.15 L11 5.3 14.3 5.25 Q15.15 5.25 15.75 5.85 L29.9 20 Q31 21.15 31 22.75 L31 22.85 31 23 Q31.05 24.5 29.9 25.7 L29.55 25.95 25.65 29.9 25.65 29.95 Q24.45 31.1 22.75 31.1 21.2 31.15 20 29.95 L5.85 15.8 Q5.25 15.2 5.25 14.35 L5.25 10.95 5.15 10.85 M19.95 24.2 L18.55 22.8 22.8 18.55 24.2 19.95 19.95 24.2 M28.45 21.4 L14.3 7.25 10.15 7.3 9.4 6.55 Q8.8 5.95 7.95 6 7.1 5.95 6.5 6.55 5.95 7.1 6 7.95 5.95 8.8 6.55 9.4 L7.25 10.1 7.25 14.35 21.4 28.5 Q22 29.1 22.75 29.1 23.6 29.1 24.2 28.5 L28.45 24.25 Q29.05 23.65 29 22.85 29.05 22 28.45 21.4 M9.25 13.5 L9.25 9.3 13.5 9.25 14.3 10.05 10.05 14.3 9.25 13.5 M17.15 21.4 L11.5 15.75 15.75 11.5 21.4 17.15 17.15 21.4","M17.15 21.4 L21.4 17.15 15.75 11.5 11.5 15.75 17.15 21.4 M28.45 21.4 Q29.05 22 29 22.85 29.05 23.65 28.45 24.25 L24.2 28.5 Q23.6 29.1 22.75 29.1 22 29.1 21.4 28.5 L7.25 14.35 7.25 10.1 6.55 9.4 Q5.95 8.8 6 7.95 5.95 7.1 6.5 6.55 7.1 5.95 7.95 6 8.8 5.95 9.4 6.55 L10.15 7.3 14.3 7.25 28.45 21.4 M19.95 24.2 L24.2 19.95 22.8 18.55 18.55 22.8 19.95 24.2 M9.25 13.5 L10.05 14.3 14.3 10.05 13.5 9.25 9.25 9.3 9.25 13.5",$J),6,18,"crosshair"),Q7=m(i("M17 2 Q18.2 2 19.15 2.9 20 3.8 20 5 L20 12 27 12 Q28.2 12 29.15 12.9 30 13.8 30 15 L30 17 Q30 18.2 29.15 19.15 28.2 20 27 20 L20 20 20 27 Q20 28.2 19.15 29.15 18.2 30 17 30 L15 30 Q13.8 30 12.9 29.15 12 28.2 12 27 L12 20 5 20 Q3.8 20 2.9 19.15 2 18.2 2 17 L2 15 Q2 13.8 2.9 12.9 3.8 12 5 12 L12 12 12 5 Q12 3.8 12.9 2.9 13.8 2 15 2 L17 2 M14 27 L14.3 27.7 Q14.6 28 15 28 L17 28 17.7 27.7 18 27 18 18.05 18.05 18 27 18 Q27.4 18 27.7 17.7 L28 17 28 15 27.7 14.3 Q27.4 14 27 14 L18 14 18 5 17.7 4.3 17 4 15 4 Q14.6 4 14.3 4.3 14 4.6 14 5 L14 14 5 14 Q4.6 14 4.3 14.3 4 14.6 4 15 L4 17 Q4 17.4 4.3 17.7 4.6 18 5 18 L14 18 14 27","M14 27 L14 18 5 18 Q4.6 18 4.3 17.7 4 17.4 4 17 L4 15 Q4 14.6 4.3 14.3 4.6 14 5 14 L14 14 14 5 Q14 4.6 14.3 4.3 14.6 4 15 4 L17 4 17.7 4.3 18 5 18 14 27 14 Q27.4 14 27.7 14.3 L28 15 28 17 27.7 17.7 Q27.4 18 27 18 L18.05 18 18 18.05 18 27 17.7 27.7 17 28 15 28 Q14.6 28 14.3 27.7 L14 27"),12,12,"crosshair"),XQ=m(i("M3.9 11.35 Q2.3 12.5 3.7 13.9 L16.4 26.65 Q17.85 28.05 19.45 26.9 L27.65 21.15 Q29.3 20 27.85 18.6 L15.15 5.85 Q13.75 4.45 12.1 5.6 L3.9 11.35 M1.05 12.4 Q1 10.95 2.75 9.75 L10.95 4 10.95 3.95 Q14 1.85 16.6 4.45 L29.3 17.2 Q30.8 18.65 30.55 20.1 30.55 21.55 28.8 22.8 L20.6 28.55 20.65 28.55 Q17.7 30.65 15 28.1 L15 28.05 2.3 15.3 2.3 15.35 Q0.8 13.85 1.05 12.4 M13.5 7 L19.85 13.35 11.65 19.15 5.3 12.75 13.5 7","M13.5 7 L5.3 12.75 11.65 19.15 19.85 13.35 13.5 7 M3.9 11.35 L12.1 5.6 Q13.75 4.45 15.15 5.85 L27.85 18.6 Q29.3 20 27.65 21.15 L19.45 26.9 Q17.85 28.05 16.4 26.65 L3.7 13.9 Q2.3 12.5 3.9 11.35"),6,14,"cell"),zQ=m(`<svg ${O7}><path d='M16 4V28M11 4H21M11 28H21' fill='none' ${A7} stroke-width='5'/><path d='M16 4V28M11 4H21M11 28H21' fill='none' stroke='${T7}' stroke-width='2.25' stroke-linecap='round'/></svg>`,12,12,"text"),UQ=m(`<svg ${O7}><path d='M6 5H21L26 10V27H6Z' fill='${T7}' ${A7} stroke-width='2.5'/><path d='M21 5V11H26' fill='none' ${A7} stroke-width='2.25'/></svg>`,5,5,"crosshair"),C=Object.freeze({browse:"default",move:qQ,hand:GQ,comment:BQ,pen:WQ,section:Q7,highlighter:KQ,shape:Q7,rect:Q7,ellipse:Q7,sticky:UQ,arrow:Q7,text:zQ,eraser:XQ});import{jsx as w7,Fragment as jQ}from"react/jsx-runtime";var FQ=Object.freeze([{id:"browse",label:"Browse",shortcut:"",cursor:C.browse},{id:"move",label:"Select",shortcut:"V",cursor:C.move},{id:"hand",label:"Hand",shortcut:"H",cursor:C.hand},{id:"comment",label:"Comment",shortcut:"C",cursor:C.comment},{id:"pen",label:"Pen",shortcut:"B",cursor:C.pen},{id:"highlighter",label:"Highlighter",shortcut:"I",cursor:C.highlighter},{id:"shape",label:"Shape",shortcut:"R",cursor:C.shape},{id:"sticky",label:"Sticky",shortcut:"N",cursor:C.sticky},{id:"section",label:"Section",shortcut:"⇧S",cursor:C.shape},{id:"arrow",label:"Arrow",shortcut:"A",cursor:C.arrow},{id:"text",label:"Text",shortcut:"T",cursor:C.text},{id:"eraser",label:"Eraser",shortcut:"E",cursor:C.eraser}]),PQ=new Set(["browse","move","hand"]);function DQ(J,Q){return Q?J.filter(($)=>PQ.has($.id)):J}var b7=YQ(null);function MQ({children:J,tools:Q=FQ,initial:$="browse"}){let Z=VJ(()=>DQ(Q,G7()),[Q]),[q,G]=E7($),[K,z]=E7(()=>({tool:null,locked:!1})),H=k7((Y)=>{if(!Z.some((D)=>D.id===Y))return;G(Y),z((D)=>D.locked&&D.tool===Y?D:{tool:null,locked:!1})},[Z]),j=k7((Y)=>{z((D)=>{if(D.locked&&D.tool===Y)return{tool:null,locked:!1};return{tool:Y,locked:!0}}),G(Y)},[]),L=k7(()=>{z({tool:null,locked:!1})},[]),[U,B]=E7("rounded");HQ(()=>{if(typeof document>"u")return;let Y=Z.find((V)=>V.id===q);if(!Y)return;let D=document.body.style.cursor,_=document.getElementById("dc-tool-cursor");if(!_)_=document.createElement("style"),_.id="dc-tool-cursor",document.head.appendChild(_);if(q==="browse"){if(document.body.style.cursor="",_.textContent="",typeof window<"u"&&window.parent&&window.parent!==window)try{window.parent.postMessage({dgn:"tool-cursor",tool:q},"*")}catch{}return()=>{document.body.style.cursor=D}}if(document.body.style.cursor=Y.cursor,_.textContent=`* { cursor: ${Y.cursor} !important; }`,typeof window<"u"&&window.parent&&window.parent!==window)try{window.parent.postMessage({dgn:"tool-cursor",tool:q},"*")}catch{}return()=>{document.body.style.cursor=D;let V=document.getElementById("dc-tool-cursor");if(V)V.textContent=""}},[q,Z]);let F=VJ(()=>({tool:q,setTool:H,tools:Z,sticky:K,toggleSticky:j,clearSticky:L,shapeKind:U,setShapeKind:B}),[q,H,Z,K,j,L,U]);return w7(b7.Provider,{value:F,children:J})}function qJ({children:J}){if(ZJ(b7))return w7(jQ,{children:J});return w7(MQ,{children:J})}function X7(){let J=ZJ(b7);if(!J)throw Error("useToolMode must be used inside <ToolProvider>");return J}import{jsx as yQ}from"react/jsx-runtime";var NQ=`
1
+ import{Component as RQ,createElement as h,Fragment as SQ,useCallback as b7,useEffect as f,useMemo as hQ,useRef as p,useState as V7}from"react";import{createRoot as gQ}from"react-dom/client";import{useCallback as T,useEffect as R,useMemo as s,useRef as S,useState as u}from"react";function P7(){if(typeof window>"u")return;try{let J=window.location.pathname;if(J==="/_canvas-shell.html"||J==="/_canvas-shell"){let Q=new URLSearchParams(window.location.search),$=Q.get("canvas")??"",Z=(Q.get("designRel")??".design").replace(/^\/+|\/+$/g,"");return $?`${Z}/${$}`:void 0}return decodeURIComponent(J).replace(/^\//,"")}catch{return}}function q7(J){if(!J)return"";return(J.getAttribute("class")??"").trim().split(/\s+/).filter((Q)=>Q&&!Q.startsWith("dgn-")&&!Q.startsWith("dc-cv-")).join(" ")}function IJ(J,Q){if(!J)return"";let $=(J.innerText||J.textContent||"").replace(/\s+/g," ").trim();return $.length>Q?`${$.slice(0,Q-1)}…`:$}function AJ(J){if(!J)return"";let Q=[],$=J;while($&&$.nodeType===1&&Q.length<8){let Z=$.getAttribute?.("data-dc-element");if(Z){Q.unshift(`[data-dc-element="${Z}"]`);break}let q=$.getAttribute?.("data-dc-screen");if(q){Q.unshift(`[data-dc-screen="${q}"]`);break}let G=$.nodeName.toLowerCase();if($.id){G=`#${$.id}`,Q.unshift(G);break}let z=q7($).split(/\s+/).filter(Boolean).slice(0,2);if(z.length)G+=`.${z.join(".")}`;let X=1,Y=$.previousElementSibling;while(Y)X++,Y=Y.previousElementSibling;G+=`:nth-child(${X})`,Q.unshift(G),$=$.parentElement}return Q.join(" > ")}function S7(J){let Q=[],$=J;while($&&$.nodeType===1&&Q.length<8){let Z=$.nodeName.toLowerCase(),q=$.getAttribute?.("data-dc-element"),G=$.getAttribute?.("data-dc-screen");if(q)Z+=`[data-dc-element="${q}"]`;else if(G)Z+=`[data-dc-screen="${G}"]`;else if($.id)Z+=`#${$.id}`;let z=q7($).split(/\s+/).filter(Boolean).slice(0,2);if(z.length&&!q&&!G)Z+=`.${z.join(".")}`;Q.unshift(Z),$=$.parentElement}return Q}function OJ(J){return J.replace(/[^a-zA-Z0-9_-]/g,(Q)=>`\\${Q}`)}function h7(J,Q){return Q?`[data-dc-screen="${Q}"] [data-cd-id="${J}"]`:`[data-cd-id="${J}"]`}function g7(J,Q,$){if(!$)return 0;try{let Z=J.querySelectorAll(Q);for(let q=0;q<Z.length;q++)if(Z[q]===$)return q}catch{}return 0}function f7(J,Q,$){if(!Q||!$)return 0;return g7(J,`[data-cd-id="${OJ(Q)}"]`,$)}function D7(J,Q){let $=(Z)=>{try{let q=J.querySelectorAll(Z);if(!q.length)return null;let G=Q.index&&Q.index>0&&Q.index<q.length?Q.index:0;return q[G]??q[0]}catch{return null}};if(Q.id){let Z=$(h7(Q.id,Q.artboardId));if(Z)return Z}if(Q.selector)return $(Q.selector);return null}function kJ(J,Q){let $=0,Z=Math.min(J.length,Q.length);for(let q=1;q<=Z;q++){if(J[J.length-q]!==Q[Q.length-q])break;$++}return $}function p7(J,Q){let $=Q.dom_path,Z=(Q.tag||"").toLowerCase();if(!$||$.length===0||!Z)return null;let q=J;if(Q.artboardId){let Y=J.querySelector(`[data-dc-screen="${Q.artboardId}"]`);if(Y)q=Y}let G=(Q.classes||"").split(/\s+/).filter(Boolean),z=null,X=0;for(let Y of Array.from(q.querySelectorAll("[data-cd-id]"))){if(Y.tagName.toLowerCase()!==Z)continue;let _=kJ(S7(Y),$);if(_===0)continue;let L=q7(Y).split(/\s+/).filter(Boolean),U=G.filter((P)=>L.includes(P)).length,W=_*10+U;if(W>X)X=W,z=Y}return z}var R7=["display","flex-direction","flex-wrap","align-items","justify-content","gap","flex","flex-grow","flex-shrink","flex-basis","align-self","font-family","color","font-size","font-weight","line-height","letter-spacing","text-align","margin","margin-top","margin-right","margin-bottom","margin-left","padding","padding-top","padding-right","padding-bottom","padding-left","width","height","min-width","min-height","max-width","max-height","background-color","border-radius","border-top-left-radius","border-top-right-radius","border-bottom-left-radius","border-bottom-right-radius","border-width","border-style","border-color","box-shadow","opacity","position","top","right","bottom","left","z-index","transform","transform-origin","font-style","text-transform","text-decoration","white-space","overflow","object-fit","aspect-ratio","object-position"],TJ=/^(style|class|data-cd-id|data-dc-|data-dcid$)/;function EJ(J){if(!J||typeof window>"u"||!window.getComputedStyle)return{authored:{},computed:{},customStyles:{},attrs:{}};try{let Q=J.style,$=window.getComputedStyle(J),Z={},q={},G=new Set(R7);for(let W of R7){let P=Q.getPropertyValue(W);if(P)Z[W]=P.trim();let H=$.getPropertyValue(W);if(H)q[W]=H.trim()}let z=/^(margin|padding|border)(-|$)/,X={};for(let W=0;W<Q.length;W++){let P=Q.item(W);if(!P||G.has(P)||z.test(P))continue;let H=Q.getPropertyValue(P);if(H)X[P]=H.trim()}let Y={};for(let W of Array.from(J.attributes)){if(TJ.test(W.name))continue;Y[W.name]=W.value}if(J.hasAttribute("data-dc-screen")){for(let W of Array.from(J.attributes))if(W.name.startsWith("data-dc-")&&W.name!=="data-dcid")Y[W.name]=W.value}let _=J.parentElement,L=_?window.getComputedStyle(_).display:"",U=_&&(L==="flex"||L==="inline-flex")?window.getComputedStyle(_).flexDirection:"";return{authored:Z,computed:q,customStyles:X,attrs:Y,parentDisplay:L,parentFlexDirection:U}}catch{return{authored:{},computed:{},customStyles:{},attrs:{}}}}function j7(J,Q){let $=J.el,Z=$&&$.getBoundingClientRect?$.getBoundingClientRect():null,q=J.cdId,G=q?h7(q,J.artboardId):J.artboardId?`[data-dc-screen="${J.artboardId}"]`:AJ($),z=q&&typeof document<"u"?g7(document,G,$):0;return{file:Q??P7(),id:q??void 0,selector:G,artboardId:J.artboardId,index:z,tag:$?.tagName.toLowerCase()??"",classes:q7($),text:IJ($,240),dom_path:S7($),bounds:Z?{x:Math.round(Z.left),y:Math.round(Z.top),w:Math.round(Z.width),h:Math.round(Z.height)}:null,worldW:$ instanceof HTMLElement?Math.round($.offsetWidth):void 0,worldH:$ instanceof HTMLElement?Math.round($.offsetHeight):void 0,html:$?($.outerHTML??"").slice(0,4000):"",...(()=>{if($?.tagName?.toLowerCase()!=="img")return{};let X=/assets\/[0-9a-f]{8}\.[a-z0-9]+/i,Y=$.getAttribute?.("data-photo-asset");if(Y&&X.test(Y))return{photoKind:"artboard-img",photoAsset:Y};let _=$.getAttribute?.("src")||"",L=X.exec(_);return L?{photoKind:"artboard-img",photoAsset:L[0]}:{}})(),...EJ($)}}var G7=null;function B7(){if(typeof window>"u")return!1;if(G7===null)try{G7=new URLSearchParams(window.location.search).get("ro")==="1"}catch{G7=!1}return G7}import*as L7 from"lib0/decoding";import*as o from"lib0/encoding";import{createContext as bJ,useCallback as V0,useContext as yJ,useEffect as Z0,useMemo as q0,useReducer as G0,useRef as B0,useState as W0}from"react";import{Awareness as z0,applyAwarenessUpdate as U0,encodeAwarenessUpdate as X0}from"y-protocols/awareness";import{readSyncMessage as H0,writeSyncStep1 as F0,writeUpdate as P0}from"y-protocols/sync";import*as vJ from"yjs";import*as wJ from"yjs";var xJ=new WeakSet;function u7(J){return xJ.add(J),J}var sQ=u7(Object.freeze({maudeOrigin:"shell-edit"})),tQ=u7(Object.freeze({maudeOrigin:"sync-agent"}));import{jsx as L0}from"react/jsx-runtime";var CJ=bJ(null);function m7(){return yJ(CJ)}import{createContext as RJ,useCallback as l,useContext as M7,useEffect as SJ,useMemo as hJ,useRef as gJ,useState as fJ}from"react";import{jsx as N7,Fragment as mJ}from"react/jsx-runtime";var W7=RJ(null);function n(J){return J.id?`id:${J.id}`:`sel:${J.selector}`}function d7(J){let Q=[],$=new Set;for(let Z of J){let q=n(Z);if($.has(q))continue;$.add(q),Q.push(Z)}return Q}var pJ=50;function uJ({children:J,postTarget:Q}){let[$,Z]=fJ([]),q=gJ(null),G=l((W)=>{if(q.current)clearTimeout(q.current);q.current=setTimeout(()=>{q.current=null;let P=Q??(typeof window<"u"?window.parent:null);if(!P)return;let H=W.length===0?null:W.length===1?W[0]??null:W;try{P.postMessage({dgn:"select-set",selection:H},"*")}catch{}},pJ)},[Q]);SJ(()=>()=>{if(q.current)clearTimeout(q.current)},[]);let z=l((W)=>{let P=d7(Array.isArray(W)?W:[W]);Z(P),G(P)},[G]),X=l((W)=>{let P=Array.isArray(W)?W:[W];Z((H)=>{let j=d7([...H,...P]);return G(j),j})},[G]),Y=l((W)=>{let P=n(W);Z((H)=>{let j=H.filter((I)=>n(I)!==P);return G(j),j})},[G]),_=l((W)=>{let P=n(W);Z((H)=>{let j=H.some((I)=>n(I)===P)?H.filter((I)=>n(I)!==P):[...H,W];return G(j),j})},[G]),L=l(()=>{Z([]),G([])},[G]),U=hJ(()=>({selected:$,replace:z,add:X,remove:Y,toggle:_,clear:L}),[$,z,X,Y,_,L]);return N7(W7.Provider,{value:U,children:J})}function i7({children:J}){if(M7(W7))return N7(mJ,{children:J});return N7(uJ,{children:J})}function K7(){let J=M7(W7);if(!J)throw Error("useSelectionSet must be used inside <SelectionSetProvider>");return J}function c7(){return M7(W7)}import{jsx as k,jsxs as b,Fragment as $Q}from"react/jsx-runtime";var dJ="/_client/comments-overlay.css";function iJ(){if(typeof document>"u")return;if(document.getElementById("cm-overlay-css"))return;let J=document.createElement("link");J.id="cm-overlay-css",J.rel="stylesheet",J.href=dJ,document.head.appendChild(J)}function cJ(){if(typeof window>"u")return null;try{let J=window.location.pathname;if(J==="/_canvas-shell.html"||J==="/_canvas-shell"){let Q=new URLSearchParams(window.location.search),$=Q.get("canvas")??"",Z=(Q.get("designRel")??".design").replace(/^\/+|\/+$/g,"");return $?`${Z}/${$}`:null}return decodeURIComponent(J).replace(/^\//,"")}catch{return null}}function lJ(J){if(!J.selector)return null;let Q=null;try{let $=document.querySelectorAll(J.selector),Z=J.index&&J.index>0&&J.index<$.length?J.index:0;Q=$[Z]??$[0]??null}catch{Q=null}if(Q&&J.tag&&Q.tagName.toLowerCase()!==J.tag.toLowerCase())Q=null;if(!Q&&J.dom_path?.length){let $=J.selector.match(/data-dc-screen="([^"]+)"/)?.[1];Q=p7(document,{artboardId:$,tag:J.tag,classes:J.classes,dom_path:J.dom_path})}return Q}function I7(J){let Q=lJ(J);if(!Q?.isConnected)return null;let $=Q.getBoundingClientRect();if($.width===0&&$.height===0)return null;return{x:$.left,y:$.top,w:$.width,h:$.height}}function a7(J,Q){let Z=typeof window<"u"?window.innerWidth:J.x+Q.w,q=typeof window<"u"?window.innerHeight:J.y+Q.h,G=J.x;if(G+Q.w+8>Z){let X=J.x-Q.w;G=X>=8?X:Math.max(8,Z-Q.w-8)}let z=J.y;if(z+Q.h+8>q){let X=J.y-Q.h;z=X>=8?X:Math.max(8,q-Q.h-8)}return{x:G,y:z}}function o7(){iJ();let J=c7(),[Q,$]=u([]),[Z,q]=u(null),[G,z]=u(null),X=s(()=>cJ(),[]);R(()=>{if(typeof document>"u")return;let B=document.getElementById("dgn-pin-layer");if(!B)return;let D=B.style.display;return B.style.display="none",()=>{B.style.display=D}},[]);let Y=T((B)=>{if(!J)return;if(!B?.selector){J.clear();return}let D=B.selector.match(/data-cd-id="([^"]+)"/),N=D?D[1]:void 0,M,A;try{let F=document.querySelector(B.selector);if(F)M=F.tagName.toLowerCase(),A=(F.getAttribute("class")??"").split(/\s+/).filter((O)=>O&&!O.startsWith("dgn-")&&!O.startsWith("dc-cv-")).join(" ")}catch{}J.replace({file:X??void 0,id:N,selector:B.selector,tag:M,classes:A,bounds:B.bounds??void 0})},[J,X]),_=S(Q);_.current=Q;let L=m7();R(()=>{if(!L)return;let B=L.doc.getArray("comments"),D=()=>{$(B.toArray())};if(B.length>0)D();return B.observe(D),()=>{try{B.unobserve(D)}catch{}}},[L]),R(()=>{if(typeof window>"u")return;let B=(D)=>{let N=D.data;if(!N||typeof N!=="object"||!N.dgn)return;if(N.dgn==="comments-set"&&Array.isArray(N.comments))$(N.comments);else if(N.dgn==="comment-focus"){let M=typeof N.id==="string"?N.id:null;q(M);let A=M?_.current.find((F)=>F.id===M):void 0;Y(A)}};return window.addEventListener("message",B),()=>window.removeEventListener("message",B)},[Y]),R(()=>{if(typeof document>"u")return;let B=(D)=>{let N=D.detail;if(!N?.selection)return;z({selection:N.selection,clientX:typeof N.clientX==="number"?N.clientX:0,clientY:typeof N.clientY==="number"?N.clientY:0})};return document.addEventListener("cm:open-composer",B),()=>document.removeEventListener("cm:open-composer",B)},[]);let U=T(()=>{if(z(null),typeof window>"u")return;try{window.parent.postMessage({dgn:"force-clear"},"*")}catch{}},[]),W=T((B)=>{if(!G)return;let D=G.selection,N={file:D.file,selector:D.selector,index:D.index,dom_path:D.dom_path,tag:D.tag,classes:D.classes,bounds:D.bounds,html_excerpt:D.html,text:B};if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-submit",payload:N},"*")}catch{}U()},[G,U]);R(()=>{if(!X)return;let B=!1;return(async()=>{try{let D=await fetch(`/_comments?file=${encodeURIComponent(X)}`);if(!D.ok)return;let N=await D.json();if(B)return;if(Array.isArray(N.comments))$((M)=>M.length===0?N.comments??[]:M)}catch{}})(),()=>{B=!0}},[X]);let P=s(()=>{return Q.slice().sort((D,N)=>D.created.localeCompare(N.created)).filter((D)=>D.status!=="resolved")},[Q]),H=s(()=>{let B=new Map;return Q.slice().sort((N,M)=>N.created.localeCompare(M.created)).forEach((N,M)=>{B.set(N.id,M+1)}),B},[Q]),j=T((B)=>{if(q(B),Y(Q.find((D)=>D.id===B)),typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-click",id:B},"*")}catch{}},[Q,Y]),I=T((B,D)=>{if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-patch",id:B,patch:D},"*")}catch{}},[]),V=T((B)=>{if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-delete",id:B},"*")}catch{}q((D)=>D===B?null:D)},[]),K=T(async(B,D)=>{if(typeof fetch>"u")return!1;try{let N=await fetch(`/_api/comments/${encodeURIComponent(B)}/reply`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({body:D})});if(!N.ok)return!1;let M=await N.json();return $((A)=>A.map((F)=>F.id===M.id?M:F)),!0}catch{return!1}},[]);return b("div",{className:"cm-layer","aria-hidden":!1,children:[P.map((B)=>{let D=H.get(B.id)??0;return k(oJ,{comment:B,sequence:D,focused:Z===B.id,onClick:j,onOrphaned:V},B.id)}),G?k(sJ,{state:G,onSubmit:W,onCancel:U}):null,(()=>{if(!Z)return null;let B=P.find((D)=>D.id===Z);if(!B)return null;return k(tJ,{comment:B,sequence:H.get(B.id)??0,onClose:()=>{q(null),J?.clear()},onPatch:(D)=>I(B.id,D),onDelete:()=>V(B.id),onReply:(D)=>K(B.id,D)})})()]})}var _7=null;async function nJ(){if(!_7)_7=(async()=>{try{let J=await fetch("/_api/git-committers");if(!J.ok)return[];let Q=await J.json();return Array.isArray(Q.committers)?Q.committers:[]}catch{return[]}})();return _7}function l7(J){return(J.trim().split(/\s+/)[0]??"").replace(/[^\w.-]/g,"").toLowerCase()}function rJ(J,Q){if(Q<=0||Q>J.length)return null;let $=Q-1;while($>=0){let Z=J[$]??"";if(Z==="@"){let q=$>0?J[$-1]:"";if($===0||/\s/.test(q??"")){let G=J.slice($+1,Q);return{start:$,end:Q,query:G}}return null}if(!/[\w.-]/.test(Z))return null;$-=1}return null}function s7({className:J,value:Q,onChange:$,onKeyDown:Z,placeholder:q,rows:G,disabled:z,textareaRef:X,ariaLabel:Y}){let _=S(null),L=T((F)=>{if(_.current=F,X)X.current=F},[X]),[U,W]=u([]),[P,H]=u(null),[j,I]=u(0),V=T(()=>{if(U.length>0)return;nJ().then((F)=>W(F))},[U.length]),K=s(()=>{if(!P)return[];let F=P.query.toLowerCase();return(!F?U:U.filter((E)=>E.name.toLowerCase().includes(F)||E.email.toLowerCase().includes(F))).slice(0,8)},[P,U]),B=T((F)=>{let O=F.selectionStart??F.value.length,E=rJ(F.value,O);H(E),I(0)},[]),D=T((F)=>{$(F.target.value),B(F.target)},[$,B]),N=T((F)=>{if(!P)return;let O=_.current;if(!O)return;let E=`@${l7(F.name)}`,y=`${Q.slice(0,P.start)}${E} ${Q.slice(P.end)}`;$(y),H(null);let w=P.start+E.length+1;requestAnimationFrame(()=>{O.focus(),O.setSelectionRange(w,w)})},[P,Q,$]),M=T((F)=>{if(P&&K.length>0){if(F.key==="ArrowDown"){F.preventDefault(),I((O)=>(O+1)%K.length);return}if(F.key==="ArrowUp"){F.preventDefault(),I((O)=>(O-1+K.length)%K.length);return}if(F.key==="Enter"||F.key==="Tab"){F.preventDefault();let O=K[j]??K[0];if(O)N(O);return}if(F.key==="Escape"){F.preventDefault(),H(null);return}}Z?.(F)},[P,K,j,N,Z]),A=T((F)=>{B(F.currentTarget)},[B]);return b("div",{style:{position:"relative"},children:[k("textarea",{ref:L,className:J,value:Q,placeholder:q,rows:G,disabled:z,"aria-label":Y,onChange:D,onKeyDown:M,onFocus:V,onSelect:A,onClick:A}),P&&K.length>0?k("ul",{className:"cm-mention-popup",role:"listbox","aria-label":"Mention suggestions",style:{left:0,top:"100%"},children:K.map((F,O)=>{return b("li",{role:"option","aria-selected":O===j,className:"cm-mention-popup__item",onMouseEnter:()=>I(O),onMouseDown:(y)=>{y.preventDefault(),N(F)},children:[b("span",{className:"cm-mention-popup__name",children:["@",l7(F.name)]}),k("span",{className:"cm-mention-popup__email",children:F.email})]},`${F.name}-${F.email}`)})}):null]})}var aJ=3000;function oJ({comment:J,sequence:Q,focused:$,onClick:Z,onOrphaned:q}){let G=S(null),z=S(null),X=S(null);R(()=>{let L=()=>{z.current=null;let U=G.current;if(!U)return;let W=I7(J);if(W)X.current=null;else{if(X.current==null)X.current=Date.now();else if(Date.now()-X.current>aJ)q(J.id);if(J.bounds)W={x:J.bounds.x,y:J.bounds.y,w:J.bounds.w,h:J.bounds.h}}if(!W){U.style.display="none",z.current=requestAnimationFrame(L);return}U.style.display="grid";let P=Math.round(W.x+W.w-12),H=Math.round(W.y-12);U.style.left=`${P}px`,U.style.top=`${H}px`,z.current=requestAnimationFrame(L)};return z.current=requestAnimationFrame(L),()=>{if(z.current!=null)cancelAnimationFrame(z.current)}},[J,q]);let Y=J.author?.trim()||"unknown",_=`Comment ${Q} by ${Y}`;return k("button",{ref:G,type:"button",className:"cm-pin","data-resolved":J.status==="resolved"?"true":"false","data-focused":$?"true":"false","data-comment-pin":J.id,"aria-label":_,"aria-expanded":$,title:J.text.slice(0,200),onClick:(L)=>{L.preventDefault(),L.stopPropagation(),Z(J.id)},children:Q})}function sJ({state:J,onSubmit:Q,onCancel:$}){let[Z,q]=u(""),G=S(null),z=S(null),X=S(null);R(()=>{let U=()=>{X.current=null;let W=z.current;if(!W)return;let P=QQ(J),H=a7(P,{w:W.offsetWidth,h:W.offsetHeight});W.style.left=`${Math.round(H.x)}px`,W.style.top=`${Math.round(H.y)}px`,X.current=requestAnimationFrame(U)};return X.current=requestAnimationFrame(U),()=>{if(X.current!=null)cancelAnimationFrame(X.current)}},[J]),R(()=>{G.current?.focus()},[]);let Y=T(()=>{let U=Z.trim();if(!U)return;Q(U)},[Z,Q]),_=T((U)=>{if(U.key==="Escape"){U.preventDefault(),$();return}if((U.metaKey||U.ctrlKey)&&U.key==="Enter")U.preventDefault(),Y()},[$,Y]),L=s(()=>{let U=J.selection.selector||"";if(!U)return J.selection.tag||"canvas";let W=U.match(/data-cd-id="([^"]+)"/);if(W)return`cd:${W[1]}`;return U.length>36?`${U.slice(0,33)}…`:U},[J.selection]);return b("div",{ref:z,className:"cm-composer",role:"dialog","aria-label":"New comment",onClick:(U)=>U.stopPropagation(),onPointerDown:(U)=>U.stopPropagation(),children:[b("div",{className:"cm-composer__head",children:[k("span",{children:"New comment"}),k("span",{className:"cm-composer__selector",children:L})]}),k(s7,{textareaRef:G,className:"cm-composer__textarea",value:Z,placeholder:"Type a comment. ⌘↵ to save · Esc to cancel · @name to tag",onChange:q,onKeyDown:_,rows:3,ariaLabel:"Comment body"}),b("div",{className:"cm-composer__actions",children:[k("button",{type:"button",className:"cm-btn",onClick:$,children:"Cancel"}),k("button",{type:"button",className:"cm-btn cm-btn--primary",disabled:!Z.trim(),onClick:Y,children:"Save"})]})]})}function tJ({comment:J,sequence:Q,onClose:$,onPatch:Z,onDelete:q,onReply:G}){let z=S(null),X=S(null),Y=S(null),[_,L]=u(""),[U,W]=u(!1);R(()=>{let V=()=>{Y.current=null;let K=z.current;if(!K)return;let B=JQ(J),D=a7(B,{w:K.offsetWidth,h:K.offsetHeight});K.style.left=`${Math.round(D.x)}px`,K.style.top=`${Math.round(D.y)}px`,Y.current=requestAnimationFrame(V)};return Y.current=requestAnimationFrame(V),()=>{if(Y.current!=null)cancelAnimationFrame(Y.current)}},[J]),R(()=>{z.current?.focus();let V=J.id;return()=>{document.querySelector(`[data-comment-pin="${V}"]`)?.focus()}},[J.id]),R(()=>{if(typeof document>"u")return;let V=(K)=>{if(K.key!=="Escape")return;let B=z.current;if(!B)return;if(B.contains(K.target)||document.activeElement===B)K.preventDefault(),$()};return document.addEventListener("keydown",V),()=>document.removeEventListener("keydown",V)},[$]);let P=T(async()=>{let V=_.trim();if(!V||U)return;W(!0);let K=await G(V);if(W(!1),K)L(""),X.current?.focus()},[_,U,G]),H=T((V)=>{if((V.metaKey||V.ctrlKey)&&V.key==="Enter")V.preventDefault(),P()},[P]),j=`cm-thread-head-${J.id}`,I=eJ(J.selector,"");return b("div",{ref:z,className:"cm-thread",role:"dialog","aria-labelledby":j,tabIndex:-1,onClick:(V)=>V.stopPropagation(),onPointerDown:(V)=>V.stopPropagation(),children:[b("div",{className:"cm-thread__head",id:j,children:[b("div",{className:"cm-thread__head-row",children:[k("span",{className:"cm-thread__seq","aria-hidden":"true",children:Q}),k("span",{className:"cm-thread__author",children:J.author?.trim()||"unknown"}),k("span",{className:"cm-thread__time",children:r7(J.created)}),k("button",{type:"button",className:"cm-thread__close","aria-label":"Close thread",title:"Close · Esc",onClick:$,children:"×"})]}),I?k("code",{className:"cm-thread__selector",children:I}):null]}),k("div",{className:"cm-thread__body",children:n7(J.text)}),(J.thread??[]).map((V)=>b("div",{className:"cm-thread__reply",children:[b("div",{className:"cm-thread__reply-head",children:[k("span",{className:"cm-thread__reply-author",children:V.author?.trim()||"unknown"}),k("span",{className:"cm-thread__reply-time",children:r7(V.created)})]}),k("div",{className:"cm-thread__reply-body",children:n7(V.body)})]},V.id)),!B7()&&b($Q,{children:[b("div",{className:"cm-thread__reply-form",children:[k(s7,{textareaRef:X,className:"cm-thread__reply-textarea",value:_,placeholder:"Reply… ⌘↵ to send · @name to tag",onChange:L,onKeyDown:H,rows:2,ariaLabel:"Reply",disabled:U}),k("div",{className:"cm-thread__reply-actions",children:k("button",{type:"button",className:"cm-btn cm-btn--primary",disabled:!_.trim()||U,onClick:()=>void P(),children:"Send"})})]}),b("div",{className:"cm-thread__actions",children:[J.status==="resolved"?k("button",{type:"button",className:"cm-btn",onClick:()=>Z({status:"open"}),children:"↺ Reopen"}):k("button",{type:"button",className:"cm-btn cm-btn--primary",onClick:()=>{Z({status:"resolved"}),$()},children:"✓ Resolve"}),k("button",{type:"button",className:"cm-btn cm-btn--danger",onClick:()=>{q(),$()},children:"Delete"})]})]})]})}function n7(J){if(!J)return null;let Q=/(@[\w][\w.-]*)/g;return J.split(Q).map((Z,q)=>{let G=`${q}:${Z}`;if(q%2===1)return k("strong",{"data-mention":"true",children:Z},G);return k("span",{children:Z},G)})}function r7(J){if(!J)return"";let Q=Date.parse(J);if(!Number.isFinite(Q))return"";let $=Math.round((Date.now()-Q)/1000);if($<60)return`${Math.max($,0)}s ago`;if($<3600)return`${Math.round($/60)}m ago`;if($<86400)return`${Math.round($/3600)}h ago`;return`${Math.round($/86400)}d ago`}function eJ(J,Q){if(!J)return Q;let $=J.match(/data-cd-id="([^"]+)"/);if($)return`cd:${$[1]}`;return J.length>36?`${J.slice(0,33)}…`:J}function JQ(J){let Q=J.selector?I7(J):null;if(Q)return{x:Q.x+Q.w-12,y:Q.y+16};if(J.bounds)return{x:J.bounds.x+J.bounds.w-12,y:J.bounds.y+16};return{x:16,y:16}}function QQ(J){if(J.clientX||J.clientY)return{x:J.clientX,y:J.clientY+8};if(J.selection.selector){let Q=I7(J.selection);if(Q)return{x:Q.x,y:Q.y+Q.h+8}}return{x:16,y:16}}import{useEffect as VQ}from"react";var ZQ=new Set(["pen","highlighter","shape","rect","ellipse","arrow","sticky","text","section","eraser"]);function A7(J){return ZQ.has(J)}var t=(J)=>!!(J.metaKey||J.ctrlKey);function e(J){if(J.type==="keydown"){if(J.isEditable)return{kind:"no-op"};if(J.metaKey||J.ctrlKey||J.altKey){if(J.key==="Escape")return{kind:"escape"};let $=(J.key||"").toLowerCase();if(!J.altKey&&(J.metaKey||J.ctrlKey)){if($==="z"&&J.shiftKey)return{kind:"redo"};if($==="z")return{kind:"undo"};if($==="y"&&!J.shiftKey)return{kind:"redo"}}return{kind:"no-op"}}let Q=(J.key||"").toLowerCase();if(Q==="v")return{kind:"tool",tool:"move"};if(Q==="h")return{kind:"tool",tool:"hand"};if(Q==="c")return{kind:"tool",tool:"comment"};if(Q==="b")return{kind:"tool",tool:"pen"};if(Q==="i")return{kind:"tool",tool:"highlighter"};if(Q==="r"||Q==="o")return{kind:"tool",tool:"shape"};if(Q==="a")return{kind:"tool",tool:"arrow"};if(Q==="n")return{kind:"tool",tool:"sticky"};if(Q==="t")return{kind:"tool",tool:"text"};if(Q==="s"&&J.shiftKey)return{kind:"tool",tool:"section"};if(Q==="e")return{kind:"tool",tool:"eraser"};if(J.key==="Escape")return{kind:"escape"};return{kind:"no-op"}}if(J.type==="contextmenu")return{kind:"context-menu",clientX:J.clientX??0,clientY:J.clientY??0};if(J.type==="pointermove"){if(A7(J.activeTool))return{kind:"no-op"};if(J.activeTool==="hand")return{kind:"no-op"};if(J.activeTool==="browse"){if(!t(J))return{kind:"no-op"};return{kind:"hover",deep:!0,clientX:J.clientX??0,clientY:J.clientY??0}}if(J.activeTool==="comment")return{kind:"hover",deep:!0,clientX:J.clientX??0,clientY:J.clientY??0};return{kind:"hover",deep:t(J),clientX:J.clientX??0,clientY:J.clientY??0}}if(J.type==="pointerdown"){if(J.button===2)return{kind:"context-menu",clientX:J.clientX??0,clientY:J.clientY??0};if(J.button===1||J.spaceHeld)return{kind:"no-op"};if(J.button!==0)return{kind:"no-op"};if(A7(J.activeTool)&&!t(J))return{kind:"no-op"};if(J.activeTool==="comment")return{kind:"drop-comment",clientX:J.clientX??0,clientY:J.clientY??0};if(J.activeTool==="hand")return{kind:"no-op"};if(J.activeTool==="browse"){if(!t(J))return{kind:"no-op"};return{kind:"select",mode:J.shiftKey?"add":"replace",deep:!0,clientX:J.clientX??0,clientY:J.clientY??0}}let Q=t(J);return{kind:"select",mode:!!J.shiftKey?"add":"replace",deep:Q,clientX:J.clientX??0,clientY:J.clientY??0}}return{kind:"no-op"}}function z7(J){if(!J||!J.tagName)return!1;let Q=J,$=Q.tagName;if($==="INPUT"||$==="TEXTAREA"||$==="SELECT")return!0;if(Q.isContentEditable)return!0;let Z=Q.getAttribute?.("contenteditable");if(Z==="true"||Z==="plaintext-only"||Z==="")return!0;return!1}function J7(J){if(!J||!J.closest)return!1;let Q=J;if(Q.closest(".dc-world"))return!1;return!!Q.closest(".cm-composer, .cm-thread, .cm-mention-popup, .cm-pin, [data-mediaref-player], .dc-tool-palette, .dc-zoom-tb, .dc-mm, .dc-context-menu")}function e7(J){if(!J||typeof J.closest!=="function")return!1;let Q=J;return!!Q.closest("[data-dc-screen]")&&!Q.closest(".dc-artboard-body")}function t7(J,Q,$){return J.kind==="select"&&!$.metaKey&&!$.ctrlKey&&e7(Q)}function qQ(J,Q,$){return J==="select"&&!$.metaKey&&!$.ctrlKey&&e7(Q)}function JJ(J){let{hostRef:Q,getActiveTool:$,isSpaceHeld:Z,callbacks:q,enabled:G=!0,claimableActions:z}=J;VQ(()=>{if(!G)return;let X=Q.current;if(!X)return;let Y=(V)=>z&&V.kind!=="no-op"&&!z.has(V.kind)?{kind:"no-op"}:V,_=(V)=>{switch(V.kind){case"hover":q.onHover?.(V);break;case"select":q.onSelect?.(V);break;case"drop-comment":q.onDropComment?.(V);break;case"context-menu":q.onContextMenu?.(V);break;case"tool":q.onTool?.(V);break;case"escape":q.onEscape?.();break;case"undo":q.onUndo?.();break;case"redo":q.onRedo?.();break;case"no-op":break}},L=(V)=>{let K=Y(e({type:"pointermove",button:V.button,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,clientX:V.clientX,clientY:V.clientY,spaceHeld:Z?.()??!1,activeTool:$()}));_(K)},U=(V)=>{if(J7(V.target))return;if(z7(V.target))return;let K=Y(e({type:"pointerdown",button:V.button,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,clientX:V.clientX,clientY:V.clientY,spaceHeld:Z?.()??!1,activeTool:$()})),B=t7(K,V.target,V);if(K.kind!=="no-op"){if(V.preventDefault(),!B)V.stopImmediatePropagation()}_(K)},W=(V)=>{if(J7(V.target))return;if(z7(V.target))return;let K=Y(e({type:"pointerdown",button:V.button,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,clientX:V.clientX,clientY:V.clientY,spaceHeld:Z?.()??!1,activeTool:$()})),B=t7(K,V.target,V);if(K.kind!=="no-op"){if(V.preventDefault(),!B)V.stopImmediatePropagation();if(K.kind==="select")try{window.focus()}catch{}}},P=(V)=>{if(J7(V.target))return;if(z7(V.target))return;let K=$(),B=V.metaKey||V.ctrlKey,D=K==="comment"?"drop-comment":K==="move"&&V.button===0?"select":(A7(K)||K==="browse")&&B&&V.button===0?"select":V.button===2?"context-menu":null;if(D&&(!z||z.has(D))){let N=qQ(D,V.target,V);if(V.preventDefault(),!N)V.stopImmediatePropagation()}},H=(V)=>{let K=Y(e({type:"contextmenu",clientX:V.clientX,clientY:V.clientY,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,activeTool:$()}));if(K.kind==="no-op")return;V.preventDefault(),V.stopImmediatePropagation(),_(K)},j=(V)=>{let K=Y(e({type:"keydown",key:V.key,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,isEditable:z7(V.target),activeTool:$()}));if(K.kind==="tool"||K.kind==="escape"||K.kind==="undo"||K.kind==="redo")V.preventDefault();_(K)};X.addEventListener("pointermove",L,{passive:!0}),X.addEventListener("pointerdown",U,{capture:!0}),X.addEventListener("mousedown",W,{capture:!0}),X.addEventListener("click",P,{capture:!0}),X.addEventListener("contextmenu",H,{capture:!0});let I=X.ownerDocument??document;return I.addEventListener("keydown",j,!0),()=>{X.removeEventListener("pointermove",L),X.removeEventListener("pointerdown",U,{capture:!0}),X.removeEventListener("mousedown",W,{capture:!0}),X.removeEventListener("click",P,{capture:!0}),X.removeEventListener("contextmenu",H,{capture:!0}),I.removeEventListener("keydown",j,!0)}},[G,Q,$,Z,q,z])}function O7(J,Q,$,Z){let q=J.elementFromPoint(Q,$);if(!q)return null;if(q.closest?.(".dc-mm, .dc-zoom-tb, .dc-tool-palette, .dc-context-menu, .dc-cv-group-bbox"))return null;let G=q.closest?.("[data-dc-screen]")??null,z=G?.getAttribute("data-dc-screen")??null,X=q.closest?.(".dc-artboard-body")??null;if(!X){if(G&&z)return{el:G,cdId:null,artboardId:z};return null}if(q===X){if(G&&z)return{el:G,cdId:null,artboardId:z};return null}if(Z.deep){let W=q.getAttribute?.("data-cd-id")??null;return{el:q,cdId:W,artboardId:z}}let Y=q,_=null;while(Y&&Y!==X){if(Y.hasAttribute?.("data-cd-id"))_=Y;Y=Y.parentElement}let L=_??q,U=L.getAttribute?.("data-cd-id")??null;return{el:L,cdId:U,artboardId:z}}import{useCallback as _Q,useEffect as WJ,useRef as Y7}from"react";var GQ=!1;function QJ(){return GQ}import{createContext as FQ,useCallback as $7,useContext as GJ,useEffect as PQ,useMemo as VJ,useState as U7}from"react";function m(J,Q,$,Z){return`url("data:image/svg+xml,${encodeURIComponent(J.trim())}") ${Q} ${$}, ${Z}`}var T7="width='24' height='24' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'",E7="#1f1f1f",k7="stroke='#ffffff' stroke-linejoin='round' stroke-linecap='round'";function i(J,Q,$){let Z=$?`<g transform='${$}'>`:"";return`<svg ${T7}>${Z}<path fill='#ffffff' d='${J}'/><path fill='${E7}' d='${Q}'/>${$?"</g>":""}</svg>`}var $J="translate(0,32) scale(1,-1)",BQ=m(i("M10.25 8.25 L10.05 8.65 10 9 10 23.1 10.05 23.4 10.25 23.75 10.8 24 11.45 23.85 11.6 23.7 11.75 23.45 14.65 19.8 14.85 19.65 14.95 19.5 15.4 19.2 15.95 19.1 21.05 19.1 21.2 19.1 21.35 19.05 21.65 18.9 21.9 18.6 22 18.3 22 17.9 21.9 17.65 21.75 17.35 21.65 17.3 21.55 17.15 11.5 8.25 11.25 8.05 10.95 8 10.6 8.05 10.25 8.25 M9.15 6.6 L9.7 6.25 10 6.15 10.95 6 11.9 6.15 13 6.9 22.9 15.65 23 15.8 23.2 15.95 23.75 16.75 24 17.9 24 18.3 23.9 18.95 23.8 19.25 23.6 19.7 23.1 20.35 22.75 20.6 22.1 20.9 22.05 20.95 22 20.95 21.2 21.1 21.05 21.1 16.2 21.1 16.1 21.25 16.05 21.25 13.4 24.6 13.05 25.15 12.9 25.3 12.55 25.55 Q11.6 26.15 10.55 26 L10.5 26 Q9.65 25.85 9 25.3 L8.45 24.65 8.4 24.5 8.15 24.05 8 23.1 8 9 Q8 8.45 8.15 8.05 L8.25 7.75 8.45 7.35 9.15 6.6","M10.25 8.25 L10.6 8.05 10.95 8 11.25 8.05 11.5 8.25 21.55 17.15 21.65 17.3 21.75 17.35 21.9 17.65 22 17.9 22 18.3 21.9 18.6 21.65 18.9 21.35 19.05 21.2 19.1 21.05 19.1 15.95 19.1 15.4 19.2 14.95 19.5 14.85 19.65 14.65 19.8 11.75 23.45 11.6 23.7 11.45 23.85 10.8 24 10.25 23.75 10.05 23.4 10 23.1 10 9 10.05 8.65 10.25 8.25"),8,5,"default"),WQ=m(i("M28.55 17.8 Q29.4 20.3 28.75 22.8 L28.7 23 28.15 24.55 28.05 24.75 Q26.4 28.2 22.75 29.4 L22.45 29.5 18 29.9 17.75 29.85 Q15.8 29.25 13.8 28.1 L13.45 27.95 Q12 27.05 10.35 26.8 L10.25 26.75 7.9 26.7 7.8 26.7 Q6.1 26.9 4.8 25.8 L4.75 25.8 4.65 25.7 4.6 25.65 Q3.25 24.5 3.05 22.85 L3 22.75 Q2.8 20.95 4 19.5 5.05 18.15 6.75 17.95 L8.4 17.9 7.5 15.55 7.3 15.2 7.2 15 5 10.95 Q3.9 9.15 4.3 7.75 L4.4 7.5 Q4.75 6.15 6.45 5.2 9 3.65 11 5 11.05 4.1 11.5 3.45 12.15 2.1 14.2 1.6 L14.35 1.6 Q18.05 0.6 19.6 4.4 L19.65 4.55 Q20.75 3.65 22.7 3.75 L22.75 3.75 Q26.75 4 27 8.15 L27 8.25 27 8.35 27 8.45 Q26.9 10.75 27.1 12.6 27.15 14.65 28.2 16.75 L28.55 17.8 M26.65 18.4 L26.1 16.8 26.1 16.85 Q24.8 13.7 25 8.35 L25 8.25 Q24.85 5.9 22.6 5.75 20.7 5.65 20.4 7.35 L20.1 7.95 19.5 8.2 18.85 8.05 18.45 7.5 17.75 5.15 Q16.85 2.95 14.7 3.55 L14.65 3.55 Q12.55 4.05 13.15 6.15 L13.85 8.75 13.75 9.45 13.25 9.95 12.55 9.95 12 9.55 10.9 7.7 Q9.5 5.7 7.45 6.9 6.5 7.45 6.25 8.15 6.1 8.9 6.7 9.85 9.2 13.9 10.8 18.65 L10.8 19.3 10.4 19.8 9.75 19.95 Q8.35 19.8 6.95 19.95 6.1 20.05 5.55 20.75 4.9 21.55 5 22.55 5.15 23.55 6 24.2 L6.05 24.25 Q6.75 24.85 7.65 24.7 L7.7 24.7 10.65 24.8 Q12.7 25.15 14.45 26.2 L14.5 26.2 Q16.4 27.35 18.3 27.9 L22.05 27.5 22.1 27.5 Q24.95 26.55 26.25 23.85 L26.8 22.3 Q27.3 20.35 26.65 18.4","M26.65 18.4 Q27.3 20.35 26.8 22.3 L26.25 23.85 Q24.95 26.55 22.1 27.5 L22.05 27.5 18.3 27.9 Q16.4 27.35 14.5 26.2 L14.45 26.2 Q12.7 25.15 10.65 24.8 L7.7 24.7 7.65 24.7 Q6.75 24.85 6.05 24.25 L6 24.2 Q5.15 23.55 5 22.55 4.9 21.55 5.55 20.75 6.1 20.05 6.95 19.95 8.35 19.8 9.75 19.95 L10.4 19.8 10.8 19.3 10.8 18.65 Q9.2 13.9 6.7 9.85 6.1 8.9 6.25 8.15 6.5 7.45 7.45 6.9 9.5 5.7 10.9 7.7 L12 9.55 12.55 9.95 13.25 9.95 13.75 9.45 13.85 8.75 13.15 6.15 Q12.55 4.05 14.65 3.55 L14.7 3.55 Q16.85 2.95 17.75 5.15 L18.45 7.5 18.85 8.05 19.5 8.2 20.1 7.95 20.4 7.35 Q20.7 5.65 22.6 5.75 24.85 5.9 25 8.25 L25 8.35 Q24.8 13.7 26.1 16.85 L26.1 16.8 26.65 18.4"),12,12,"grab"),KQ=m(i("M28 14 Q28 9.85 24.45 6.9 20.95 4 16 4 11.05 4 7.5 6.9 L7.45 7 Q4 9.9 4 14 4 18.15 7.55 21.05 L7.5 21.05 Q9.2 22.45 11.2 23.2 L15.3 27.3 16 27.6 16.7 27.3 20.85 23.2 Q22.7 22.45 24.3 21.15 L24.45 21.05 Q28 18.15 28 14 M25.75 5.35 Q30.05 8.95 30 14 30.05 19.05 25.75 22.6 L25.4 22.85 Q23.8 24.1 22 24.9 L18.1 28.75 18.15 28.75 Q17.2 29.6 16 29.6 14.8 29.6 13.85 28.75 L13.9 28.75 10 24.9 6.6 22.85 6.25 22.6 Q1.95 19.05 2 14 1.95 8.95 6.25 5.35 10.3 2 16 2 21.7 2 25.75 5.35","M28 14 Q28 18.15 24.45 21.05 L24.3 21.15 Q22.7 22.45 20.85 23.2 L16.7 27.3 16 27.6 15.3 27.3 11.2 23.2 Q9.2 22.45 7.5 21.05 L7.55 21.05 Q4 18.15 4 14 4 9.9 7.45 7 L7.5 6.9 Q11.05 4 16 4 20.95 4 24.45 6.9 28 9.85 28 14"),12,21,"crosshair"),zQ=m(i("M4 13.1 L4 6 Q4 5.15 4.6 4.6 5.15 4 6 4 L13.1 4 Q13.95 4 14.55 4.6 L28.65 18.75 Q29.8 19.9 29.75 21.45 L29.75 21.6 29.75 21.7 Q29.75 23.2 28.7 24.35 L24.45 28.65 24.35 28.75 Q23.15 29.85 21.65 29.8 L21.55 29.8 21.4 29.8 Q20.2 29.8 19.25 29.15 L18 29.35 Q16.6 29.4 15.25 28 L15.2 27.95 8.2 20.95 Q7.6 20.35 7.6 19.55 7.6 18.7 8.2 18.1 L4.6 14.5 Q4 13.9 4 13.1 M19.5 26.65 L20.1 27.25 Q20.7 27.85 21.5 27.8 22.35 27.85 23 27.25 L27.25 22.95 Q27.8 22.35 27.75 21.55 27.8 20.75 27.2 20.15 L13.1 6 6 6 6 13.1 12.35 19.45 9.6 19.5 16.65 26.55 Q18.05 28.05 19.5 26.65 M8.05 12.3 L8 8 12.25 8.05 13.8 9.6 9.6 13.85 8.05 12.3 M15.25 11.05 L23 18.8 18.8 23.05 11.05 15.3 15.25 11.05","M15.25 11.05 L11.05 15.3 18.8 23.05 23 18.8 15.25 11.05 M12.35 19.45 L6 13.1 6 6 13.1 6 27.2 20.15 Q27.8 20.75 27.75 21.55 27.8 22.35 27.25 22.95 L23 27.25 Q22.35 27.85 21.5 27.8 20.7 27.85 20.1 27.25 L19.5 26.65 12.35 19.45 M8.05 12.3 L9.6 13.85 13.8 9.6 12.25 8.05 8 8 8.05 12.3",$J),6,18,"crosshair"),UQ=m(i("M5.15 10.85 Q4 9.65 4 8.1 L4 7.95 4 7.85 Q3.95 6.2 5.1 5.15 6.25 4 7.85 4 L7.95 4 8.1 4 Q9.65 4 10.85 5.15 L11 5.3 14.3 5.25 Q15.15 5.25 15.75 5.85 L29.9 20 Q31 21.15 31 22.75 L31 22.85 31 23 Q31.05 24.5 29.9 25.7 L29.55 25.95 25.65 29.9 25.65 29.95 Q24.45 31.1 22.75 31.1 21.2 31.15 20 29.95 L5.85 15.8 Q5.25 15.2 5.25 14.35 L5.25 10.95 5.15 10.85 M19.95 24.2 L18.55 22.8 22.8 18.55 24.2 19.95 19.95 24.2 M28.45 21.4 L14.3 7.25 10.15 7.3 9.4 6.55 Q8.8 5.95 7.95 6 7.1 5.95 6.5 6.55 5.95 7.1 6 7.95 5.95 8.8 6.55 9.4 L7.25 10.1 7.25 14.35 21.4 28.5 Q22 29.1 22.75 29.1 23.6 29.1 24.2 28.5 L28.45 24.25 Q29.05 23.65 29 22.85 29.05 22 28.45 21.4 M9.25 13.5 L9.25 9.3 13.5 9.25 14.3 10.05 10.05 14.3 9.25 13.5 M17.15 21.4 L11.5 15.75 15.75 11.5 21.4 17.15 17.15 21.4","M17.15 21.4 L21.4 17.15 15.75 11.5 11.5 15.75 17.15 21.4 M28.45 21.4 Q29.05 22 29 22.85 29.05 23.65 28.45 24.25 L24.2 28.5 Q23.6 29.1 22.75 29.1 22 29.1 21.4 28.5 L7.25 14.35 7.25 10.1 6.55 9.4 Q5.95 8.8 6 7.95 5.95 7.1 6.5 6.55 7.1 5.95 7.95 6 8.8 5.95 9.4 6.55 L10.15 7.3 14.3 7.25 28.45 21.4 M19.95 24.2 L24.2 19.95 22.8 18.55 18.55 22.8 19.95 24.2 M9.25 13.5 L10.05 14.3 14.3 10.05 13.5 9.25 9.25 9.3 9.25 13.5",$J),6,18,"crosshair"),Q7=m(i("M17 2 Q18.2 2 19.15 2.9 20 3.8 20 5 L20 12 27 12 Q28.2 12 29.15 12.9 30 13.8 30 15 L30 17 Q30 18.2 29.15 19.15 28.2 20 27 20 L20 20 20 27 Q20 28.2 19.15 29.15 18.2 30 17 30 L15 30 Q13.8 30 12.9 29.15 12 28.2 12 27 L12 20 5 20 Q3.8 20 2.9 19.15 2 18.2 2 17 L2 15 Q2 13.8 2.9 12.9 3.8 12 5 12 L12 12 12 5 Q12 3.8 12.9 2.9 13.8 2 15 2 L17 2 M14 27 L14.3 27.7 Q14.6 28 15 28 L17 28 17.7 27.7 18 27 18 18.05 18.05 18 27 18 Q27.4 18 27.7 17.7 L28 17 28 15 27.7 14.3 Q27.4 14 27 14 L18 14 18 5 17.7 4.3 17 4 15 4 Q14.6 4 14.3 4.3 14 4.6 14 5 L14 14 5 14 Q4.6 14 4.3 14.3 4 14.6 4 15 L4 17 Q4 17.4 4.3 17.7 4.6 18 5 18 L14 18 14 27","M14 27 L14 18 5 18 Q4.6 18 4.3 17.7 4 17.4 4 17 L4 15 Q4 14.6 4.3 14.3 4.6 14 5 14 L14 14 14 5 Q14 4.6 14.3 4.3 14.6 4 15 4 L17 4 17.7 4.3 18 5 18 14 27 14 Q27.4 14 27.7 14.3 L28 15 28 17 27.7 17.7 Q27.4 18 27 18 L18.05 18 18 18.05 18 27 17.7 27.7 17 28 15 28 Q14.6 28 14.3 27.7 L14 27"),12,12,"crosshair"),XQ=m(i("M3.9 11.35 Q2.3 12.5 3.7 13.9 L16.4 26.65 Q17.85 28.05 19.45 26.9 L27.65 21.15 Q29.3 20 27.85 18.6 L15.15 5.85 Q13.75 4.45 12.1 5.6 L3.9 11.35 M1.05 12.4 Q1 10.95 2.75 9.75 L10.95 4 10.95 3.95 Q14 1.85 16.6 4.45 L29.3 17.2 Q30.8 18.65 30.55 20.1 30.55 21.55 28.8 22.8 L20.6 28.55 20.65 28.55 Q17.7 30.65 15 28.1 L15 28.05 2.3 15.3 2.3 15.35 Q0.8 13.85 1.05 12.4 M13.5 7 L19.85 13.35 11.65 19.15 5.3 12.75 13.5 7","M13.5 7 L5.3 12.75 11.65 19.15 19.85 13.35 13.5 7 M3.9 11.35 L12.1 5.6 Q13.75 4.45 15.15 5.85 L27.85 18.6 Q29.3 20 27.65 21.15 L19.45 26.9 Q17.85 28.05 16.4 26.65 L3.7 13.9 Q2.3 12.5 3.9 11.35"),6,14,"cell"),YQ=m(`<svg ${T7}><path d='M16 4V28M11 4H21M11 28H21' fill='none' ${k7} stroke-width='5'/><path d='M16 4V28M11 4H21M11 28H21' fill='none' stroke='${E7}' stroke-width='2.25' stroke-linecap='round'/></svg>`,12,12,"text"),HQ=m(`<svg ${T7}><path d='M6 5H21L26 10V27H6Z' fill='${E7}' ${k7} stroke-width='2.5'/><path d='M21 5V11H26' fill='none' ${k7} stroke-width='2.25'/></svg>`,5,5,"crosshair"),C=Object.freeze({browse:"default",move:BQ,hand:WQ,comment:KQ,pen:zQ,section:Q7,highlighter:UQ,shape:Q7,rect:Q7,ellipse:Q7,sticky:HQ,arrow:Q7,text:YQ,eraser:XQ});import{jsx as w7,Fragment as MQ}from"react/jsx-runtime";var ZJ=Object.freeze({preview:"browse",edit:"move"});function qJ(J){if(J==="browse")return"preview";if(J==="move")return"edit";return null}var DQ=Object.freeze([{id:"browse",label:"Browse",shortcut:"",cursor:C.browse},{id:"move",label:"Select",shortcut:"V",cursor:C.move},{id:"hand",label:"Hand",shortcut:"H",cursor:C.hand},{id:"comment",label:"Comment",shortcut:"C",cursor:C.comment},{id:"pen",label:"Pen",shortcut:"B",cursor:C.pen},{id:"highlighter",label:"Highlighter",shortcut:"I",cursor:C.highlighter},{id:"shape",label:"Shape",shortcut:"R",cursor:C.shape},{id:"sticky",label:"Sticky",shortcut:"N",cursor:C.sticky},{id:"section",label:"Section",shortcut:"⇧S",cursor:C.shape},{id:"arrow",label:"Arrow",shortcut:"A",cursor:C.arrow},{id:"text",label:"Text",shortcut:"T",cursor:C.text},{id:"eraser",label:"Eraser",shortcut:"E",cursor:C.eraser}]),jQ=new Set(["browse","move","hand"]);function LQ(J,Q){return Q?J.filter(($)=>jQ.has($.id)):J}var x7=FQ(null);function NQ({children:J,tools:Q=DQ,initial:$,initialMode:Z}){let q=B7(),G=VJ(()=>LQ(Q,q),[Q,q]),z=$??(q?"browse":"move"),X=Z??qJ(z)??(q?"preview":"edit"),[Y,_]=U7(z),[L,U]=U7(X),[W,P]=U7(()=>({tool:null,locked:!1})),H=$7((M)=>{if(!G.some((F)=>F.id===M))return;_(M);let A=qJ(M);if(A)U(A);P((F)=>F.locked&&F.tool===M?F:{tool:null,locked:!1})},[G]),j=$7((M)=>{let A=ZJ[M];if(!G.some((F)=>F.id===A))return;U(M),_(A),P((F)=>F.locked&&F.tool===A?F:{tool:null,locked:!1})},[G]),I=$7(()=>{H(ZJ[L])},[L,H]),V=$7((M)=>{P((A)=>{if(A.locked&&A.tool===M)return{tool:null,locked:!1};return{tool:M,locked:!0}}),_(M)},[]),K=$7(()=>{P({tool:null,locked:!1})},[]),[B,D]=U7("rounded");PQ(()=>{if(typeof document>"u")return;let M=G.find((O)=>O.id===Y);if(!M)return;let A=document.body.style.cursor,F=document.getElementById("dc-tool-cursor");if(!F)F=document.createElement("style"),F.id="dc-tool-cursor",document.head.appendChild(F);if(Y==="browse"){if(document.body.style.cursor="",F.textContent="",typeof window<"u"&&window.parent&&window.parent!==window)try{window.parent.postMessage({dgn:"tool-cursor",tool:Y},"*")}catch{}return()=>{document.body.style.cursor=A}}if(document.body.style.cursor=M.cursor,F.textContent=`* { cursor: ${M.cursor} !important; }`,typeof window<"u"&&window.parent&&window.parent!==window)try{window.parent.postMessage({dgn:"tool-cursor",tool:Y},"*")}catch{}return()=>{document.body.style.cursor=A;let O=document.getElementById("dc-tool-cursor");if(O)O.textContent=""}},[Y,G]);let N=VJ(()=>({tool:Y,setTool:H,tools:G,mode:L,setMode:j,resetTool:I,sticky:W,toggleSticky:V,clearSticky:K,shapeKind:B,setShapeKind:D}),[Y,H,G,L,j,I,W,V,K,B]);return w7(x7.Provider,{value:N,children:J})}function BJ({children:J,initial:Q,initialMode:$}){if(GJ(x7))return w7(MQ,{children:J});return w7(NQ,{initial:Q,initialMode:$,children:J})}function X7(){let J=GJ(x7);if(!J)throw Error("useToolMode must be used inside <ToolProvider>");return J}import{jsx as CQ}from"react/jsx-runtime";var IQ=`
2
2
  .dc-el-resize-handle {
3
3
  position: fixed;
4
4
  width: 8px;
@@ -56,4 +56,4 @@ import{Component as vQ,createElement as g,Fragment as CQ,useCallback as x7,useEf
56
56
  @media (prefers-reduced-motion: reduce) {
57
57
  .dc-el-resize-handle, .dc-el-resize-readout { transition-duration: 1ms; }
58
58
  }
59
- `.trim();function _Q(){if(typeof document>"u")return;if(document.getElementById("dc-el-resize-css"))return;let J=document.createElement("style");J.id="dc-el-resize-css",J.textContent=NQ,document.head.appendChild(J)}var IQ=["nw","n","ne","e","se","s","sw","w"];function AQ(J){return{movesLeft:J==="nw"||J==="w"||J==="sw",movesRight:J==="ne"||J==="e"||J==="se",movesTop:J==="nw"||J==="n"||J==="ne",movesBottom:J==="sw"||J==="s"||J==="se"}}var n=(J)=>Math.round(J*100)/100,U7=1;function OQ(J,Q,$,Z,q,G){let{movesLeft:K,movesRight:z,movesTop:H,movesBottom:j}=AQ(J),L=q.center,U=Q.w,B=Q.h;if(z)U=Q.w+(L?2*$:$);else if(K)U=Q.w-(L?2*$:$);if(j)B=Q.h+(L?2*Z:Z);else if(H)B=Q.h-(L?2*Z:Z);if(q.aspect&&Q.w>0&&Q.h>0){let Y=Q.w/Q.h;if((K||z)&&(H||j)){let _=Math.abs(U-Q.w)/Q.w,V=Math.abs(B-Q.h)/Q.h;if(_>=V)B=U/Y;else U=B*Y}else if(K||z)B=U/Y;else if(H||j)U=B*Y}if(U<U7)U=U7;if(B<U7)B=U7;let F={width:n(U),height:n(B)};if(L){if(G.canMoveLeft&&(K||z))F.left=n(Q.left+(Q.w-U)/2);if(G.canMoveTop&&(H||j))F.top=n(Q.top+(Q.h-B)/2)}else{if(G.canMoveLeft&&K)F.left=n(Q.left+Q.w-U);if(G.canMoveTop&&H)F.top=n(Q.top+Q.h-B)}return F}function BJ(J){if(!J||J==="none")return 0;let Q=/matrix\(([^)]+)\)/.exec(J);if(!Q)return 0;let $=Q[1].split(",").map(Number),Z=$[0]??1,q=$[1]??0;return Math.round(Math.atan2(q,Z)*(180/Math.PI)*100)/100}function TQ(J){if(!J||J==="none")return 1;let Q=/matrix\(([^)]+)\)/.exec(J);if(!Q)return 1;let $=Q[1].split(",").map(Number),Z=$[0]??1,q=$[1]??0,G=Math.hypot(Z,q);return G>0?G:1}function kQ(J){let Q=J.closest(".dc-world");if(!Q)return 1;let $=getComputedStyle(Q),Z=Number.parseFloat($.zoom||"1")||1;return TQ($.transform)*Z}function WJ(J,Q,$){let Z=$*Math.PI/180,q=Math.cos(Z),G=Math.sin(Z);return[J*q-Q*G,J*G+Q*q]}function KJ(J,Q,$,Z){return Math.atan2(Z-Q,$-J)}function EQ(J,Q,$,Z){let q=J+($-Q)*(180/Math.PI);while(q>180)q-=360;while(q<=-180)q+=360;if(Z)q=Math.round(q/15)*15;return Math.round(q*100)/100}function wQ(J,Q){let $={width:`${Q.width}px`,height:`${Q.height}px`};if(typeof Q.left==="number")$.left=`${Q.left}px`;if(typeof Q.top==="number")$.top=`${Q.top}px`;try{window.parent.postMessage({dgn:"resize-request",id:J.cdId,patch:$,before:J.before,idIndex:J.idIndex},"*")}catch{}}function bQ(J,Q){if(!J.artboardId)return;try{window.parent.postMessage({dgn:"resize-artboard-request",artboardId:J.artboardId,width:Q.width,height:Q.height},"*")}catch{}}function xQ(J,Q){try{window.parent.postMessage({dgn:"resize-request",id:J.cdId,patch:{transform:Q},before:J.before,idIndex:J.idIndex},"*")}catch{}}function XJ(){_Q();let{selected:J}=W7(),{tool:Q}=X7(),$=z7(null),Z=z7(null),q=z7(null),G=z7(null),K=J.length===1?J[0]:null,z=K&&typeof K.id==="string"?K.id:null,H=K&&!z&&typeof K.artboardId==="string"?K.artboardId:null,j=Q==="move"&&(!!z||!!H);GJ(()=>{let U=$.current;if(!U)return;let B=()=>{for(let Y of Array.from(U.children)){let D=Y;D.style.opacity="0",D.style.pointerEvents="none"}};if(!j||!K){B();return}let F=()=>{if(Z.current=null,QJ()){B(),Z.current=requestAnimationFrame(F);return}let Y=F7(document,K);if(!Y){B(),Z.current=requestAnimationFrame(F);return}let D=Y.getBoundingClientRect();if(D.width<=0&&D.height<=0){B(),Z.current=requestAnimationFrame(F);return}let _=H?["e","s","se"]:IQ,V=H?[]:["rot-nw","rot-ne","rot-sw","rot-se"],X=_.length+V.length+1;while(U.children.length<X)U.appendChild(document.createElement("div"));while(U.children.length>X)U.lastChild&&U.removeChild(U.lastChild);let W=D.left+D.width/2,P=D.top+D.height/2,N=BJ(getComputedStyle(Y).transform),I=kQ(Y),A=Y.offsetWidth*I/2,M=Y.offsetHeight*I/2,T={nw:[-A,-M],n:[0,-M],ne:[A,-M],e:[A,0],se:[A,M],s:[0,M],sw:[-A,M],w:[-A,0],"rot-nw":[-A,-M],"rot-ne":[A,-M],"rot-sw":[-A,M],"rot-se":[A,M]},E=[...V,..._];for(let h=0;h<E.length;h++){let b=E[h],v=U.children[h],[d,c]=T[b]??[0,0],[FJ,PJ]=WJ(d,c,N),DJ=W+FJ,MJ=P+PJ,Y7=b.startsWith("rot-"),v7=b==="n"||b==="s",C7=b==="e"||b==="w",jJ=Y7?10:v7?7:C7?3:4,LJ=Y7?10:v7?3:C7?7:4;v.className="dc-el-resize-handle",v.dataset.corner=b,v.style.opacity="1",v.style.pointerEvents="auto",v.style.left=`${Math.round(DJ-jJ)}px`,v.style.top=`${Math.round(MJ-LJ)}px`,v.style.transform=Y7?"":`rotate(${N}deg)`}let y=U.children[E.length],w=q.current;if(w&&w.el===Y&&!w.corner.startsWith("rot-")){let h=w.lastResult?.width??Y.offsetWidth,b=w.lastResult?.height??Y.offsetHeight,v=`${Math.round(h)} × ${Math.round(b)}`,d=w.lastResult?.left,c=w.lastResult?.top;if(typeof d==="number"||typeof c==="number")v+=` · ${Math.round(d??w.start.left)}, ${Math.round(c??w.start.top)}`;y.className="dc-el-resize-readout",y.textContent=v,y.style.opacity="1",y.style.left=`${Math.round(W)}px`,y.style.top=`${Math.round(P+M)}px`}else y.style.opacity="0";Z.current=requestAnimationFrame(F)};return Z.current=requestAnimationFrame(F),()=>{if(Z.current!=null)cancelAnimationFrame(Z.current)}},[j,K,H]);let L=LQ((U,B)=>{if(U.el.style.width=`${B.width}px`,U.el.style.height=`${B.height}px`,typeof B.left==="number")U.el.style.left=`${B.left}px`;if(typeof B.top==="number")U.el.style.top=`${B.top}px`;U.lastResult=B},[]);return GJ(()=>{let U=$.current;if(!U)return;let B=(V,X)=>{let[W,P]=WJ(X.clientX-V.startClientX,X.clientY-V.startClientY,-V.angle);return OQ(V.corner,V.start,W/V.elZoom,P/V.elZoom,{aspect:!!X.shiftKey,center:!V.artboardId&&!!X.altKey},V.flags)},F=(V)=>{let X=V.target;if(!X?.classList.contains("dc-el-resize-handle"))return;let W=X.dataset.corner;if(!W||!K)return;let P=typeof K.id==="string"?K.id:null,N=!P&&typeof K.artboardId==="string"?K.artboardId:null;if(!P&&!N)return;let I=F7(document,K);if(!I)return;V.preventDefault(),V.stopPropagation();let A=I.getBoundingClientRect(),M=I.offsetWidth?A.width/I.offsetWidth:1,T=getComputedStyle(I),E=!N&&(T.position==="absolute"||T.position==="fixed"),y=N?Number.NaN:Number.parseFloat(I.style.left),w=N?Number.NaN:Number.parseFloat(I.style.top),h=N?0:BJ(T.transform),b=M>0?M:1,v=A.left+A.width/2,d=A.top+A.height/2,c={pointerId:V.pointerId,corner:W,el:I,cdId:P??"",artboardId:N,idIndex:P?f7(document,P,I):0,startClientX:V.clientX,startClientY:V.clientY,elZoom:b,angle:h,cx:v,cy:d,rotStartPointer:KJ(v,d,V.clientX,V.clientY),start:{w:(h?I.offsetWidth:A.width/b)||A.width/b,h:(h?I.offsetHeight:A.height/b)||A.height/b,left:y,top:w},flags:{canMoveLeft:E&&Number.isFinite(y),canMoveTop:E&&Number.isFinite(w)},before:{width:I.style.width||null,height:I.style.height||null,left:I.style.left||null,top:I.style.top||null,transform:I.style.transform||null},lastResult:null,lastTransform:null};q.current=c;try{X.setPointerCapture(V.pointerId)}catch{}},Y=(V)=>{let X=q.current;if(!X||V.pointerId!==X.pointerId)return;if(V.preventDefault(),X.corner.startsWith("rot-")){let P=`rotate(${EQ(X.angle,X.rotStartPointer,KJ(X.cx,X.cy,V.clientX,V.clientY),!!V.shiftKey)}deg)`;X.el.style.transform=P,X.lastTransform=P;return}L(X,B(X,V))},D=(V)=>{let X=q.current;if(!X||V.pointerId!==X.pointerId)return;if(q.current=null,X.corner.startsWith("rot-")){let N=X.lastTransform;if(!N||N===X.before.transform)return;G.current={el:X.el,before:X.before},xQ(X,N);return}let W=X.lastResult??B(X,V);if(!(`${W.width}px`!==X.before.width||`${W.height}px`!==X.before.height||typeof W.left==="number"&&`${W.left}px`!==X.before.left||typeof W.top==="number"&&`${W.top}px`!==X.before.top))return;if(G.current={el:X.el,before:X.before},X.artboardId)bQ(X,W);else wQ(X,W)},_=(V)=>{let X=V.data;if(X?.dgn!=="resize-failed"&&X?.dgn!=="resize-artboard-failed")return;if(V.source!==window.parent)return;let W=G.current;if(!W)return;if(W.el.style.width=W.before.width??"",W.el.style.height=W.before.height??"",W.before.left!==null||W.el.style.left)W.el.style.left=W.before.left??"";if(W.before.top!==null||W.el.style.top)W.el.style.top=W.before.top??"";if(W.before.transform!==null||W.el.style.transform)W.el.style.transform=W.before.transform??"";G.current=null};return U.addEventListener("pointerdown",F),window.addEventListener("pointermove",Y),window.addEventListener("pointerup",D),window.addEventListener("pointercancel",D),window.addEventListener("message",_),()=>{U.removeEventListener("pointerdown",F),window.removeEventListener("pointermove",Y),window.removeEventListener("pointerup",D),window.removeEventListener("pointercancel",D),window.removeEventListener("message",_)}},[K,L]),yQ("div",{ref:$,"aria-hidden":"true"})}import{jsx as o,jsxs as lQ}from"react/jsx-runtime";var gQ=new Set(["drop-comment","tool","escape","hover"]);function V7(){return typeof document<"u"&&!document.querySelector(".dc-canvas")}function y7(J,Q){if(typeof document>"u")return null;let $=document.elementFromPoint(J,Q);if(!$)return null;if($.closest(".cm-composer, .cm-thread, .cm-mention-popup, .cm-pin, [data-mc-hover-halo], [data-mc-selection-halo], .dc-el-resize-handle"))return null;let Z=$.tagName;if(Z==="HTML"||Z==="BODY")return null;return $}function hQ(J,Q){let $=y7(J,Q);if(!$)return null;return $.closest("[data-cd-id]")??$}function fQ({children:J,file:Q}){let{tool:$,setTool:Z}=X7(),q=W7(),G=p(null),[K,z]=$7(null),H=p($);H.current=$;let j=SQ(()=>()=>H.current,[]);f(()=>{if($!=="comment")z(null)},[$]);let[L,U]=$7(null),[B,F]=$7(!1);return f(()=>{let Y=()=>F(V7());Y();let D=requestAnimationFrame(Y),_=setTimeout(Y,120);return()=>{cancelAnimationFrame(D),clearTimeout(_)}},[]),f(()=>{if(typeof document>"u")return;let Y=(D)=>{if(D.button!==0||!(D.metaKey||D.ctrlKey))return;if(!V7())return;if(J7(D.target))return;let _=hQ(D.clientX,D.clientY);if(!_)return;D.preventDefault(),D.stopImmediatePropagation();let V=_.getAttribute("data-cd-id"),X=P7({el:_,cdId:V,artboardId:null});if(D.shiftKey)q.add(X);else q.replace(X);U(_)};return document.addEventListener("pointerdown",Y,!0),()=>document.removeEventListener("pointerdown",Y,!0)},[q]),f(()=>{if(q.selected.length===0)U(null)},[q.selected]),f(()=>{let Y=G.current;if(Y)Y.setAttribute("data-active-tool",$);if(typeof document<"u"&&document.body)document.body.setAttribute("data-active-tool",$);return()=>{Y?.removeAttribute("data-active-tool")}},[$]),f(()=>{if(typeof window>"u")return;let Y=(D)=>{let _=D.data;if(!_||typeof _!=="object"||_.dgn!=="tool-set")return;if(typeof _.tool==="string")Z(_.tool)};return window.addEventListener("message",Y),()=>window.removeEventListener("message",Y)},[Z]),JJ({hostRef:G,getActiveTool:j,claimableActions:gQ,callbacks:{onHover:({clientX:Y,clientY:D})=>{if(H.current!=="comment"||!V7()){z(null);return}let _=y7(Y,D);z((V)=>V===_?V:_)},onTool:({tool:Y})=>Z(Y),onEscape:()=>{if(H.current!=="move")Z("move");if(z(null),q.clear(),typeof window<"u")try{window.parent.postMessage({dgn:"force-clear"},"*")}catch{}},onDropComment:({clientX:Y,clientY:D})=>mQ(Y,D,q,Q)}}),lQ("div",{"data-mc-host":!0,ref:G,style:{display:"contents"},children:[J,K?o(uQ,{el:K}):null,L?o(pQ,{el:L}):null,B?o(XJ,{}):null,o(a7,{})]})}function pQ({el:J}){let Q=p(null),$=p(J);$.current=J;let Z=p(null);return f(()=>{let q=()=>{Z.current=null;let G=Q.current,K=$.current;if(G&&K?.isConnected){let z=K.getBoundingClientRect();if(z.width===0&&z.height===0)G.style.display="none";else G.style.display="block",G.style.left=`${Math.round(z.left)}px`,G.style.top=`${Math.round(z.top)}px`,G.style.width=`${Math.round(z.width)}px`,G.style.height=`${Math.round(z.height)}px`}else if(G)G.style.display="none";Z.current=requestAnimationFrame(q)};return Z.current=requestAnimationFrame(q),()=>{if(Z.current!=null)cancelAnimationFrame(Z.current)}},[]),o("div",{ref:Q,"aria-hidden":"true","data-mc-selection-halo":"",style:{position:"fixed",display:"none",pointerEvents:"none",zIndex:2147483645,border:"1.5px solid var(--maude-hud-accent, oklch(0.680 0.180 268))",borderRadius:"3px",boxSizing:"border-box"}})}function uQ({el:J}){let Q=p(null),$=p(J);$.current=J;let Z=p(null);return f(()=>{let q=()=>{Z.current=null;let G=Q.current,K=$.current;if(G&&K?.isConnected){let z=K.getBoundingClientRect();if(z.width===0&&z.height===0)G.style.display="none";else G.style.display="block",G.style.left=`${Math.round(z.left)}px`,G.style.top=`${Math.round(z.top)}px`,G.style.width=`${Math.round(z.width)}px`,G.style.height=`${Math.round(z.height)}px`}else if(G)G.style.display="none";Z.current=requestAnimationFrame(q)};return Z.current=requestAnimationFrame(q),()=>{if(Z.current!=null)cancelAnimationFrame(Z.current)}},[]),o("div",{ref:Q,"aria-hidden":"true","data-mc-hover-halo":"",style:{position:"fixed",display:"none",pointerEvents:"none",zIndex:2147483646,border:"2px solid var(--maude-hud-accent, #d63b1f)",borderRadius:"3px",boxSizing:"border-box"}})}function mQ(J,Q,$,Z){if(typeof document>"u")return;let q=I7(document,J,Q,{deep:!0});if(!q)q=I7(document,J,Q,{deep:!1});if(!q&&!V7()&&typeof document.elementsFromPoint==="function"){let K=document.elementsFromPoint(J,Q);for(let z of K){let H=z.closest?.("[data-cd-id]");if(!H)continue;if(!H.closest(".dc-artboard-body"))continue;let j=H.closest("[data-dc-screen]");q={el:H,cdId:H.getAttribute("data-cd-id"),artboardId:j?.getAttribute("data-dc-screen")??null};break}}if(!q&&V7()){let K=y7(J,Q);if(K)q={el:K,cdId:K.getAttribute("data-cd-id"),artboardId:null}}if(!q){let K={file:Z,id:void 0,selector:"",artboardId:null,tag:"",classes:"",text:"",dom_path:[],bounds:{x:J-12,y:Q-12,w:24,h:24},html:""};zJ(K,J,Q);return}let G=P7(q,Z);$.replace(G),zJ(G,J,Q)}function zJ(J,Q,$){if(typeof document<"u")try{document.dispatchEvent(new CustomEvent("cm:open-composer",{detail:{selection:J,clientX:Q,clientY:$}}))}catch{}if(typeof window<"u")try{window.parent.postMessage({dgn:"comment-compose",selection:J},"*")}catch{}}function YJ(J,Q){return g(qJ,null,g(i7,null,g(fQ,{file:Q},g(J))))}function e0(J,Q){let $=RQ(Q.rootEl);if(!Q.commentsEnabled){$.render(g(J));return}let Z=Q.file??H7();$.render(g(cQ,{initialCanvas:J,file:Z}))}var UJ="__maudeCanvasRuntime";function dQ({Canvas:J,file:Q,onOk:$}){return f(()=>{$()},[]),YJ(J,Q)}class HJ extends vQ{state={hasError:!1};static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(){this.props.onError()}componentDidUpdate(J){if(J.attempt!==this.props.attempt&&this.state.hasError)this.setState({hasError:!1})}render(){if(this.state.hasError)return this.props.fallback();return this.props.children}}function iQ({message:J}){return g("div",{className:"dc-hmr-holding",role:"status","aria-live":"polite",title:J?`Holding last working render — ${J}`:"Holding last working render"},"⏸ build error — držím poslední funkční verzi")}function cQ({initialCanvas:J,file:Q}){let[{canvas:$,attempt:Z},q]=$7({canvas:J,attempt:0}),[G,K]=$7({on:!1}),z=p(null),H=p($);H.current=$,f(()=>{let B={remount:(F)=>q((Y)=>({canvas:F,attempt:Y.attempt+1})),setHolding:(F,Y)=>K(F?{on:!0,message:Y}:{on:!1})};return window[UJ]=B,()=>{window[UJ]=void 0}},[]);let j=x7(()=>{z.current=H.current,K((B)=>B.on?{on:!1}:B)},[]),L=x7(()=>{K({on:!0,message:"render error"})},[]),U=x7(()=>{let B=z.current;return B?YJ(B,Q):null},[Q]);return g(CQ,null,g(HJ,{attempt:Z,onError:L,fallback:U},g(dQ,{key:Z,Canvas:$,file:Q,onOk:j})),G.on?g(iQ,{message:G.message}):null)}export{hQ as pickSpecimenSelectEl,e0 as mountCanvas,V7 as isBareSpecimen,HJ as CanvasErrorBoundary};
59
+ `.trim();function AQ(){if(typeof document>"u")return;if(document.getElementById("dc-el-resize-css"))return;let J=document.createElement("style");J.id="dc-el-resize-css",J.textContent=IQ,document.head.appendChild(J)}var OQ=["nw","n","ne","e","se","s","sw","w"];function kQ(J){return{movesLeft:J==="nw"||J==="w"||J==="sw",movesRight:J==="ne"||J==="e"||J==="se",movesTop:J==="nw"||J==="n"||J==="ne",movesBottom:J==="sw"||J==="s"||J==="se"}}var r=(J)=>Math.round(J*100)/100,H7=1;function TQ(J,Q,$,Z,q,G){let{movesLeft:z,movesRight:X,movesTop:Y,movesBottom:_}=kQ(J),L=q.center,U=Q.w,W=Q.h;if(X)U=Q.w+(L?2*$:$);else if(z)U=Q.w-(L?2*$:$);if(_)W=Q.h+(L?2*Z:Z);else if(Y)W=Q.h-(L?2*Z:Z);if(q.aspect&&Q.w>0&&Q.h>0){let H=Q.w/Q.h;if((z||X)&&(Y||_)){let I=Math.abs(U-Q.w)/Q.w,V=Math.abs(W-Q.h)/Q.h;if(I>=V)W=U/H;else U=W*H}else if(z||X)W=U/H;else if(Y||_)U=W*H}if(U<H7)U=H7;if(W<H7)W=H7;let P={width:r(U),height:r(W)};if(L){if(G.canMoveLeft&&(z||X))P.left=r(Q.left+(Q.w-U)/2);if(G.canMoveTop&&(Y||_))P.top=r(Q.top+(Q.h-W)/2)}else{if(G.canMoveLeft&&z)P.left=r(Q.left+Q.w-U);if(G.canMoveTop&&Y)P.top=r(Q.top+Q.h-W)}return P}function KJ(J){if(!J||J==="none")return 0;let Q=/matrix\(([^)]+)\)/.exec(J);if(!Q)return 0;let $=Q[1].split(",").map(Number),Z=$[0]??1,q=$[1]??0;return Math.round(Math.atan2(q,Z)*(180/Math.PI)*100)/100}function EQ(J){if(!J||J==="none")return 1;let Q=/matrix\(([^)]+)\)/.exec(J);if(!Q)return 1;let $=Q[1].split(",").map(Number),Z=$[0]??1,q=$[1]??0,G=Math.hypot(Z,q);return G>0?G:1}function wQ(J){let Q=J.closest(".dc-world");if(!Q)return 1;let $=getComputedStyle(Q),Z=Number.parseFloat($.zoom||"1")||1;return EQ($.transform)*Z}function zJ(J,Q,$){let Z=$*Math.PI/180,q=Math.cos(Z),G=Math.sin(Z);return[J*q-Q*G,J*G+Q*q]}function UJ(J,Q,$,Z){return Math.atan2(Z-Q,$-J)}function xQ(J,Q,$,Z){let q=J+($-Q)*(180/Math.PI);while(q>180)q-=360;while(q<=-180)q+=360;if(Z)q=Math.round(q/15)*15;return Math.round(q*100)/100}function bQ(J,Q){let $={width:`${Q.width}px`,height:`${Q.height}px`};if(typeof Q.left==="number")$.left=`${Q.left}px`;if(typeof Q.top==="number")$.top=`${Q.top}px`;try{window.parent.postMessage({dgn:"resize-request",id:J.cdId,patch:$,before:J.before,idIndex:J.idIndex},"*")}catch{}}function yQ(J,Q){if(!J.artboardId)return;try{window.parent.postMessage({dgn:"resize-artboard-request",artboardId:J.artboardId,width:Q.width,height:Q.height},"*")}catch{}}function vQ(J,Q){try{window.parent.postMessage({dgn:"resize-request",id:J.cdId,patch:{transform:Q},before:J.before,idIndex:J.idIndex},"*")}catch{}}function XJ(){AQ();let{selected:J}=K7(),{tool:Q}=X7(),$=Y7(null),Z=Y7(null),q=Y7(null),G=Y7(null),z=J.length===1?J[0]:null,X=z&&typeof z.id==="string"?z.id:null,Y=z&&!X&&typeof z.artboardId==="string"?z.artboardId:null,_=Q==="move"&&(!!X||!!Y);WJ(()=>{let U=$.current;if(!U)return;let W=()=>{for(let H of Array.from(U.children)){let j=H;j.style.opacity="0",j.style.pointerEvents="none"}};if(!_||!z){W();return}let P=()=>{if(Z.current=null,QJ()){W(),Z.current=requestAnimationFrame(P);return}let H=D7(document,z);if(!H){W(),Z.current=requestAnimationFrame(P);return}let j=H.getBoundingClientRect();if(j.width<=0&&j.height<=0){W(),Z.current=requestAnimationFrame(P);return}let I=Y?["e","s","se"]:OQ,V=Y?[]:["rot-nw","rot-ne","rot-sw","rot-se"],K=I.length+V.length+1;while(U.children.length<K)U.appendChild(document.createElement("div"));while(U.children.length>K)U.lastChild&&U.removeChild(U.lastChild);let B=j.left+j.width/2,D=j.top+j.height/2,N=KJ(getComputedStyle(H).transform),M=wQ(H),A=H.offsetWidth*M/2,F=H.offsetHeight*M/2,O={nw:[-A,-F],n:[0,-F],ne:[A,-F],e:[A,0],se:[A,F],s:[0,F],sw:[-A,F],w:[-A,0],"rot-nw":[-A,-F],"rot-ne":[A,-F],"rot-sw":[-A,F],"rot-se":[A,F]},E=[...V,...I];for(let g=0;g<E.length;g++){let x=E[g],v=U.children[g],[d,c]=O[x]??[0,0],[DJ,jJ]=zJ(d,c,N),LJ=B+DJ,NJ=D+jJ,F7=x.startsWith("rot-"),v7=x==="n"||x==="s",C7=x==="e"||x==="w",MJ=F7?10:v7?7:C7?3:4,_J=F7?10:v7?3:C7?7:4;v.className="dc-el-resize-handle",v.dataset.corner=x,v.style.opacity="1",v.style.pointerEvents="auto",v.style.left=`${Math.round(LJ-MJ)}px`,v.style.top=`${Math.round(NJ-_J)}px`,v.style.transform=F7?"":`rotate(${N}deg)`}let y=U.children[E.length],w=q.current;if(w&&w.el===H&&!w.corner.startsWith("rot-")){let g=w.lastResult?.width??H.offsetWidth,x=w.lastResult?.height??H.offsetHeight,v=`${Math.round(g)} × ${Math.round(x)}`,d=w.lastResult?.left,c=w.lastResult?.top;if(typeof d==="number"||typeof c==="number")v+=` · ${Math.round(d??w.start.left)}, ${Math.round(c??w.start.top)}`;y.className="dc-el-resize-readout",y.textContent=v,y.style.opacity="1",y.style.left=`${Math.round(B)}px`,y.style.top=`${Math.round(D+F)}px`}else y.style.opacity="0";Z.current=requestAnimationFrame(P)};return Z.current=requestAnimationFrame(P),()=>{if(Z.current!=null)cancelAnimationFrame(Z.current)}},[_,z,Y]);let L=_Q((U,W)=>{if(U.el.style.width=`${W.width}px`,U.el.style.height=`${W.height}px`,typeof W.left==="number")U.el.style.left=`${W.left}px`;if(typeof W.top==="number")U.el.style.top=`${W.top}px`;U.lastResult=W},[]);return WJ(()=>{let U=$.current;if(!U)return;let W=(V,K)=>{let[B,D]=zJ(K.clientX-V.startClientX,K.clientY-V.startClientY,-V.angle);return TQ(V.corner,V.start,B/V.elZoom,D/V.elZoom,{aspect:!!K.shiftKey,center:!V.artboardId&&!!K.altKey},V.flags)},P=(V)=>{let K=V.target;if(!K?.classList.contains("dc-el-resize-handle"))return;let B=K.dataset.corner;if(!B||!z)return;let D=typeof z.id==="string"?z.id:null,N=!D&&typeof z.artboardId==="string"?z.artboardId:null;if(!D&&!N)return;let M=D7(document,z);if(!M)return;V.preventDefault(),V.stopPropagation();let A=M.getBoundingClientRect(),F=M.offsetWidth?A.width/M.offsetWidth:1,O=getComputedStyle(M),E=!N&&(O.position==="absolute"||O.position==="fixed"),y=N?Number.NaN:Number.parseFloat(M.style.left),w=N?Number.NaN:Number.parseFloat(M.style.top),g=N?0:KJ(O.transform),x=F>0?F:1,v=A.left+A.width/2,d=A.top+A.height/2,c={pointerId:V.pointerId,corner:B,el:M,cdId:D??"",artboardId:N,idIndex:D?f7(document,D,M):0,startClientX:V.clientX,startClientY:V.clientY,elZoom:x,angle:g,cx:v,cy:d,rotStartPointer:UJ(v,d,V.clientX,V.clientY),start:{w:(g?M.offsetWidth:A.width/x)||A.width/x,h:(g?M.offsetHeight:A.height/x)||A.height/x,left:y,top:w},flags:{canMoveLeft:E&&Number.isFinite(y),canMoveTop:E&&Number.isFinite(w)},before:{width:M.style.width||null,height:M.style.height||null,left:M.style.left||null,top:M.style.top||null,transform:M.style.transform||null},lastResult:null,lastTransform:null};q.current=c;try{K.setPointerCapture(V.pointerId)}catch{}},H=(V)=>{let K=q.current;if(!K||V.pointerId!==K.pointerId)return;if(V.preventDefault(),K.corner.startsWith("rot-")){let D=`rotate(${xQ(K.angle,K.rotStartPointer,UJ(K.cx,K.cy,V.clientX,V.clientY),!!V.shiftKey)}deg)`;K.el.style.transform=D,K.lastTransform=D;return}L(K,W(K,V))},j=(V)=>{let K=q.current;if(!K||V.pointerId!==K.pointerId)return;if(q.current=null,K.corner.startsWith("rot-")){let N=K.lastTransform;if(!N||N===K.before.transform)return;G.current={el:K.el,before:K.before},vQ(K,N);return}let B=K.lastResult??W(K,V);if(!(`${B.width}px`!==K.before.width||`${B.height}px`!==K.before.height||typeof B.left==="number"&&`${B.left}px`!==K.before.left||typeof B.top==="number"&&`${B.top}px`!==K.before.top))return;if(G.current={el:K.el,before:K.before},K.artboardId)yQ(K,B);else bQ(K,B)},I=(V)=>{let K=V.data;if(K?.dgn!=="resize-failed"&&K?.dgn!=="resize-artboard-failed")return;if(V.source!==window.parent)return;let B=G.current;if(!B)return;if(B.el.style.width=B.before.width??"",B.el.style.height=B.before.height??"",B.before.left!==null||B.el.style.left)B.el.style.left=B.before.left??"";if(B.before.top!==null||B.el.style.top)B.el.style.top=B.before.top??"";if(B.before.transform!==null||B.el.style.transform)B.el.style.transform=B.before.transform??"";G.current=null};return U.addEventListener("pointerdown",P),window.addEventListener("pointermove",H),window.addEventListener("pointerup",j),window.addEventListener("pointercancel",j),window.addEventListener("message",I),()=>{U.removeEventListener("pointerdown",P),window.removeEventListener("pointermove",H),window.removeEventListener("pointerup",j),window.removeEventListener("pointercancel",j),window.removeEventListener("message",I)}},[z,L]),CQ("div",{ref:$,"aria-hidden":"true"})}import{jsx as a,jsxs as rQ}from"react/jsx-runtime";var fQ=new Set(["drop-comment","tool","escape","hover"]);function Z7(){return typeof document<"u"&&!document.querySelector(".dc-canvas")}function y7(J,Q){if(typeof document>"u")return null;let $=document.elementFromPoint(J,Q);if(!$)return null;if($.closest(".cm-composer, .cm-thread, .cm-mention-popup, .cm-pin, [data-mc-hover-halo], [data-mc-selection-halo], .dc-el-resize-handle"))return null;let Z=$.tagName;if(Z==="HTML"||Z==="BODY")return null;return $}function pQ(J,Q){let $=y7(J,Q);if(!$)return null;return $.closest("[data-cd-id]")??$}function uQ({children:J,file:Q}){let{tool:$,setTool:Z}=X7(),q=K7(),G=p(null),[z,X]=V7(null),Y=p($);Y.current=$;let _=hQ(()=>()=>Y.current,[]);f(()=>{if($!=="comment")X(null)},[$]);let[L,U]=V7(null),[W,P]=V7(!1);return f(()=>{let H=()=>P(Z7());H();let j=requestAnimationFrame(H),I=setTimeout(H,120);return()=>{cancelAnimationFrame(j),clearTimeout(I)}},[]),f(()=>{if(typeof document>"u")return;let H=(j)=>{if(j.button!==0||!(j.metaKey||j.ctrlKey))return;if(!Z7())return;if(J7(j.target))return;let I=pQ(j.clientX,j.clientY);if(!I)return;j.preventDefault(),j.stopImmediatePropagation();let V=I.getAttribute("data-cd-id"),K=j7({el:I,cdId:V,artboardId:null});if(j.shiftKey)q.add(K);else q.replace(K);U(I)};return document.addEventListener("pointerdown",H,!0),()=>document.removeEventListener("pointerdown",H,!0)},[q]),f(()=>{if(q.selected.length===0)U(null)},[q.selected]),f(()=>{let H=G.current;if(H)H.setAttribute("data-active-tool",$);if(typeof document<"u"&&document.body)document.body.setAttribute("data-active-tool",$);return()=>{H?.removeAttribute("data-active-tool")}},[$]),f(()=>{if(typeof window>"u")return;let H=(j)=>{let I=j.data;if(!I||typeof I!=="object"||I.dgn!=="tool-set")return;if(typeof I.tool==="string")Z(I.tool)};return window.addEventListener("message",H),()=>window.removeEventListener("message",H)},[Z]),JJ({hostRef:G,getActiveTool:_,claimableActions:fQ,callbacks:{onHover:({clientX:H,clientY:j})=>{if(Y.current!=="comment"||!Z7()){X(null);return}let I=y7(H,j);X((V)=>V===I?V:I)},onTool:({tool:H})=>Z(H),onEscape:()=>{if(Y.current!=="move")Z("move");if(X(null),q.clear(),typeof window<"u")try{window.parent.postMessage({dgn:"force-clear"},"*")}catch{}},onDropComment:({clientX:H,clientY:j})=>iQ(H,j,q,Q)}}),rQ("div",{"data-mc-host":!0,ref:G,style:{display:"contents"},children:[J,z?a(dQ,{el:z}):null,L?a(mQ,{el:L}):null,W?a(XJ,{}):null,a(o7,{})]})}function mQ({el:J}){let Q=p(null),$=p(J);$.current=J;let Z=p(null);return f(()=>{let q=()=>{Z.current=null;let G=Q.current,z=$.current;if(G&&z?.isConnected){let X=z.getBoundingClientRect();if(X.width===0&&X.height===0)G.style.display="none";else G.style.display="block",G.style.left=`${Math.round(X.left)}px`,G.style.top=`${Math.round(X.top)}px`,G.style.width=`${Math.round(X.width)}px`,G.style.height=`${Math.round(X.height)}px`}else if(G)G.style.display="none";Z.current=requestAnimationFrame(q)};return Z.current=requestAnimationFrame(q),()=>{if(Z.current!=null)cancelAnimationFrame(Z.current)}},[]),a("div",{ref:Q,"aria-hidden":"true","data-mc-selection-halo":"",style:{position:"fixed",display:"none",pointerEvents:"none",zIndex:2147483645,border:"1.5px solid var(--maude-hud-accent, oklch(0.680 0.180 268))",borderRadius:"3px",boxSizing:"border-box"}})}function dQ({el:J}){let Q=p(null),$=p(J);$.current=J;let Z=p(null);return f(()=>{let q=()=>{Z.current=null;let G=Q.current,z=$.current;if(G&&z?.isConnected){let X=z.getBoundingClientRect();if(X.width===0&&X.height===0)G.style.display="none";else G.style.display="block",G.style.left=`${Math.round(X.left)}px`,G.style.top=`${Math.round(X.top)}px`,G.style.width=`${Math.round(X.width)}px`,G.style.height=`${Math.round(X.height)}px`}else if(G)G.style.display="none";Z.current=requestAnimationFrame(q)};return Z.current=requestAnimationFrame(q),()=>{if(Z.current!=null)cancelAnimationFrame(Z.current)}},[]),a("div",{ref:Q,"aria-hidden":"true","data-mc-hover-halo":"",style:{position:"fixed",display:"none",pointerEvents:"none",zIndex:2147483646,border:"2px solid var(--maude-hud-accent, #d63b1f)",borderRadius:"3px",boxSizing:"border-box"}})}function iQ(J,Q,$,Z){if(typeof document>"u")return;let q=O7(document,J,Q,{deep:!0});if(!q)q=O7(document,J,Q,{deep:!1});if(!q&&!Z7()&&typeof document.elementsFromPoint==="function"){let z=document.elementsFromPoint(J,Q);for(let X of z){let Y=X.closest?.("[data-cd-id]");if(!Y)continue;if(!Y.closest(".dc-artboard-body"))continue;let _=Y.closest("[data-dc-screen]");q={el:Y,cdId:Y.getAttribute("data-cd-id"),artboardId:_?.getAttribute("data-dc-screen")??null};break}}if(!q&&Z7()){let z=y7(J,Q);if(z)q={el:z,cdId:z.getAttribute("data-cd-id"),artboardId:null}}if(!q){let z={file:Z,id:void 0,selector:"",artboardId:null,tag:"",classes:"",text:"",dom_path:[],bounds:{x:J-12,y:Q-12,w:24,h:24},html:""};YJ(z,J,Q);return}let G=j7(q,Z);$.replace(G),YJ(G,J,Q)}function YJ(J,Q,$){if(typeof document<"u")try{document.dispatchEvent(new CustomEvent("cm:open-composer",{detail:{selection:J,clientX:Q,clientY:$}}))}catch{}if(typeof window<"u")try{window.parent.postMessage({dgn:"comment-compose",selection:J},"*")}catch{}}function FJ(J,Q){return h(BJ,{initial:"browse"},h(i7,null,h(uQ,{file:Q},h(J))))}function Q3(J,Q){let $=gQ(Q.rootEl);if(!Q.commentsEnabled){$.render(h(J));return}let Z=Q.file??P7();$.render(h(nQ,{initialCanvas:J,file:Z}))}var HJ="__maudeCanvasRuntime";function cQ({Canvas:J,file:Q,onOk:$}){return f(()=>{$()},[]),FJ(J,Q)}class PJ extends RQ{state={hasError:!1};static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(){this.props.onError()}componentDidUpdate(J){if(J.attempt!==this.props.attempt&&this.state.hasError)this.setState({hasError:!1})}render(){if(this.state.hasError)return this.props.fallback();return this.props.children}}function lQ({message:J}){return h("div",{className:"dc-hmr-holding",role:"status","aria-live":"polite",title:J?`Holding last working render — ${J}`:"Holding last working render"},"⏸ build error — držím poslední funkční verzi")}function nQ({initialCanvas:J,file:Q}){let[{canvas:$,attempt:Z},q]=V7({canvas:J,attempt:0}),[G,z]=V7({on:!1}),X=p(null),Y=p($);Y.current=$,f(()=>{let W={remount:(P)=>q((H)=>({canvas:P,attempt:H.attempt+1})),setHolding:(P,H)=>z(P?{on:!0,message:H}:{on:!1})};return window[HJ]=W,()=>{window[HJ]=void 0}},[]);let _=b7(()=>{X.current=Y.current,z((W)=>W.on?{on:!1}:W)},[]),L=b7(()=>{z({on:!0,message:"render error"})},[]),U=b7(()=>{let W=X.current;return W?FJ(W,Q):null},[Q]);return h(SQ,null,h(PJ,{attempt:Z,onError:L,fallback:U},h(cQ,{key:Z,Canvas:$,file:Q,onOk:_})),G.on?h(lQ,{message:G.message}):null)}export{pQ as pickSpecimenSelectEl,Q3 as mountCanvas,Z7 as isBareSpecimen,PJ as CanvasErrorBoundary};
@@ -511,3 +511,70 @@ export function hoverTargetToSelection(target: HoverTarget, file?: string): Sele
511
511
  ...styleMapsFor(el),
512
512
  };
513
513
  }
514
+
515
+ /**
516
+ * Build the comment-composer Selection for a right-click "Add comment"
517
+ * (context-menu.tsx's `element` / `artboard-chrome` / `world` targets share
518
+ * this one builder). When an element was under the cursor, delegates to
519
+ * `hoverTargetToSelection` — the exact anchor a comment-tool CLICK on that
520
+ * same element would produce, so a menu-driven comment and a drop-comment
521
+ * pin resolve identically. When there wasn't (empty canvas background, or an
522
+ * artboard's chrome/border rather than its body), returns a FLOATING
523
+ * selection pinned to the click point — the same shape
524
+ * canvas-comment-mount.tsx's `dropComment` uses for its own no-target
525
+ * fallback (issue-90).
526
+ */
527
+ export function buildComposeSelection(
528
+ target: { el: Element | null; cdId?: string | null; artboardId?: string | null },
529
+ clientX: number,
530
+ clientY: number,
531
+ file?: string
532
+ ): Selection {
533
+ if (target.el) {
534
+ return hoverTargetToSelection(
535
+ { el: target.el, cdId: target.cdId ?? null, artboardId: target.artboardId ?? null },
536
+ file
537
+ );
538
+ }
539
+ return {
540
+ file: file ?? deriveFile(),
541
+ selector: '',
542
+ artboardId: target.artboardId ?? null,
543
+ index: 0,
544
+ tag: '',
545
+ classes: '',
546
+ text: '',
547
+ dom_path: [],
548
+ bounds: { x: clientX - 12, y: clientY - 12, w: 24, h: 24 },
549
+ html: '',
550
+ };
551
+ }
552
+
553
+ /**
554
+ * Open the in-place comment composer for `selection`, anchored at
555
+ * `(clientX, clientY)`. The single choke point for the two-part signal every
556
+ * "add a comment here" affordance must send: `cm:open-composer` is what
557
+ * ACTUALLY opens the composer (`comments-overlay.tsx`'s own listener); the
558
+ * `comment-compose` postMessage is a secondary mirror so the parent shell's
559
+ * StatusBar/sidebar reflect the target too. A caller that only sends the
560
+ * second half opens nothing — canvas-shell.tsx's context-menu "Add comment"
561
+ * did exactly that until issue-90.
562
+ */
563
+ export function openCommentComposer(selection: Selection, clientX: number, clientY: number): void {
564
+ if (typeof document !== 'undefined') {
565
+ try {
566
+ document.dispatchEvent(
567
+ new CustomEvent('cm:open-composer', { detail: { selection, clientX, clientY } })
568
+ );
569
+ } catch {
570
+ /* CustomEvent unsupported — fall through */
571
+ }
572
+ }
573
+ if (typeof window !== 'undefined') {
574
+ try {
575
+ window.parent.postMessage({ dgn: 'comment-compose', selection }, '*');
576
+ } catch {
577
+ /* parent detached */
578
+ }
579
+ }
580
+ }
@@ -33,7 +33,7 @@ const DEBOUNCE_MS = 50;
33
33
 
34
34
  export interface HmrMessage {
35
35
  type: 'canvas-hmr';
36
- mode: 'css' | 'module' | 'hard' | 'meta';
36
+ mode: 'css' | 'module' | 'hard' | 'meta' | 'asset';
37
37
  /**
38
38
  * Canvas-relative path of the file that changed, slash-normalised. Absent
39
39
  * when mode === 'hard' (the change is global — every canvas reloads).
@@ -74,7 +74,13 @@ export function createHmrBroadcaster(
74
74
  // meta is the lightest signal — it doesn't trigger a reload, just re-fetches
75
75
  // the sidecar. CSS still ranks above it so a same-window CSS write wins over
76
76
  // a meta echo; hard tops everything.
77
- const rank: Record<HmrMessage['mode'], number> = { meta: 0, css: 1, module: 2, hard: 3 };
77
+ const rank: Record<HmrMessage['mode'], number> = {
78
+ meta: 0,
79
+ asset: 0,
80
+ css: 1,
81
+ module: 2,
82
+ hard: 3,
83
+ };
78
84
 
79
85
  function flush() {
80
86
  // A pending `hard` supersedes the per-file queue — every open canvas does a
@@ -169,9 +175,41 @@ export function classifyChange(
169
175
  if (ext === '.tsx' || ext === '.jsx' || ext === '.ts' || ext === '.js') {
170
176
  return { type: 'canvas-hmr', mode: 'module', file: rel, version, scope: 'canvas' };
171
177
  }
178
+ // 2026-08-15 annotations-assets RCA — a MEDIA file landing on disk (asset
179
+ // pull, file-plane pull, desktop push echo) is a heal signal, not a reload:
180
+ // any <img>/<image> that already 404'd on this name keeps the broken glyph
181
+ // forever (browsers never retry a failed load on their own). `mode:'asset'`
182
+ // tells open canvases to re-point matching, still-broken elements — no
183
+ // reload, no React state loss. Covers top-level `assets/` AND DS trees
184
+ // (`system/<ds>/assets/…`); `.part` staging files never match the ext set.
185
+ if (ASSET_MEDIA_EXTS.has(ext)) {
186
+ return { type: 'canvas-hmr', mode: 'asset', file: rel, version, scope: 'canvas' };
187
+ }
172
188
  return null;
173
189
  }
174
190
 
191
+ /** Media extensions worth a heal broadcast — the renderable subset of the
192
+ * asset lanes' vocabulary (fonts excluded: a font 404 heals only via a CSS
193
+ * re-evaluation, which is a reload — not worth forcing for the rare case). */
194
+ const ASSET_MEDIA_EXTS = new Set([
195
+ '.png',
196
+ '.jpg',
197
+ '.jpeg',
198
+ '.webp',
199
+ '.gif',
200
+ '.avif',
201
+ '.svg',
202
+ '.mp4',
203
+ '.webm',
204
+ '.mov',
205
+ '.m4v',
206
+ '.mp3',
207
+ '.wav',
208
+ '.m4a',
209
+ '.aac',
210
+ '.ogg',
211
+ ]);
212
+
175
213
  // ---------------------------------------------------------------------------
176
214
  // Container write bridge — inspector-edits-live-render RCA.
177
215
 
@@ -398,12 +398,36 @@ export function isEditableTarget(t: EventTarget | null): boolean {
398
398
  */
399
399
  export function isOverlayTarget(t: EventTarget | null): boolean {
400
400
  if (!t || !(t as Element).closest) return false;
401
+ const el = t as Element;
402
+ // Security review (issue-90) — `.dc-world` is exactly the subtree the
403
+ // active canvas's own JSX renders into (`canvas-lib.tsx`'s
404
+ // `<div className="dc-world">{children}</div>`); every selector below is
405
+ // shell-owned chrome that NEVER renders inside it (ToolPalette/
406
+ // AnnotationsLayer/ContextMenuView are siblings of `.dc-canvas`,
407
+ // DCZoomToolbar/DCMiniMap are children of `.dc-canvas` but siblings of
408
+ // `.dc-world`). Since untrusted, AI/user-authored canvas content is the one
409
+ // thing that DOES render inside `.dc-world`, it could otherwise spoof one
410
+ // of these class names on its own element to make the router yield to it
411
+ // (skip `preventDefault`) instead of claiming the gesture — bail out first
412
+ // so a same-name imposter inside the canvas never qualifies.
413
+ if (el.closest('.dc-world')) return false;
401
414
  // [data-mediaref-player] — the inline <video>/<audio controls> on a media
402
415
  // reference chip (DDR-150 dogfood #8). The router must never claim (and
403
416
  // preventDefault) pointerdowns over the player, or its native controls
404
417
  // (play button, scrubber drag, volume) die under the move tool.
405
- return !!(t as Element).closest(
406
- '.cm-composer, .cm-thread, .cm-mention-popup, .cm-pin, [data-mediaref-player]'
418
+ //
419
+ // .dc-tool-palette, .dc-zoom-tb, .dc-mm, .dc-context-menu (issue-90) — the
420
+ // shell's floating chrome renders as SIBLINGS of `.dc-canvas` but INSIDE
421
+ // this router's host (`[data-mc-host]` wraps the whole surface, chrome
422
+ // included). Without this exemption, once comment mode is armed every
423
+ // click on the palette/zoom-pill/minimap/context-menu was claimed as
424
+ // `drop-comment` (preventDefault + stopImmediatePropagation) and dropped a
425
+ // stray pin at the chrome's own coordinates instead of reaching its React
426
+ // onClick — `classifyContextKind` (canvas-shell.tsx) already treats these
427
+ // same selectors as `'overlay'`, non-canvas chrome; this router's claim
428
+ // gate was the one place that didn't.
429
+ return !!el.closest(
430
+ '.cm-composer, .cm-thread, .cm-mention-popup, .cm-pin, [data-mediaref-player], .dc-tool-palette, .dc-zoom-tb, .dc-mm, .dc-context-menu'
407
431
  );
408
432
  }
409
433
 
@@ -40,6 +40,7 @@ import type * as Y from 'yjs';
40
40
 
41
41
  import { atomicWrite } from './atomic-write.ts';
42
42
  import {
43
+ annotationsEditAtFromDoc,
43
44
  annotationsFromDoc,
44
45
  applyAnnotationsToDoc,
45
46
  applyCommentsToDoc,
@@ -50,14 +51,21 @@ import {
50
51
  commentsFromDoc,
51
52
  cssFromDoc,
52
53
  htmlFromDoc,
54
+ isEmptyAnnotationsSvg,
53
55
  markSeeded,
54
56
  mergeSharedMetaIntoLocal,
55
57
  metaFromDoc,
56
58
  seededByFromDoc,
59
+ stampAnnotationsEdit,
57
60
  stampBodyEdit,
58
61
  Y_SYNC_TYPES,
59
62
  } from './codec.ts';
60
- import { decideColdStart, isExactRepeat, unionCommentsById } from './cold-start.ts';
63
+ import {
64
+ decideAnnotationsColdStart,
65
+ decideColdStart,
66
+ isExactRepeat,
67
+ unionCommentsById,
68
+ } from './cold-start.ts';
61
69
  import { type EchoGuard, hashBytes } from './echo-guard.ts';
62
70
  import type { SyncJournal } from './journal.ts';
63
71
 
@@ -364,7 +372,15 @@ export function createCanvasSyncAgent(opts: CanvasSyncAgentOptions): CanvasSyncA
364
372
  return changed;
365
373
  }
366
374
  if (evt.path === paths.annotations) {
367
- const changed = applyAnnotationsToDoc(doc, str, origin);
375
+ // Apply + per-lane stamp in ONE transaction (mirrors the html branch) so
376
+ // peers receive a single update and the annotations newest-wins stamp
377
+ // rides the edit — this is what makes a deliberate delete-all (empty
378
+ // wrapper written by saveAnnotations) cold-start-safe on other peers.
379
+ let changed = false;
380
+ doc.transact(() => {
381
+ changed = applyAnnotationsToDoc(doc, str, origin);
382
+ if (changed) stampAnnotationsEdit(doc, origin);
383
+ }, origin);
368
384
  if (changed) lastAnnotations = str;
369
385
  return changed;
370
386
  }
@@ -419,7 +435,15 @@ export function createCanvasSyncAgent(opts: CanvasSyncAgentOptions): CanvasSyncA
419
435
  const parsed = tryParseJsonArray(localComments);
420
436
  if (parsed !== null) applyCommentsToDoc(doc, parsed, origin);
421
437
  }
422
- if (localAnnotations !== null) applyAnnotationsToDoc(doc, localAnnotations, origin);
438
+ if (localAnnotations !== null) {
439
+ doc.transact(() => {
440
+ if (applyAnnotationsToDoc(doc, localAnnotations, origin)) {
441
+ // Stamp with the FILE's mtime — adopt seeds pre-existing content,
442
+ // which must not claim apply-time freshness over a newer peer.
443
+ stampAnnotationsEdit(doc, origin, localMtimeMs(paths.annotations) ?? undefined);
444
+ }
445
+ }, origin);
446
+ }
423
447
  if (paths.meta && localMeta !== null) applyMetaToDoc(doc, localMeta, origin);
424
448
  if (paths.css && localCss !== null) applyCssToDoc(doc, localCss, origin);
425
449
  lastHtml = localHtml ?? '';
@@ -574,14 +598,47 @@ export function createCanvasSyncAgent(opts: CanvasSyncAgentOptions): CanvasSyncA
574
598
  }
575
599
  }
576
600
 
577
- // ---- annotations + css: follow the body winner (visually coupled) ------
578
- if (bodyWinner === 'local') {
579
- if (localAnnotations !== null && localAnnotations !== docAnnotations) {
580
- applyAnnotationsToDoc(doc, localAnnotations, origin);
601
+ // ---- annotations: PER-LANE newest-wins (the 2026-08-14 eraser fix) -----
602
+ // Annotations used to blindly follow the body winner, but annotation edits
603
+ // don't move the body's edit time — so a hub with a newer body and a stale
604
+ // EMPTY-WRAPPER annotations lane (72 bytes, not '') erased newer local
605
+ // strokes on every cold start, taking the `assets/<sha8>` references the
606
+ // asset pull scans with them. decideAnnotationsColdStart owns the table;
607
+ // the rule that matters: unstamped emptiness never beats content.
608
+ {
609
+ const annDecision = decideAnnotationsColdStart({
610
+ local: localAnnotations,
611
+ doc: docAnnotations,
612
+ isEmpty: isEmptyAnnotationsSvg,
613
+ localMtimeMs: localMtimeMs(paths.annotations),
614
+ docEditAtMs: annotationsEditAtFromDoc(doc),
615
+ bodyWinner,
616
+ });
617
+ if (annDecision.winner === 'local' && localAnnotations !== null) {
618
+ console.warn(`[sync/${slug}] cold-start annotations: ${annDecision.reason}`);
619
+ doc.transact(() => {
620
+ if (applyAnnotationsToDoc(doc, localAnnotations, origin)) {
621
+ stampAnnotationsEdit(doc, origin, localMtimeMs(paths.annotations) ?? undefined);
622
+ }
623
+ }, origin);
581
624
  lastAnnotations = localAnnotations;
625
+ } else if (annDecision.winner === 'hub' && localAnnotations !== docAnnotations) {
626
+ // Warn only when this overwrites real local content — the clean
627
+ // first-sync materialize (local empty/absent) is the common quiet path.
628
+ if (!isEmptyAnnotationsSvg(localAnnotations)) {
629
+ console.warn(`[sync/${slug}] cold-start annotations: ${annDecision.reason}`);
630
+ }
631
+ const hash = hashBytes(docAnnotations);
632
+ echoGuard.record(paths.annotations, hash);
633
+ writer(paths.annotations, docAnnotations);
634
+ lastAnnotations = docAnnotations;
582
635
  } else {
583
636
  lastAnnotations = docAnnotations;
584
637
  }
638
+ }
639
+
640
+ // ---- css: follow the body winner (visually coupled) --------------------
641
+ if (bodyWinner === 'local') {
585
642
  if (paths.css && localCss !== null && localCss !== docCss) {
586
643
  applyCssToDoc(doc, localCss, origin);
587
644
  lastCss = localCss;
@@ -590,12 +647,6 @@ export function createCanvasSyncAgent(opts: CanvasSyncAgentOptions): CanvasSyncA
590
647
  lastCss = docCss;
591
648
  }
592
649
  } else {
593
- lastAnnotations = docAnnotations;
594
- if (docAnnotations !== '' && localAnnotations !== docAnnotations) {
595
- const hash = hashBytes(docAnnotations);
596
- echoGuard.record(paths.annotations, hash);
597
- writer(paths.annotations, docAnnotations);
598
- }
599
650
  lastCss = docCss;
600
651
  if (paths.css && docCss !== null && localCss !== docCss) {
601
652
  const hash = hashBytes(docCss);