@1agh/maude 1.4.5 → 1.4.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.
- package/apps/studio/annotations-model.ts +33 -1
- package/apps/studio/api.ts +15 -0
- package/apps/studio/canvas-comment-mount.tsx +35 -2
- package/apps/studio/canvas-lib.tsx +5 -0
- package/apps/studio/canvas-shell.tsx +48 -1
- package/apps/studio/client/app.jsx +3 -0
- package/apps/studio/client/comments-overlay.css +10 -0
- package/apps/studio/collab/index.ts +9 -0
- package/apps/studio/collab/persistence.ts +49 -1
- package/apps/studio/comment-anchor.ts +116 -0
- package/apps/studio/comments-overlay.tsx +78 -35
- package/apps/studio/context.ts +1 -0
- package/apps/studio/cursors-overlay.tsx +181 -107
- package/apps/studio/dist/client.bundle.js +7 -7
- package/apps/studio/dist/comment-mount.js +2 -2
- package/apps/studio/sync/accepted-cold-start.ts +60 -4
- package/apps/studio/sync/agent.ts +28 -2
- package/apps/studio/sync/comment-ledger.ts +229 -0
- package/apps/studio/sync/file-plane.ts +77 -1
- package/apps/studio/sync/index.ts +37 -0
- package/apps/studio/sync/migrate-seed.ts +9 -2
- package/apps/studio/use-collab.tsx +28 -1
- package/apps/studio/use-selection-set.tsx +4 -0
- package/apps/studio/whats-new.json +36 -0
- package/package.json +8 -8
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Component as pQ,createElement as S7,useCallback as C7,useEffect as p,useMemo as uQ,useRef as u,useState as V7}from"react";import{createRoot as mQ}from"react-dom/client";import{useCallback as b,useEffect as R,useMemo as s,useRef as g,useState as h}from"react";function F7(){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")??"",V=(Q.get("designRel")??".design").replace(/^\/+|\/+$/g,"");return $?`${V}/${$}`: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 TJ(J,Q){if(!J)return"";let $=(J.innerText||J.textContent||"").replace(/\s+/g," ").trim();return $.length>Q?`${$.slice(0,Q-1)}…`:$}function bJ(J){if(!J)return"";let Q=[],$=J;while($&&$.nodeType===1&&Q.length<8){let V=$.getAttribute?.("data-dc-element");if(V){Q.unshift(`[data-dc-element="${V}"]`);break}let Z=$.getAttribute?.("data-dc-screen");if(Z){Q.unshift(`[data-dc-screen="${Z}"]`);break}let G=$.nodeName.toLowerCase();if($.id){G=`#${$.id}`,Q.unshift(G);break}let B=q7($).split(/\s+/).filter(Boolean).slice(0,2);if(B.length)G+=`.${B.join(".")}`;let K=1,Y=$.previousElementSibling;while(Y)K++,Y=Y.previousElementSibling;G+=`:nth-child(${K})`,Q.unshift(G),$=$.parentElement}return Q.join(" > ")}function p7(J){let Q=[],$=J;while($&&$.nodeType===1&&Q.length<8){let V=$.nodeName.toLowerCase(),Z=$.getAttribute?.("data-dc-element"),G=$.getAttribute?.("data-dc-screen");if(Z)V+=`[data-dc-element="${Z}"]`;else if(G)V+=`[data-dc-screen="${G}"]`;else if($.id)V+=`#${$.id}`;let B=q7($).split(/\s+/).filter(Boolean).slice(0,2);if(B.length&&!Z&&!G)V+=`.${B.join(".")}`;Q.unshift(V),$=$.parentElement}return Q}function xJ(J){return J.replace(/[^a-zA-Z0-9_-]/g,(Q)=>`\\${Q}`)}function u7(J,Q){return Q?`[data-dc-screen="${Q}"] [data-cd-id="${J}"]`:`[data-cd-id="${J}"]`}function m7(J,Q,$){if(!$)return 0;try{let V=J.querySelectorAll(Q);for(let Z=0;Z<V.length;Z++)if(V[Z]===$)return Z}catch{}return 0}function d7(J,Q,$){if(!Q||!$)return 0;return m7(J,`[data-cd-id="${xJ(Q)}"]`,$)}function P7(J,Q){let $=(V)=>{try{let Z=J.querySelectorAll(V);if(!Z.length)return null;let G=Q.index&&Q.index>0&&Q.index<Z.length?Q.index:0;return Z[G]??Z[0]}catch{return null}};if(Q.id){let V=$(u7(Q.id,Q.artboardId));if(V)return V}if(Q.selector)return $(Q.selector);return null}function yJ(J,Q){let $=0,V=Math.min(J.length,Q.length);for(let Z=1;Z<=V;Z++){if(J[J.length-Z]!==Q[Q.length-Z])break;$++}return $}function i7(J,Q){let $=Q.dom_path,V=(Q.tag||"").toLowerCase();if(!$||$.length===0||!V)return null;let Z=J;if(Q.artboardId){let Y=J.querySelector(`[data-dc-screen="${Q.artboardId}"]`);if(Y)Z=Y}let G=(Q.classes||"").split(/\s+/).filter(Boolean),B=null,K=0;for(let Y of Array.from(Z.querySelectorAll("[data-cd-id]"))){if(Y.tagName.toLowerCase()!==V)continue;let j=yJ(p7(Y),$);if(j===0)continue;let N=q7(Y).split(/\s+/).filter(Boolean),U=G.filter((P)=>N.includes(P)).length,z=j*10+U;if(z>K)K=z,B=Y}return B}var f7=["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"],vJ=/^(style|class|data-cd-id|data-dc-|data-dcid$)/;function CJ(J){if(!J||typeof window>"u"||!window.getComputedStyle)return{authored:{},computed:{},customStyles:{},attrs:{}};try{let Q=J.style,$=window.getComputedStyle(J),V={},Z={},G=new Set(f7);for(let z of f7){let P=Q.getPropertyValue(z);if(P)V[z]=P.trim();let X=$.getPropertyValue(z);if(X)Z[z]=X.trim()}let B=/^(margin|padding|border)(-|$)/,K={};for(let z=0;z<Q.length;z++){let P=Q.item(z);if(!P||G.has(P)||B.test(P))continue;let X=Q.getPropertyValue(P);if(X)K[P]=X.trim()}let Y={};for(let z of Array.from(J.attributes)){if(vJ.test(z.name))continue;Y[z.name]=z.value}if(J.hasAttribute("data-dc-screen")){for(let z of Array.from(J.attributes))if(z.name.startsWith("data-dc-")&&z.name!=="data-dcid")Y[z.name]=z.value}let j=J.parentElement,N=j?window.getComputedStyle(j).display:"",U=j&&(N==="flex"||N==="inline-flex")?window.getComputedStyle(j).flexDirection:"";return{authored:V,computed:Z,customStyles:K,attrs:Y,parentDisplay:N,parentFlexDirection:U}}catch{return{authored:{},computed:{},customStyles:{},attrs:{}}}}function D7(J,Q){let $=J.el,V=$&&$.getBoundingClientRect?$.getBoundingClientRect():null,Z=J.cdId,G=Z?u7(Z,J.artboardId):J.artboardId?`[data-dc-screen="${J.artboardId}"]`:bJ($),B=Z&&typeof document<"u"?m7(document,G,$):0;return{file:Q??F7(),id:Z??void 0,selector:G,artboardId:J.artboardId,index:B,tag:$?.tagName.toLowerCase()??"",classes:q7($),text:TJ($,240),dom_path:p7($),bounds:V?{x:Math.round(V.left),y:Math.round(V.top),w:Math.round(V.width),h:Math.round(V.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 K=/assets\/[0-9a-f]{8}\.[a-z0-9]+/i,Y=$.getAttribute?.("data-photo-asset");if(Y&&K.test(Y))return{photoKind:"artboard-img",photoAsset:Y};let j=$.getAttribute?.("src")||"",N=K.exec(j);return N?{photoKind:"artboard-img",photoAsset:N[0]}:{}})(),...CJ($)}}var G7=null;function a(){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 gJ,useCallback as B0,useContext as hJ,useEffect as W0,useMemo as K0,useReducer as z0,useRef as U0,useState as X0}from"react";import{Awareness as Y0,applyAwarenessUpdate as F0,encodeAwarenessUpdate as P0}from"y-protocols/awareness";import{readSyncMessage as L0,writeSyncStep1 as M0,writeUpdate as N0}from"y-protocols/sync";import*as fJ from"yjs";import*as SJ from"yjs";var RJ=new WeakSet;function c7(J){return RJ.add(J),J}var Q0=c7(Object.freeze({maudeOrigin:"shell-edit"})),$0=c7(Object.freeze({maudeOrigin:"sync-agent"}));import{jsx as I0}from"react/jsx-runtime";var pJ=gJ(null);function l7(){return hJ(pJ)}import{createContext as uJ,useCallback as l,useContext as N7,useEffect as mJ,useMemo as dJ,useRef as r7,useState as iJ}from"react";import{jsx as M7,Fragment as rJ}from"react/jsx-runtime";var B7=uJ(null);function r(J){return J.id?`id:${J.id}`:`sel:${J.selector}`}function n7(J){let Q=[],$=new Set;for(let V of J){let Z=r(V);if($.has(Z))continue;$.add(Z),Q.push(V)}return Q}var cJ=50;function lJ({children:J,postTarget:Q}){let[$,V]=iJ([]),Z=r7(null),G=r7(null),B=l((P)=>{if(Z.current)clearTimeout(Z.current);G.current=()=>{Z.current=null,G.current=null;let X=Q??(typeof window<"u"?window.parent:null);if(!X)return;let M=P.length===0?null:P.length===1?P[0]??null:P;try{X.postMessage({dgn:"select-set",selection:M},"*")}catch{}},Z.current=setTimeout(()=>G.current?.(),cJ)},[Q]);mJ(()=>()=>{if(Z.current)clearTimeout(Z.current);G.current?.()},[]);let K=l((P)=>{let X=n7(Array.isArray(P)?P:[P]);V(X),B(X)},[B]),Y=l((P)=>{let X=Array.isArray(P)?P:[P];V((M)=>{let O=n7([...M,...X]);return B(O),O})},[B]),j=l((P)=>{let X=r(P);V((M)=>{let O=M.filter((q)=>r(q)!==X);return B(O),O})},[B]),N=l((P)=>{let X=r(P);V((M)=>{let O=M.some((q)=>r(q)===X)?M.filter((q)=>r(q)!==X):[...M,P];return B(O),O})},[B]),U=l(()=>{V([]),B([])},[B]),z=dJ(()=>({selected:$,replace:K,add:Y,remove:j,toggle:N,clear:U}),[$,K,Y,j,N,U]);return M7(B7.Provider,{value:z,children:J})}function a7({children:J}){if(N7(B7))return M7(rJ,{children:J});return M7(lJ,{children:J})}function W7(){let J=N7(B7);if(!J)throw Error("useSelectionSet must be used inside <SelectionSetProvider>");return J}function o7(){return N7(B7)}import{jsx as w,jsxs as x,Fragment as WQ}from"react/jsx-runtime";var nJ="/_client/comments-overlay.css";function aJ(){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=nJ,document.head.appendChild(J)}function oJ(){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")??"",V=(Q.get("designRel")??".design").replace(/^\/+|\/+$/g,"");return $?`${V}/${$}`:null}return decodeURIComponent(J).replace(/^\//,"")}catch{return null}}function sJ(J){if(!J.selector)return null;let Q=null;try{let $=document.querySelectorAll(J.selector),V=J.index&&J.index>0&&J.index<$.length?J.index:0;Q=$[V]??$[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=i7(document,{artboardId:$,tag:J.tag,classes:J.classes,dom_path:J.dom_path})}return Q}function I7(J){let Q=sJ(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 QJ(J,Q){let V=typeof window<"u"?window.innerWidth:J.x+Q.w,Z=typeof window<"u"?window.innerHeight:J.y+Q.h,G=J.x;if(G+Q.w+8>V){let K=J.x-Q.w;G=K>=8?K:Math.max(8,V-Q.w-8)}let B=J.y;if(B+Q.h+8>Z){let K=J.y-Q.h;B=K>=8?K:Math.max(8,Z-Q.h-8)}return{x:G,y:B}}function $J(){aJ();let J=o7(),[Q,$]=h([]),[V,Z]=h(null),[G,B]=h(null),K=s(()=>oJ(),[]);R(()=>{if(typeof document>"u")return;let F=document.getElementById("dgn-pin-layer");if(!F)return;let W=F.style.display;return F.style.display="none",()=>{F.style.display=W}},[]);let Y=b((F)=>{if(!J)return;if(!F?.selector){J.clear();return}let W=F.selector.match(/data-cd-id="([^"]+)"/),D=W?W[1]:void 0,A,L;try{let I=document.querySelector(F.selector);if(I)A=I.tagName.toLowerCase(),L=(I.getAttribute("class")??"").split(/\s+/).filter((E)=>E&&!E.startsWith("dgn-")&&!E.startsWith("dc-cv-")).join(" ")}catch{}J.replace({file:K??void 0,id:D,selector:F.selector,tag:A,classes:L,bounds:F.bounds??void 0})},[J,K]),j=g(Q);j.current=Q;let N=l7(),U=VQ();R(()=>{if(!N)return;let F=N.doc.getArray("comments"),W=()=>{$(F.toArray())};if(F.length>0)W();return F.observe(W),()=>{try{F.unobserve(W)}catch{}}},[N]),R(()=>{if(typeof window>"u")return;let F=(W)=>{let D=W.data;if(!D||typeof D!=="object"||!D.dgn)return;if(D.dgn==="comments-set"&&Array.isArray(D.comments))$(D.comments);else if(D.dgn==="comment-focus"){let A=typeof D.id==="string"?D.id:null;Z(A);let L=A?j.current.find((I)=>I.id===A):void 0;Y(L)}};return window.addEventListener("message",F),()=>window.removeEventListener("message",F)},[Y]),R(()=>{if(typeof document>"u")return;let F=(W)=>{let D=W.detail;if(!D?.selection)return;B({selection:D.selection,clientX:typeof D.clientX==="number"?D.clientX:0,clientY:typeof D.clientY==="number"?D.clientY:0})};return document.addEventListener("cm:open-composer",F),()=>document.removeEventListener("cm:open-composer",F)},[]);let z=b(()=>{if(B(null),typeof window>"u")return;try{window.parent.postMessage({dgn:"force-clear"},"*")}catch{}},[]),P=b((F)=>{if(!G)return;let W=G.selection,D={file:W.file,selector:W.selector,index:W.index,dom_path:W.dom_path,tag:W.tag,classes:W.classes,bounds:W.bounds,html_excerpt:W.html,text:F};if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-submit",payload:D},"*")}catch{}z()},[G,z]);R(()=>{if(!K)return;let F=!1;return(async()=>{try{let W=await fetch(`/_comments?file=${encodeURIComponent(K)}`);if(!W.ok)return;let D=await W.json();if(F)return;if(Array.isArray(D.comments))$((A)=>A.length===0?D.comments??[]:A)}catch{}})(),()=>{F=!0}},[K]);let X=s(()=>{return Q.slice().sort((W,D)=>W.created.localeCompare(D.created)).filter((W)=>W.status!=="resolved")},[Q]),M=s(()=>{let F=new Map;return Q.slice().sort((D,A)=>D.created.localeCompare(A.created)).forEach((D,A)=>{F.set(D.id,A+1)}),F},[Q]),O=b((F)=>{if(Z(F),Y(Q.find((W)=>W.id===F)),typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-click",id:F},"*")}catch{}},[Q,Y]),q=b((F,W)=>{if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-patch",id:F,patch:W},"*")}catch{}},[]),H=b((F)=>{if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-delete",id:F},"*")}catch{}Z((W)=>W===F?null:W)},[]),_=b(async(F,W)=>{if(typeof fetch>"u")return!1;try{let D=await fetch(`/_api/comments/${encodeURIComponent(F)}/reply`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({body:W})});if(!D.ok)return!1;let A=await D.json();return $((L)=>L.map((I)=>I.id===A.id?A:I)),!0}catch{return!1}},[]);return x("div",{className:"cm-layer","aria-hidden":!1,children:[X.map((F)=>{let W=M.get(F.id)??0;return w(QQ,{comment:F,sequence:W,focused:V===F.id,onClick:O,onOrphaned:H},F.id)}),G?w($Q,{state:G,onSubmit:P,onCancel:z}):null,(()=>{if(!V)return null;let F=X.find((W)=>W.id===V);if(!F)return null;return w(ZQ,{comment:F,sequence:M.get(F.id)??0,onClose:()=>{Z(null),J?.clear()},onPatch:(W)=>q(F.id,W),onDelete:()=>H(F.id),onReply:(W)=>_(F.id,W),mine:!a()&&!!(U??N?.myName)&&(F.author??"").trim()===(U??N?.myName??"").trim()})})()]})}var j7=null;async function tJ(){if(!j7)j7=(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 j7}function s7(J){return(J.trim().split(/\s+/)[0]??"").replace(/[^\w.-]/g,"").toLowerCase()}function eJ(J,Q){if(Q<=0||Q>J.length)return null;let $=Q-1;while($>=0){let V=J[$]??"";if(V==="@"){let Z=$>0?J[$-1]:"";if($===0||/\s/.test(Z??"")){let G=J.slice($+1,Q);return{start:$,end:Q,query:G}}return null}if(!/[\w.-]/.test(V))return null;$-=1}return null}function _7({className:J,value:Q,onChange:$,onKeyDown:V,placeholder:Z,rows:G,disabled:B,textareaRef:K,ariaLabel:Y}){let j=g(null),N=b((L)=>{if(j.current=L,K)K.current=L},[K]),[U,z]=h([]),[P,X]=h(null),[M,O]=h(0),q=b(()=>{if(U.length>0)return;tJ().then((L)=>z(L))},[U.length]),H=s(()=>{if(!P)return[];let L=P.query.toLowerCase();return(!L?U:U.filter((E)=>E.name.toLowerCase().includes(L)||E.email.toLowerCase().includes(L))).slice(0,8)},[P,U]),_=b((L)=>{let I=L.selectionStart??L.value.length,E=eJ(L.value,I);X(E),O(0)},[]),F=b((L)=>{$(L.target.value),_(L.target)},[$,_]),W=b((L)=>{if(!P)return;let I=j.current;if(!I)return;let E=`@${s7(L.name)}`,k=`${Q.slice(0,P.start)}${E} ${Q.slice(P.end)}`;$(k),X(null);let T=P.start+E.length+1;requestAnimationFrame(()=>{I.focus(),I.setSelectionRange(T,T)})},[P,Q,$]),D=b((L)=>{if(P&&H.length>0){if(L.key==="ArrowDown"){L.preventDefault(),O((I)=>(I+1)%H.length);return}if(L.key==="ArrowUp"){L.preventDefault(),O((I)=>(I-1+H.length)%H.length);return}if(L.key==="Enter"||L.key==="Tab"){L.preventDefault();let I=H[M]??H[0];if(I)W(I);return}if(L.key==="Escape"){L.preventDefault(),X(null);return}}V?.(L)},[P,H,M,W,V]),A=b((L)=>{_(L.currentTarget)},[_]);return x("div",{style:{position:"relative"},children:[w("textarea",{ref:N,className:J,value:Q,placeholder:Z,rows:G,disabled:B,"aria-label":Y,onChange:F,onKeyDown:D,onFocus:q,onSelect:A,onClick:A}),P&&H.length>0?w("ul",{className:"cm-mention-popup",role:"listbox","aria-label":"Mention suggestions",style:{left:0,top:"100%"},children:H.map((L,I)=>{return x("li",{role:"option","aria-selected":I===M,className:"cm-mention-popup__item",onMouseEnter:()=>O(I),onMouseDown:(k)=>{k.preventDefault(),W(L)},children:[x("span",{className:"cm-mention-popup__name",children:["@",s7(L.name)]}),w("span",{className:"cm-mention-popup__email",children:L.email})]},`${L.name}-${L.email}`)})}):null]})}var JQ=3000;function QQ({comment:J,sequence:Q,focused:$,onClick:V,onOrphaned:Z}){let G=g(null),B=g(null),K=g(null);R(()=>{let N=()=>{B.current=null;let U=G.current;if(!U)return;let z=I7(J);if(z)K.current=null;else{if(K.current==null)K.current=Date.now();else if(Date.now()-K.current>JQ)Z(J.id);if(J.bounds)z={x:J.bounds.x,y:J.bounds.y,w:J.bounds.w,h:J.bounds.h}}if(!z){U.style.display="none",B.current=requestAnimationFrame(N);return}U.style.display="grid";let P=Math.round(z.x+z.w-12),X=Math.round(z.y-12);U.style.left=`${P}px`,U.style.top=`${X}px`,B.current=requestAnimationFrame(N)};return B.current=requestAnimationFrame(N),()=>{if(B.current!=null)cancelAnimationFrame(B.current)}},[J,Z]);let Y=J.author?.trim()||"unknown",j=`Comment ${Q} by ${Y}`;return w("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:(N)=>{N.preventDefault(),N.stopPropagation(),V(J.id)},children:Q})}function $Q({state:J,onSubmit:Q,onCancel:$}){let[V,Z]=h(""),G=g(null),B=g(null),K=g(null);R(()=>{let U=()=>{K.current=null;let z=B.current;if(!z)return;let P=BQ(J),X=QJ(P,{w:z.offsetWidth,h:z.offsetHeight});z.style.left=`${Math.round(X.x)}px`,z.style.top=`${Math.round(X.y)}px`,K.current=requestAnimationFrame(U)};return K.current=requestAnimationFrame(U),()=>{if(K.current!=null)cancelAnimationFrame(K.current)}},[J]),R(()=>{G.current?.focus()},[]);let Y=b(()=>{let U=V.trim();if(!U)return;Q(U)},[V,Q]),j=b((U)=>{if(U.key==="Escape"){U.preventDefault(),$();return}if((U.metaKey||U.ctrlKey)&&U.key==="Enter")U.preventDefault(),Y()},[$,Y]),N=s(()=>{let U=J.selection.selector||"";if(!U)return J.selection.tag||"canvas";let z=U.match(/data-cd-id="([^"]+)"/);if(z)return`cd:${z[1]}`;return U.length>36?`${U.slice(0,33)}…`:U},[J.selection]);return x("div",{ref:B,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:[w("span",{children:"New comment"}),w("span",{className:"cm-composer__selector",children:N})]}),w(_7,{textareaRef:G,className:"cm-composer__textarea",value:V,placeholder:"Type a comment. ⌘↵ to save · Esc to cancel · @name to tag",onChange:Z,onKeyDown:j,rows:3,ariaLabel:"Comment body"}),x("div",{className:"cm-composer__actions",children:[w("button",{type:"button",className:"cm-btn",onClick:$,children:"Cancel"}),w("button",{type:"button",className:"cm-btn cm-btn--primary",disabled:!V.trim(),onClick:Y,children:"Save"})]})]})}var t7=null;function VQ(){let[J,Q]=h(null);return R(()=>{if(typeof fetch>"u")return;t7??=fetch("/_api/git-user").then((V)=>V.ok?V.json():null).then((V)=>typeof V?.name==="string"&&V.name.trim()?V.name.trim():null).catch(()=>null);let $=!0;return t7.then((V)=>$&&Q(V)),()=>{$=!1}},[]),J}function ZQ({comment:J,sequence:Q,onClose:$,onPatch:V,onDelete:Z,onReply:G,mine:B=!1}){let K=g(null),Y=g(null),j=g(null),[N,U]=h(""),[z,P]=h(!1),[X,M]=h(null),O=b(()=>{let W=(X??"").trim();if(!W)return;if(W!==J.text)V({text:W});M(null)},[X,J.text,V]);R(()=>{let W=()=>{j.current=null;let D=K.current;if(!D)return;let A=GQ(J),L=QJ(A,{w:D.offsetWidth,h:D.offsetHeight});D.style.left=`${Math.round(L.x)}px`,D.style.top=`${Math.round(L.y)}px`,j.current=requestAnimationFrame(W)};return j.current=requestAnimationFrame(W),()=>{if(j.current!=null)cancelAnimationFrame(j.current)}},[J]),R(()=>{K.current?.focus();let W=J.id;return()=>{document.querySelector(`[data-comment-pin="${W}"]`)?.focus()}},[J.id]),R(()=>{if(typeof document>"u")return;let W=(D)=>{if(D.key!=="Escape")return;let A=K.current;if(!A)return;if(A.contains(D.target)||document.activeElement===A)D.preventDefault(),$()};return document.addEventListener("keydown",W),()=>document.removeEventListener("keydown",W)},[$]);let q=b(async()=>{let W=N.trim();if(!W||z)return;P(!0);let D=await G(W);if(P(!1),D)U(""),Y.current?.focus()},[N,z,G]),H=b((W)=>{if((W.metaKey||W.ctrlKey)&&W.key==="Enter")W.preventDefault(),q()},[q]),_=`cm-thread-head-${J.id}`,F=qQ(J.selector,"");return x("div",{ref:K,className:"cm-thread",role:"dialog","aria-labelledby":_,tabIndex:-1,onClick:(W)=>W.stopPropagation(),onPointerDown:(W)=>W.stopPropagation(),children:[x("div",{className:"cm-thread__head",id:_,children:[x("div",{className:"cm-thread__head-row",children:[w("span",{className:"cm-thread__seq","aria-hidden":"true",children:Q}),w("span",{className:"cm-thread__author",children:J.author?.trim()||"unknown"}),w("span",{className:"cm-thread__time",children:JJ(J.created)}),w("button",{type:"button",className:"cm-thread__close","aria-label":"Close thread",title:"Close · Esc",onClick:$,children:"×"})]}),F?w("code",{className:"cm-thread__selector",children:F}):null]}),X===null?w("div",{className:"cm-thread__body",children:e7(J.text)}):x("div",{className:"cm-thread__reply-form",children:[w(_7,{className:"cm-thread__reply-textarea",value:X,placeholder:"Edit your comment… ⌘↵ to save",onChange:M,onKeyDown:(W)=>{if((W.metaKey||W.ctrlKey)&&W.key==="Enter")W.preventDefault(),O()},rows:3,ariaLabel:"Edit comment"}),x("div",{className:"cm-thread__reply-actions",children:[w("button",{type:"button",className:"cm-btn",onClick:()=>M(null),children:"Cancel"}),w("button",{type:"button",className:"cm-btn cm-btn--primary","data-testid":"comment-edit-save",disabled:!X.trim(),onClick:O,children:"Save"})]})]}),(J.thread??[]).map((W)=>x("div",{className:"cm-thread__reply",children:[x("div",{className:"cm-thread__reply-head",children:[w("span",{className:"cm-thread__reply-author",children:W.author?.trim()||"unknown"}),w("span",{className:"cm-thread__reply-time",children:JJ(W.created)})]}),w("div",{className:"cm-thread__reply-body",children:e7(W.body)})]},W.id)),!a()&&x(WQ,{children:[x("div",{className:"cm-thread__reply-form",children:[w(_7,{textareaRef:Y,className:"cm-thread__reply-textarea",value:N,placeholder:"Reply… ⌘↵ to send · @name to tag",onChange:U,onKeyDown:H,rows:2,ariaLabel:"Reply",disabled:z}),w("div",{className:"cm-thread__reply-actions",children:w("button",{type:"button",className:"cm-btn cm-btn--primary",disabled:!N.trim()||z,onClick:()=>void q(),children:"Send"})})]}),x("div",{className:"cm-thread__actions",children:[B&&X===null?w("button",{type:"button",className:"cm-btn","data-testid":"comment-edit",onClick:()=>M(J.text),children:"Edit"}):null,J.status==="resolved"?w("button",{type:"button",className:"cm-btn",onClick:()=>V({status:"open"}),children:"↺ Reopen"}):w("button",{type:"button",className:"cm-btn cm-btn--primary",onClick:()=>{V({status:"resolved"}),$()},children:"✓ Resolve"}),w("button",{type:"button",className:"cm-btn cm-btn--danger",onClick:()=>{Z(),$()},children:"Delete"})]})]})]})}function e7(J){if(!J)return null;let Q=/(@[\w][\w.-]*)/g;return J.split(Q).map((V,Z)=>{let G=`${Z}:${V}`;if(Z%2===1)return w("strong",{"data-mention":"true",children:V},G);return w("span",{children:V},G)})}function JJ(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 qQ(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 GQ(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 BQ(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 KQ}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 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 V=Q.getAttribute?.("contenteditable");if(V==="true"||V==="plaintext-only"||V==="")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 ZJ(J){if(!J||typeof J.closest!=="function")return!1;let Q=J;return!!Q.closest("[data-dc-screen]")&&!Q.closest(".dc-artboard-body")}function VJ(J,Q,$){return J.kind==="select"&&!$.metaKey&&!$.ctrlKey&&ZJ(Q)}function UQ(J,Q,$){return J==="select"&&!$.metaKey&&!$.ctrlKey&&ZJ(Q)}function qJ(J){let{hostRef:Q,getActiveTool:$,isSpaceHeld:V,callbacks:Z,enabled:G=!0,claimableActions:B}=J;KQ(()=>{if(!G)return;let K=Q.current;if(!K)return;let Y=(q)=>B&&q.kind!=="no-op"&&!B.has(q.kind)?{kind:"no-op"}:q,j=(q)=>{switch(q.kind){case"hover":Z.onHover?.(q);break;case"select":Z.onSelect?.(q);break;case"drop-comment":Z.onDropComment?.(q);break;case"context-menu":Z.onContextMenu?.(q);break;case"tool":Z.onTool?.(q);break;case"escape":Z.onEscape?.();break;case"undo":Z.onUndo?.();break;case"redo":Z.onRedo?.();break;case"no-op":break}},N=(q)=>{let H=Y(e({type:"pointermove",button:q.button,metaKey:q.metaKey,ctrlKey:q.ctrlKey,shiftKey:q.shiftKey,altKey:q.altKey,clientX:q.clientX,clientY:q.clientY,spaceHeld:V?.()??!1,activeTool:$()}));j(H)},U=(q)=>{if(J7(q.target))return;if(K7(q.target))return;let H=Y(e({type:"pointerdown",button:q.button,metaKey:q.metaKey,ctrlKey:q.ctrlKey,shiftKey:q.shiftKey,altKey:q.altKey,clientX:q.clientX,clientY:q.clientY,spaceHeld:V?.()??!1,activeTool:$()})),_=VJ(H,q.target,q);if(H.kind!=="no-op"){if(q.preventDefault(),!_)q.stopImmediatePropagation()}j(H)},z=(q)=>{if(J7(q.target))return;if(K7(q.target))return;let H=Y(e({type:"pointerdown",button:q.button,metaKey:q.metaKey,ctrlKey:q.ctrlKey,shiftKey:q.shiftKey,altKey:q.altKey,clientX:q.clientX,clientY:q.clientY,spaceHeld:V?.()??!1,activeTool:$()})),_=VJ(H,q.target,q);if(H.kind!=="no-op"){if(q.preventDefault(),!_)q.stopImmediatePropagation();if(H.kind==="select")try{window.focus()}catch{}}},P=(q)=>{if(J7(q.target))return;if(K7(q.target))return;let H=$(),_=q.metaKey||q.ctrlKey,F=H==="comment"?"drop-comment":H==="move"&&q.button===0?"select":(A7(H)||H==="browse")&&_&&q.button===0?"select":q.button===2?"context-menu":null;if(F&&(!B||B.has(F))){let W=UQ(F,q.target,q);if(q.preventDefault(),!W)q.stopImmediatePropagation()}},X=(q)=>{let H=Y(e({type:"contextmenu",clientX:q.clientX,clientY:q.clientY,metaKey:q.metaKey,ctrlKey:q.ctrlKey,shiftKey:q.shiftKey,altKey:q.altKey,activeTool:$()}));if(H.kind==="no-op")return;q.preventDefault(),q.stopImmediatePropagation(),j(H)},M=(q)=>{let H=Y(e({type:"keydown",key:q.key,metaKey:q.metaKey,ctrlKey:q.ctrlKey,shiftKey:q.shiftKey,altKey:q.altKey,isEditable:K7(q.target),activeTool:$()}));if(H.kind==="tool"||H.kind==="escape"||H.kind==="undo"||H.kind==="redo")q.preventDefault();j(H)};K.addEventListener("pointermove",N,{passive:!0}),K.addEventListener("pointerdown",U,{capture:!0}),K.addEventListener("mousedown",z,{capture:!0}),K.addEventListener("click",P,{capture:!0}),K.addEventListener("contextmenu",X,{capture:!0});let O=K.ownerDocument??document;return O.addEventListener("keydown",M,!0),()=>{K.removeEventListener("pointermove",N),K.removeEventListener("pointerdown",U,{capture:!0}),K.removeEventListener("mousedown",z,{capture:!0}),K.removeEventListener("click",P,{capture:!0}),K.removeEventListener("contextmenu",X,{capture:!0}),O.removeEventListener("keydown",M,!0)}},[G,Q,$,V,Z,B])}function O7(J,Q,$,V){let Z=J.elementFromPoint(Q,$);if(!Z)return null;if(Z.closest?.(".dc-mm, .dc-zoom-tb, .dc-tool-palette, .dc-context-menu, .dc-cv-group-bbox"))return null;let G=Z.closest?.("[data-dc-screen]")??null,B=G?.getAttribute("data-dc-screen")??null,K=Z.closest?.(".dc-artboard-body")??null;if(!K){if(G&&B)return{el:G,cdId:null,artboardId:B};return null}if(Z===K){if(G&&B)return{el:G,cdId:null,artboardId:B};return null}if(V.deep){let z=Z.getAttribute?.("data-cd-id")??null;return{el:Z,cdId:z,artboardId:B}}let Y=Z,j=null;while(Y&&Y!==K){if(Y.hasAttribute?.("data-cd-id"))j=Y;Y=Y.parentElement}let N=j??Z,U=N.getAttribute?.("data-cd-id")??null;return{el:N,cdId:U,artboardId:B}}import{useCallback as EQ,useEffect as HJ,useRef as X7}from"react";var XQ=!1;function GJ(){return XQ}import{createContext as jQ,useCallback as $7,useContext as UJ,useEffect as T7,useMemo as WJ,useRef as b7,useState as z7}from"react";function m(J,Q,$,V){return`url("data:image/svg+xml,${encodeURIComponent(J.trim())}") ${Q} ${$}, ${V}`}var E7="width='24' height='24' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'",w7="#1f1f1f",k7="stroke='#ffffff' stroke-linejoin='round' stroke-linecap='round'";function i(J,Q,$){let V=$?`<g transform='${$}'>`:"";return`<svg ${E7}>${V}<path fill='#ffffff' d='${J}'/><path fill='${w7}' d='${Q}'/>${$?"</g>":""}</svg>`}var BJ="translate(0,32) scale(1,-1)",HQ=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"),YQ=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"),FQ=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"),PQ=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",BJ),6,18,"crosshair"),DQ=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",BJ),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"),LQ=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"),MQ=m(`<svg ${E7}><path d='M16 4V28M11 4H21M11 28H21' fill='none' ${k7} stroke-width='5'/><path d='M16 4V28M11 4H21M11 28H21' fill='none' stroke='${w7}' stroke-width='2.25' stroke-linecap='round'/></svg>`,12,12,"text"),NQ=m(`<svg ${E7}><path d='M6 5H21L26 10V27H6Z' fill='${w7}' ${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:HQ,hand:YQ,comment:FQ,pen:PQ,section:Q7,highlighter:DQ,shape:Q7,rect:Q7,ellipse:Q7,sticky:NQ,arrow:Q7,text:MQ,eraser:LQ});import{jsx as y7,Fragment as kQ}from"react/jsx-runtime";var x7="maude:tool-sync",KJ=Object.freeze({preview:"browse",edit:"move"});function zJ(J){if(J==="browse")return"preview";if(J==="move")return"edit";return null}var _Q=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}]),IQ=new Set(["browse","move","hand"]);function AQ(J,Q){return Q?J.filter(($)=>IQ.has($.id)):J}var v7=jQ(null);function OQ({children:J,tools:Q=_Q,initial:$,initialMode:V}){let Z=a(),G=WJ(()=>AQ(Q,Z),[Q,Z]),B=$??(Z?"browse":"move"),K=V??zJ(B)??(Z?"preview":"edit"),[Y,j]=z7(B),[N,U]=z7(K),[z,P]=z7(()=>({tool:null,locked:!1})),X=$7((I)=>{if(!G.some((k)=>k.id===I))return;j(I);let E=zJ(I);if(E)U(E);P((k)=>k.locked&&k.tool===I?k:{tool:null,locked:!1})},[G]),M=$7((I)=>{let E=KJ[I];if(!G.some((k)=>k.id===E))return;U(I),j(E),P((k)=>k.locked&&k.tool===E?k:{tool:null,locked:!1})},[G]),O=$7(()=>{X(KJ[N])},[N,X]),q=$7((I)=>{P((E)=>{if(E.locked&&E.tool===I)return{tool:null,locked:!1};return{tool:I,locked:!0}}),j(I)},[]),H=$7(()=>{P({tool:null,locked:!1})},[]),[_,F]=z7("rounded"),W=b7(Math.random().toString(36).slice(2)),D=b7(Y);D.current=Y;let A=b7(!1);T7(()=>{if(!A.current){A.current=!0;return}if(typeof document>"u")return;document.dispatchEvent(new CustomEvent(x7,{detail:{tool:Y,from:W.current}}))},[Y]),T7(()=>{if(typeof document>"u")return;let I=(E)=>{let k=E.detail;if(!k||k.from===W.current||typeof k.tool!=="string")return;if(k.tool===D.current)return;X(k.tool)};return document.addEventListener(x7,I),()=>document.removeEventListener(x7,I)},[X]),T7(()=>{if(typeof document>"u")return;let I=G.find((T)=>T.id===Y);if(!I)return;let E=document.body.style.cursor,k=document.getElementById("dc-tool-cursor");if(!k)k=document.createElement("style"),k.id="dc-tool-cursor",document.head.appendChild(k);if(Y==="browse"){if(document.body.style.cursor="",k.textContent="",typeof window<"u"&&window.parent&&window.parent!==window)try{window.parent.postMessage({dgn:"tool-cursor",tool:Y},"*")}catch{}return()=>{document.body.style.cursor=E}}if(document.body.style.cursor=I.cursor,k.textContent=`* { cursor: ${I.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=E;let T=document.getElementById("dc-tool-cursor");if(T)T.textContent=""}},[Y,G]);let L=WJ(()=>({tool:Y,setTool:X,tools:G,mode:N,setMode:M,resetTool:O,sticky:z,toggleSticky:q,clearSticky:H,shapeKind:_,setShapeKind:F}),[Y,X,G,N,M,O,z,q,H,_]);return y7(v7.Provider,{value:L,children:J})}function XJ({children:J,initial:Q,initialMode:$}){if(UJ(v7))return y7(kQ,{children:J});return y7(OQ,{initial:Q,initialMode:$,children:J})}function U7(){let J=UJ(v7);if(!J)throw Error("useToolMode must be used inside <ToolProvider>");return J}import{jsx as fQ}from"react/jsx-runtime";var wQ=`
|
|
1
|
+
import{Component as aQ,createElement as h7,useCallback as R7,useEffect as p,useMemo as sQ,useRef as u,useState as Z7}from"react";import{createRoot as tQ}from"react-dom/client";var RJ=/^[A-Za-z0-9_-]{1,64}$/;function o(J){return typeof J==="string"&&RJ.test(J)}function m7(J){if(!J||typeof J!=="object")return!1;let{x:Q,y:$}=J;return typeof Q==="number"&&typeof $==="number"&&Number.isFinite(Q)&&Number.isFinite($)&&Math.abs(Q)<=1e7&&Math.abs($)<=1e7}function d7(){if(typeof window>"u"||typeof document>"u")return null;let J=window.__maudeViewport?.()??null;if(!J||!(J.zoom>0))return null;let Q=document.querySelector(".dc-canvas");if(!Q)return null;let $=Q.getBoundingClientRect();return{vp:J,left:$.left,top:$.top}}function c7(J,Q){let $=d7();if(!$)return null;let{vp:V}=$;return{x:(J-$.left-V.x)/V.zoom,y:(Q-$.top-V.y)/V.zoom}}function i7(J){let Q=d7();if(!Q)return null;let{vp:$}=Q;return{x:Q.left+$.x+J.x*$.zoom,y:Q.top+$.y+J.y*$.zoom}}function G7(J){if(typeof document>"u"||!o(J))return null;return document.querySelector(`[data-id="${J}"][data-tool]`)}function l7(J,Q){if(typeof document>"u")return null;let $=null;for(let V of Array.from(document.querySelectorAll("[data-id][data-tool]"))){if(V.getAttribute("data-tool")==="section")continue;let Z=V.getAttribute("data-id");if(!o(Z))continue;let G=V.getBoundingClientRect();if(G.width<=0&&G.height<=0)continue;if(J<G.left||J>G.right||Q<G.top||Q>G.bottom)continue;let W=Math.max(1,G.width)*Math.max(1,G.height);if(!$||W<=$.area)$={id:Z,area:W}}return $?.id??null}import{useCallback as b,useEffect as R,useMemo as t,useRef as g,useState as h}from"react";function L7(){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")??"",V=(Q.get("designRel")??".design").replace(/^\/+|\/+$/g,"");return $?`${V}/${$}`:void 0}return decodeURIComponent(J).replace(/^\//,"")}catch{return}}function B7(J){if(!J)return"";return(J.getAttribute("class")??"").trim().split(/\s+/).filter((Q)=>Q&&!Q.startsWith("dgn-")&&!Q.startsWith("dc-cv-")).join(" ")}function gJ(J,Q){if(!J)return"";let $=(J.innerText||J.textContent||"").replace(/\s+/g," ").trim();return $.length>Q?`${$.slice(0,Q-1)}…`:$}function hJ(J){if(!J)return"";let Q=[],$=J;while($&&$.nodeType===1&&Q.length<8){let V=$.getAttribute?.("data-dc-element");if(V){Q.unshift(`[data-dc-element="${V}"]`);break}let Z=$.getAttribute?.("data-dc-screen");if(Z){Q.unshift(`[data-dc-screen="${Z}"]`);break}let G=$.nodeName.toLowerCase();if($.id){G=`#${$.id}`,Q.unshift(G);break}let W=B7($).split(/\s+/).filter(Boolean).slice(0,2);if(W.length)G+=`.${W.join(".")}`;let K=1,H=$.previousElementSibling;while(H)K++,H=H.previousElementSibling;G+=`:nth-child(${K})`,Q.unshift(G),$=$.parentElement}return Q.join(" > ")}function n7(J){let Q=[],$=J;while($&&$.nodeType===1&&Q.length<8){let V=$.nodeName.toLowerCase(),Z=$.getAttribute?.("data-dc-element"),G=$.getAttribute?.("data-dc-screen");if(Z)V+=`[data-dc-element="${Z}"]`;else if(G)V+=`[data-dc-screen="${G}"]`;else if($.id)V+=`#${$.id}`;let W=B7($).split(/\s+/).filter(Boolean).slice(0,2);if(W.length&&!Z&&!G)V+=`.${W.join(".")}`;Q.unshift(V),$=$.parentElement}return Q}function fJ(J){return J.replace(/[^a-zA-Z0-9_-]/g,(Q)=>`\\${Q}`)}function o7(J,Q){return Q?`[data-dc-screen="${Q}"] [data-cd-id="${J}"]`:`[data-cd-id="${J}"]`}function a7(J,Q,$){if(!$)return 0;try{let V=J.querySelectorAll(Q);for(let Z=0;Z<V.length;Z++)if(V[Z]===$)return Z}catch{}return 0}function s7(J,Q,$){if(!Q||!$)return 0;return a7(J,`[data-cd-id="${fJ(Q)}"]`,$)}function D7(J,Q){let $=(V)=>{try{let Z=J.querySelectorAll(V);if(!Z.length)return null;let G=Q.index&&Q.index>0&&Q.index<Z.length?Q.index:0;return Z[G]??Z[0]}catch{return null}};if(Q.id){let V=$(o7(Q.id,Q.artboardId));if(V)return V}if(Q.selector)return $(Q.selector);return null}function pJ(J,Q){let $=0,V=Math.min(J.length,Q.length);for(let Z=1;Z<=V;Z++){if(J[J.length-Z]!==Q[Q.length-Z])break;$++}return $}function t7(J,Q){let $=Q.dom_path,V=(Q.tag||"").toLowerCase();if(!$||$.length===0||!V)return null;let Z=J;if(Q.artboardId){let H=J.querySelector(`[data-dc-screen="${Q.artboardId}"]`);if(H)Z=H}let G=(Q.classes||"").split(/\s+/).filter(Boolean),W=null,K=0;for(let H of Array.from(Z.querySelectorAll("[data-cd-id]"))){if(H.tagName.toLowerCase()!==V)continue;let j=pJ(n7(H),$);if(j===0)continue;let N=B7(H).split(/\s+/).filter(Boolean),X=G.filter((Y)=>N.includes(Y)).length,z=j*10+X;if(z>K)K=z,W=H}return W}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"],uJ=/^(style|class|data-cd-id|data-dc-|data-dcid$)/;function mJ(J){if(!J||typeof window>"u"||!window.getComputedStyle)return{authored:{},computed:{},customStyles:{},attrs:{}};try{let Q=J.style,$=window.getComputedStyle(J),V={},Z={},G=new Set(r7);for(let z of r7){let Y=Q.getPropertyValue(z);if(Y)V[z]=Y.trim();let U=$.getPropertyValue(z);if(U)Z[z]=U.trim()}let W=/^(margin|padding|border)(-|$)/,K={};for(let z=0;z<Q.length;z++){let Y=Q.item(z);if(!Y||G.has(Y)||W.test(Y))continue;let U=Q.getPropertyValue(Y);if(U)K[Y]=U.trim()}let H={};for(let z of Array.from(J.attributes)){if(uJ.test(z.name))continue;H[z.name]=z.value}if(J.hasAttribute("data-dc-screen")){for(let z of Array.from(J.attributes))if(z.name.startsWith("data-dc-")&&z.name!=="data-dcid")H[z.name]=z.value}let j=J.parentElement,N=j?window.getComputedStyle(j).display:"",X=j&&(N==="flex"||N==="inline-flex")?window.getComputedStyle(j).flexDirection:"";return{authored:V,computed:Z,customStyles:K,attrs:H,parentDisplay:N,parentFlexDirection:X}}catch{return{authored:{},computed:{},customStyles:{},attrs:{}}}}function M7(J,Q){let $=J.el,V=$&&$.getBoundingClientRect?$.getBoundingClientRect():null,Z=J.cdId,G=Z?o7(Z,J.artboardId):J.artboardId?`[data-dc-screen="${J.artboardId}"]`:hJ($),W=Z&&typeof document<"u"?a7(document,G,$):0;return{file:Q??L7(),id:Z??void 0,selector:G,artboardId:J.artboardId,index:W,tag:$?.tagName.toLowerCase()??"",classes:B7($),text:gJ($,240),dom_path:n7($),bounds:V?{x:Math.round(V.left),y:Math.round(V.top),w:Math.round(V.width),h:Math.round(V.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 K=/assets\/[0-9a-f]{8}\.[a-z0-9]+/i,H=$.getAttribute?.("data-photo-asset");if(H&&K.test(H))return{photoKind:"artboard-img",photoAsset:H};let j=$.getAttribute?.("src")||"",N=K.exec(j);return N?{photoKind:"artboard-img",photoAsset:N[0]}:{}})(),...mJ($)}}var W7=null;function a(){if(typeof window>"u")return!1;if(W7===null)try{W7=new URLSearchParams(window.location.search).get("ro")==="1"}catch{W7=!1}return W7}import*as j7 from"lib0/decoding";import*as s from"lib0/encoding";import{createContext as iJ,useCallback as D0,useContext as lJ,useEffect as M0,useMemo as j0,useReducer as N0,useRef as _0,useState as A0}from"react";import{Awareness as O0,applyAwarenessUpdate as k0,encodeAwarenessUpdate as E0}from"y-protocols/awareness";import{readSyncMessage as w0,writeSyncStep1 as b0,writeUpdate as x0}from"y-protocols/sync";import*as rJ from"yjs";import*as dJ from"yjs";var cJ=new WeakSet;function e7(J){return cJ.add(J),J}var H0=e7(Object.freeze({maudeOrigin:"shell-edit"})),X0=e7(Object.freeze({maudeOrigin:"sync-agent"}));import{jsx as v0}from"react/jsx-runtime";var nJ=iJ(null);function JJ(){return lJ(nJ)}import{createContext as oJ,useCallback as l,useContext as _7,useEffect as aJ,useMemo as sJ,useRef as QJ,useState as tJ}from"react";import{jsx as N7,Fragment as QQ}from"react/jsx-runtime";var K7=oJ(null);function r(J){return J.id?`id:${J.id}`:`sel:${J.selector}`}function $J(J){let Q=[],$=new Set;for(let V of J){let Z=r(V);if($.has(Z))continue;$.add(Z),Q.push(V)}return Q}var eJ=50;function JQ({children:J,postTarget:Q}){let[$,V]=tJ([]),Z=QJ(null),G=QJ(null),W=l((Y)=>{if(Z.current)clearTimeout(Z.current);G.current=()=>{Z.current=null,G.current=null;let U=Q??(typeof window<"u"?window.parent:null);if(!U)return;let D=Y.length===0?null:Y.length===1?Y[0]??null:Y;try{U.postMessage({dgn:"select-set",selection:D},"*")}catch{}},Z.current=setTimeout(()=>G.current?.(),eJ)},[Q]);aJ(()=>()=>{if(Z.current)clearTimeout(Z.current);G.current?.()},[]);let K=l((Y)=>{let U=$J(Array.isArray(Y)?Y:[Y]);V(U),W(U)},[W]),H=l((Y)=>{let U=Array.isArray(Y)?Y:[Y];V((D)=>{let A=$J([...D,...U]);return W(A),A})},[W]),j=l((Y)=>{let U=r(Y);V((D)=>{let A=D.filter((q)=>r(q)!==U);return W(A),A})},[W]),N=l((Y)=>{let U=r(Y);V((D)=>{let A=D.some((q)=>r(q)===U)?D.filter((q)=>r(q)!==U):[...D,Y];return W(A),A})},[W]),X=l(()=>{V([]),W([])},[W]),z=sJ(()=>({selected:$,replace:K,add:H,remove:j,toggle:N,clear:X}),[$,K,H,j,N,X]);return N7(K7.Provider,{value:z,children:J})}function VJ({children:J}){if(_7(K7))return N7(QQ,{children:J});return N7(JQ,{children:J})}function z7(){let J=_7(K7);if(!J)throw Error("useSelectionSet must be used inside <SelectionSetProvider>");return J}function ZJ(){return _7(K7)}import{jsx as T,jsxs as x,Fragment as DQ}from"react/jsx-runtime";var $Q="/_client/comments-overlay.css";function VQ(){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=$Q,document.head.appendChild(J)}function ZQ(){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")??"",V=(Q.get("designRel")??".design").replace(/^\/+|\/+$/g,"");return $?`${V}/${$}`:null}return decodeURIComponent(J).replace(/^\//,"")}catch{return null}}function qQ(J){if(o(J.annotationId))return G7(J.annotationId);if(!J.selector)return null;let Q=null;try{let $=document.querySelectorAll(J.selector),V=J.index&&J.index>0&&J.index<$.length?J.index:0;Q=$[V]??$[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=t7(document,{artboardId:$,tag:J.tag,classes:J.classes,dom_path:J.dom_path})}return Q}function O7(J){let Q=qQ(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 KJ(J,Q){let V=typeof window<"u"?window.innerWidth:J.x+Q.w,Z=typeof window<"u"?window.innerHeight:J.y+Q.h,G=J.x;if(G+Q.w+8>V){let K=J.x-Q.w;G=K>=8?K:Math.max(8,V-Q.w-8)}let W=J.y;if(W+Q.h+8>Z){let K=J.y-Q.h;W=K>=8?K:Math.max(8,Z-Q.h-8)}return{x:G,y:W}}function zJ(){VQ();let J=ZJ(),[Q,$]=h([]),[V,Z]=h(null),[G,W]=h(null),K=t(()=>ZQ(),[]);R(()=>{if(typeof document>"u")return;let P=document.getElementById("dgn-pin-layer");if(!P)return;let B=P.style.display;return P.style.display="none",()=>{P.style.display=B}},[]);let H=b((P)=>{if(!J)return;if(!P?.selector){J.clear();return}let B=P.selector.match(/data-cd-id="([^"]+)"/),L=B?B[1]:void 0,O,M;try{let I=document.querySelector(P.selector);if(I)O=I.tagName.toLowerCase(),M=(I.getAttribute("class")??"").split(/\s+/).filter((E)=>E&&!E.startsWith("dgn-")&&!E.startsWith("dc-cv-")).join(" ")}catch{}J.replace({file:K??void 0,id:L,selector:P.selector,tag:O,classes:M,bounds:P.bounds??void 0})},[J,K]),j=g(Q);j.current=Q;let N=JJ(),X=XQ();R(()=>{if(!N)return;let P=N.doc.getArray("comments"),B=()=>{$(P.toArray())};if(P.length>0)B();return P.observe(B),()=>{try{P.unobserve(B)}catch{}}},[N]),R(()=>{if(typeof window>"u")return;let P=(B)=>{let L=B.data;if(!L||typeof L!=="object"||!L.dgn)return;if(L.dgn==="comments-set"&&Array.isArray(L.comments))$(L.comments);else if(L.dgn==="comment-focus"){let O=typeof L.id==="string"?L.id:null;Z(O);let M=O?j.current.find((I)=>I.id===O):void 0;H(M)}};return window.addEventListener("message",P),()=>window.removeEventListener("message",P)},[H]),R(()=>{if(typeof document>"u")return;let P=(B)=>{let L=B.detail;if(!L?.selection)return;W({selection:L.selection,clientX:typeof L.clientX==="number"?L.clientX:0,clientY:typeof L.clientY==="number"?L.clientY:0})};return document.addEventListener("cm:open-composer",P),()=>document.removeEventListener("cm:open-composer",P)},[]);let z=b(()=>{if(W(null),typeof window>"u")return;try{window.parent.postMessage({dgn:"force-clear"},"*")}catch{}},[]),Y=b((P)=>{if(!G)return;let B=G.selection,L={file:B.file,selector:B.selector,index:B.index,dom_path:B.dom_path,tag:B.tag,classes:B.classes,bounds:B.bounds,html_excerpt:B.html,...B.annotationId?{annotationId:B.annotationId}:{},...B.world?{world:B.world}:{},text:P};if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-submit",payload:L},"*")}catch{}z()},[G,z]);R(()=>{if(!K)return;let P=!1;return(async()=>{try{let B=await fetch(`/_comments?file=${encodeURIComponent(K)}`);if(!B.ok)return;let L=await B.json();if(P)return;if(Array.isArray(L.comments))$((O)=>O.length===0?L.comments??[]:O)}catch{}})(),()=>{P=!0}},[K]);let U=t(()=>{return Q.slice().sort((B,L)=>B.created.localeCompare(L.created)).filter((B)=>B.status!=="resolved")},[Q]),D=t(()=>{let P=new Map;return Q.slice().sort((L,O)=>L.created.localeCompare(O.created)).forEach((L,O)=>{P.set(L.id,O+1)}),P},[Q]),A=b((P)=>{if(Z(P),H(Q.find((B)=>B.id===P)),typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-click",id:P},"*")}catch{}},[Q,H]),q=b((P,B)=>{if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-patch",id:P,patch:B},"*")}catch{}},[]),F=b((P)=>{if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-delete",id:P},"*")}catch{}Z((B)=>B===P?null:B)},[]),_=b(async(P,B)=>{if(typeof fetch>"u")return!1;try{let L=await fetch(`/_api/comments/${encodeURIComponent(P)}/reply`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({body:B})});if(!L.ok)return!1;let O=await L.json();return $((M)=>M.map((I)=>I.id===O.id?O:I)),!0}catch{return!1}},[]);return x("div",{className:"cm-layer","aria-hidden":!1,children:[U.map((P)=>{let B=D.get(P.id)??0;return T(UQ,{comment:P,sequence:B,focused:V===P.id,onClick:A},P.id)}),G?T(HQ,{state:G,onSubmit:Y,onCancel:z}):null,(()=>{if(!V)return null;let P=U.find((B)=>B.id===V);if(!P)return null;return T(FQ,{comment:P,sequence:D.get(P.id)??0,onClose:()=>{Z(null),J?.clear()},onPatch:(B)=>q(P.id,B),onDelete:()=>F(P.id),onReply:(B)=>_(P.id,B),mine:!a()&&!!(X??N?.myName)&&(P.author??"").trim()===(X??N?.myName??"").trim()})})()]})}var A7=null;async function GQ(){if(!A7)A7=(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 A7}function qJ(J){return(J.trim().split(/\s+/)[0]??"").replace(/[^\w.-]/g,"").toLowerCase()}function BQ(J,Q){if(Q<=0||Q>J.length)return null;let $=Q-1;while($>=0){let V=J[$]??"";if(V==="@"){let Z=$>0?J[$-1]:"";if($===0||/\s/.test(Z??"")){let G=J.slice($+1,Q);return{start:$,end:Q,query:G}}return null}if(!/[\w.-]/.test(V))return null;$-=1}return null}function I7({className:J,value:Q,onChange:$,onKeyDown:V,placeholder:Z,rows:G,disabled:W,textareaRef:K,ariaLabel:H}){let j=g(null),N=b((M)=>{if(j.current=M,K)K.current=M},[K]),[X,z]=h([]),[Y,U]=h(null),[D,A]=h(0),q=b(()=>{if(X.length>0)return;GQ().then((M)=>z(M))},[X.length]),F=t(()=>{if(!Y)return[];let M=Y.query.toLowerCase();return(!M?X:X.filter((E)=>E.name.toLowerCase().includes(M)||E.email.toLowerCase().includes(M))).slice(0,8)},[Y,X]),_=b((M)=>{let I=M.selectionStart??M.value.length,E=BQ(M.value,I);U(E),A(0)},[]),P=b((M)=>{$(M.target.value),_(M.target)},[$,_]),B=b((M)=>{if(!Y)return;let I=j.current;if(!I)return;let E=`@${qJ(M.name)}`,k=`${Q.slice(0,Y.start)}${E} ${Q.slice(Y.end)}`;$(k),U(null);let w=Y.start+E.length+1;requestAnimationFrame(()=>{I.focus(),I.setSelectionRange(w,w)})},[Y,Q,$]),L=b((M)=>{if(Y&&F.length>0){if(M.key==="ArrowDown"){M.preventDefault(),A((I)=>(I+1)%F.length);return}if(M.key==="ArrowUp"){M.preventDefault(),A((I)=>(I-1+F.length)%F.length);return}if(M.key==="Enter"||M.key==="Tab"){M.preventDefault();let I=F[D]??F[0];if(I)B(I);return}if(M.key==="Escape"){M.preventDefault(),U(null);return}}V?.(M)},[Y,F,D,B,V]),O=b((M)=>{_(M.currentTarget)},[_]);return x("div",{style:{position:"relative"},children:[T("textarea",{ref:N,className:J,value:Q,placeholder:Z,rows:G,disabled:W,"aria-label":H,onChange:P,onKeyDown:L,onFocus:q,onSelect:O,onClick:O}),Y&&F.length>0?T("ul",{className:"cm-mention-popup",role:"listbox","aria-label":"Mention suggestions",style:{left:0,top:"100%"},children:F.map((M,I)=>{return x("li",{role:"option","aria-selected":I===D,className:"cm-mention-popup__item",onMouseEnter:()=>A(I),onMouseDown:(k)=>{k.preventDefault(),B(M)},children:[x("span",{className:"cm-mention-popup__name",children:["@",qJ(M.name)]}),T("span",{className:"cm-mention-popup__email",children:M.email})]},`${M.name}-${M.email}`)})}):null]})}var WQ=3000;function KQ(J){return{x:J.x-12,y:J.y-12,w:24,h:24}}function zQ(J){let Q=!!J.selector||o(J.annotationId);if(Q){let Z=O7(J);if(Z)return{pos:Z,missing:!1}}let $=m7(J.world)?i7(J.world):null;return{pos:$?KQ($):J.bounds??null,missing:Q}}function UQ({comment:J,sequence:Q,focused:$,onClick:V}){let Z=g(null),G=g(null),W=g(null),[K,H]=h(!1),j=g(!1);R(()=>{let z=()=>{G.current=null;let Y=Z.current;if(!Y)return;let{pos:U,missing:D}=zQ(J),A=!1;if(D){if(W.current==null)W.current=Date.now();A=Date.now()-W.current>WQ}else W.current=null;if(A!==j.current)j.current=A,H(A);if(!U){Y.style.display="none",G.current=requestAnimationFrame(z);return}Y.style.display="grid";let q=Math.round(U.x+U.w-12),F=Math.round(U.y-12);Y.style.left=`${q}px`,Y.style.top=`${F}px`,G.current=requestAnimationFrame(z)};return G.current=requestAnimationFrame(z),()=>{if(G.current!=null)cancelAnimationFrame(G.current)}},[J]);let N=J.author?.trim()||"unknown",X=`Comment ${Q} by ${N}${K?" (detached: its target is gone)":""}`;return T("button",{ref:Z,type:"button",className:"cm-pin","data-resolved":J.status==="resolved"?"true":"false","data-focused":$?"true":"false","data-detached":K?"true":"false","data-comment-pin":J.id,"aria-label":X,"aria-expanded":$,title:J.text.slice(0,200),onClick:(z)=>{z.preventDefault(),z.stopPropagation(),V(J.id)},children:Q})}function HQ({state:J,onSubmit:Q,onCancel:$}){let[V,Z]=h(""),G=g(null),W=g(null),K=g(null);R(()=>{let X=()=>{K.current=null;let z=W.current;if(!z)return;let Y=LQ(J),U=KJ(Y,{w:z.offsetWidth,h:z.offsetHeight});z.style.left=`${Math.round(U.x)}px`,z.style.top=`${Math.round(U.y)}px`,K.current=requestAnimationFrame(X)};return K.current=requestAnimationFrame(X),()=>{if(K.current!=null)cancelAnimationFrame(K.current)}},[J]),R(()=>{G.current?.focus()},[]);let H=b(()=>{let X=V.trim();if(!X)return;Q(X)},[V,Q]),j=b((X)=>{if(X.key==="Escape"){X.preventDefault(),$();return}if((X.metaKey||X.ctrlKey)&&X.key==="Enter")X.preventDefault(),H()},[$,H]),N=t(()=>{let X=J.selection.selector||"";if(!X)return J.selection.tag||(J.selection.annotationId?"annotation":"canvas");let z=X.match(/data-cd-id="([^"]+)"/);if(z)return`cd:${z[1]}`;return X.length>36?`${X.slice(0,33)}…`:X},[J.selection]);return x("div",{ref:W,className:"cm-composer",role:"dialog","aria-label":"New comment",onClick:(X)=>X.stopPropagation(),onPointerDown:(X)=>X.stopPropagation(),children:[x("div",{className:"cm-composer__head",children:[T("span",{children:"New comment"}),T("span",{className:"cm-composer__selector",children:N})]}),T(I7,{textareaRef:G,className:"cm-composer__textarea",value:V,placeholder:"Type a comment. ⌘↵ to save · Esc to cancel · @name to tag",onChange:Z,onKeyDown:j,rows:3,ariaLabel:"Comment body"}),x("div",{className:"cm-composer__actions",children:[T("button",{type:"button",className:"cm-btn",onClick:$,children:"Cancel"}),T("button",{type:"button",className:"cm-btn cm-btn--primary",disabled:!V.trim(),onClick:H,children:"Save"})]})]})}var GJ=null;function XQ(){let[J,Q]=h(null);return R(()=>{if(typeof fetch>"u")return;GJ??=fetch("/_api/git-user").then((V)=>V.ok?V.json():null).then((V)=>typeof V?.name==="string"&&V.name.trim()?V.name.trim():null).catch(()=>null);let $=!0;return GJ.then((V)=>$&&Q(V)),()=>{$=!1}},[]),J}function FQ({comment:J,sequence:Q,onClose:$,onPatch:V,onDelete:Z,onReply:G,mine:W=!1}){let K=g(null),H=g(null),j=g(null),[N,X]=h(""),[z,Y]=h(!1),[U,D]=h(null),A=b(()=>{let B=(U??"").trim();if(!B)return;if(B!==J.text)V({text:B});D(null)},[U,J.text,V]);R(()=>{let B=()=>{j.current=null;let L=K.current;if(!L)return;let O=PQ(J),M=KJ(O,{w:L.offsetWidth,h:L.offsetHeight});L.style.left=`${Math.round(M.x)}px`,L.style.top=`${Math.round(M.y)}px`,j.current=requestAnimationFrame(B)};return j.current=requestAnimationFrame(B),()=>{if(j.current!=null)cancelAnimationFrame(j.current)}},[J]),R(()=>{K.current?.focus();let B=J.id;return()=>{document.querySelector(`[data-comment-pin="${B}"]`)?.focus()}},[J.id]),R(()=>{if(typeof document>"u")return;let B=(L)=>{if(L.key!=="Escape")return;let O=K.current;if(!O)return;if(O.contains(L.target)||document.activeElement===O)L.preventDefault(),$()};return document.addEventListener("keydown",B),()=>document.removeEventListener("keydown",B)},[$]);let q=b(async()=>{let B=N.trim();if(!B||z)return;Y(!0);let L=await G(B);if(Y(!1),L)X(""),H.current?.focus()},[N,z,G]),F=b((B)=>{if((B.metaKey||B.ctrlKey)&&B.key==="Enter")B.preventDefault(),q()},[q]),_=`cm-thread-head-${J.id}`,P=YQ(J.selector,"");return x("div",{ref:K,className:"cm-thread",role:"dialog","aria-labelledby":_,tabIndex:-1,onClick:(B)=>B.stopPropagation(),onPointerDown:(B)=>B.stopPropagation(),children:[x("div",{className:"cm-thread__head",id:_,children:[x("div",{className:"cm-thread__head-row",children:[T("span",{className:"cm-thread__seq","aria-hidden":"true",children:Q}),T("span",{className:"cm-thread__author",children:J.author?.trim()||"unknown"}),T("span",{className:"cm-thread__time",children:WJ(J.created)}),T("button",{type:"button",className:"cm-thread__close","aria-label":"Close thread",title:"Close · Esc",onClick:$,children:"×"})]}),P?T("code",{className:"cm-thread__selector",children:P}):null]}),U===null?T("div",{className:"cm-thread__body",children:BJ(J.text)}):x("div",{className:"cm-thread__reply-form",children:[T(I7,{className:"cm-thread__reply-textarea",value:U,placeholder:"Edit your comment… ⌘↵ to save",onChange:D,onKeyDown:(B)=>{if((B.metaKey||B.ctrlKey)&&B.key==="Enter")B.preventDefault(),A()},rows:3,ariaLabel:"Edit comment"}),x("div",{className:"cm-thread__reply-actions",children:[T("button",{type:"button",className:"cm-btn",onClick:()=>D(null),children:"Cancel"}),T("button",{type:"button",className:"cm-btn cm-btn--primary","data-testid":"comment-edit-save",disabled:!U.trim(),onClick:A,children:"Save"})]})]}),(J.thread??[]).map((B)=>x("div",{className:"cm-thread__reply",children:[x("div",{className:"cm-thread__reply-head",children:[T("span",{className:"cm-thread__reply-author",children:B.author?.trim()||"unknown"}),T("span",{className:"cm-thread__reply-time",children:WJ(B.created)})]}),T("div",{className:"cm-thread__reply-body",children:BJ(B.body)})]},B.id)),!a()&&x(DQ,{children:[x("div",{className:"cm-thread__reply-form",children:[T(I7,{textareaRef:H,className:"cm-thread__reply-textarea",value:N,placeholder:"Reply… ⌘↵ to send · @name to tag",onChange:X,onKeyDown:F,rows:2,ariaLabel:"Reply",disabled:z}),T("div",{className:"cm-thread__reply-actions",children:T("button",{type:"button",className:"cm-btn cm-btn--primary",disabled:!N.trim()||z,onClick:()=>void q(),children:"Send"})})]}),x("div",{className:"cm-thread__actions",children:[W&&U===null?T("button",{type:"button",className:"cm-btn","data-testid":"comment-edit",onClick:()=>D(J.text),children:"Edit"}):null,J.status==="resolved"?T("button",{type:"button",className:"cm-btn",onClick:()=>V({status:"open"}),children:"↺ Reopen"}):T("button",{type:"button",className:"cm-btn cm-btn--primary",onClick:()=>{V({status:"resolved"}),$()},children:"✓ Resolve"}),T("button",{type:"button",className:"cm-btn cm-btn--danger",onClick:()=>{Z(),$()},children:"Delete"})]})]})]})}function BJ(J){if(!J)return null;let Q=/(@[\w][\w.-]*)/g;return J.split(Q).map((V,Z)=>{let G=`${Z}:${V}`;if(Z%2===1)return T("strong",{"data-mention":"true",children:V},G);return T("span",{children:V},G)})}function WJ(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 YQ(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 PQ(J){let Q=J.selector?O7(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 LQ(J){if(J.clientX||J.clientY)return{x:J.clientX,y:J.clientY+8};if(J.selection.selector){let Q=O7(J.selection);if(Q)return{x:Q.x,y:Q.y+Q.h+8}}return{x:16,y:16}}import{useEffect as MQ}from"react";var jQ=new Set(["pen","highlighter","shape","rect","ellipse","arrow","sticky","text","section","eraser"]);function k7(J){return jQ.has(J)}var e=(J)=>!!(J.metaKey||J.ctrlKey);function J7(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(k7(J.activeTool))return{kind:"no-op"};if(J.activeTool==="hand")return{kind:"no-op"};if(J.activeTool==="browse"){if(!e(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:e(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(k7(J.activeTool)&&!e(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(!e(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=e(J);return{kind:"select",mode:!!J.shiftKey?"add":"replace",deep:Q,clientX:J.clientX??0,clientY:J.clientY??0}}return{kind:"no-op"}}function U7(J){if(!J||!J.tagName)return!1;let Q=J,$=Q.tagName;if($==="INPUT"||$==="TEXTAREA"||$==="SELECT")return!0;if(Q.isContentEditable)return!0;let V=Q.getAttribute?.("contenteditable");if(V==="true"||V==="plaintext-only"||V==="")return!0;return!1}function Q7(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 HJ(J){if(!J||typeof J.closest!=="function")return!1;let Q=J;return!!Q.closest("[data-dc-screen]")&&!Q.closest(".dc-artboard-body")}function UJ(J,Q,$){return J.kind==="select"&&!$.metaKey&&!$.ctrlKey&&HJ(Q)}function NQ(J,Q,$){return J==="select"&&!$.metaKey&&!$.ctrlKey&&HJ(Q)}function XJ(J){let{hostRef:Q,getActiveTool:$,isSpaceHeld:V,callbacks:Z,enabled:G=!0,claimableActions:W}=J;MQ(()=>{if(!G)return;let K=Q.current;if(!K)return;let H=(q)=>W&&q.kind!=="no-op"&&!W.has(q.kind)?{kind:"no-op"}:q,j=(q)=>{switch(q.kind){case"hover":Z.onHover?.(q);break;case"select":Z.onSelect?.(q);break;case"drop-comment":Z.onDropComment?.(q);break;case"context-menu":Z.onContextMenu?.(q);break;case"tool":Z.onTool?.(q);break;case"escape":Z.onEscape?.();break;case"undo":Z.onUndo?.();break;case"redo":Z.onRedo?.();break;case"no-op":break}},N=(q)=>{let F=H(J7({type:"pointermove",button:q.button,metaKey:q.metaKey,ctrlKey:q.ctrlKey,shiftKey:q.shiftKey,altKey:q.altKey,clientX:q.clientX,clientY:q.clientY,spaceHeld:V?.()??!1,activeTool:$()}));j(F)},X=(q)=>{if(Q7(q.target))return;if(U7(q.target))return;let F=H(J7({type:"pointerdown",button:q.button,metaKey:q.metaKey,ctrlKey:q.ctrlKey,shiftKey:q.shiftKey,altKey:q.altKey,clientX:q.clientX,clientY:q.clientY,spaceHeld:V?.()??!1,activeTool:$()})),_=UJ(F,q.target,q);if(F.kind!=="no-op"){if(q.preventDefault(),!_)q.stopImmediatePropagation()}j(F)},z=(q)=>{if(Q7(q.target))return;if(U7(q.target))return;let F=H(J7({type:"pointerdown",button:q.button,metaKey:q.metaKey,ctrlKey:q.ctrlKey,shiftKey:q.shiftKey,altKey:q.altKey,clientX:q.clientX,clientY:q.clientY,spaceHeld:V?.()??!1,activeTool:$()})),_=UJ(F,q.target,q);if(F.kind!=="no-op"){if(q.preventDefault(),!_)q.stopImmediatePropagation();if(F.kind==="select")try{window.focus()}catch{}}},Y=(q)=>{if(Q7(q.target))return;if(U7(q.target))return;let F=$(),_=q.metaKey||q.ctrlKey,P=F==="comment"?"drop-comment":F==="move"&&q.button===0?"select":(k7(F)||F==="browse")&&_&&q.button===0?"select":q.button===2?"context-menu":null;if(P&&(!W||W.has(P))){let B=NQ(P,q.target,q);if(q.preventDefault(),!B)q.stopImmediatePropagation()}},U=(q)=>{let F=H(J7({type:"contextmenu",clientX:q.clientX,clientY:q.clientY,metaKey:q.metaKey,ctrlKey:q.ctrlKey,shiftKey:q.shiftKey,altKey:q.altKey,activeTool:$()}));if(F.kind==="no-op")return;q.preventDefault(),q.stopImmediatePropagation(),j(F)},D=(q)=>{let F=H(J7({type:"keydown",key:q.key,metaKey:q.metaKey,ctrlKey:q.ctrlKey,shiftKey:q.shiftKey,altKey:q.altKey,isEditable:U7(q.target),activeTool:$()}));if(F.kind==="tool"||F.kind==="escape"||F.kind==="undo"||F.kind==="redo")q.preventDefault();j(F)};K.addEventListener("pointermove",N,{passive:!0}),K.addEventListener("pointerdown",X,{capture:!0}),K.addEventListener("mousedown",z,{capture:!0}),K.addEventListener("click",Y,{capture:!0}),K.addEventListener("contextmenu",U,{capture:!0});let A=K.ownerDocument??document;return A.addEventListener("keydown",D,!0),()=>{K.removeEventListener("pointermove",N),K.removeEventListener("pointerdown",X,{capture:!0}),K.removeEventListener("mousedown",z,{capture:!0}),K.removeEventListener("click",Y,{capture:!0}),K.removeEventListener("contextmenu",U,{capture:!0}),A.removeEventListener("keydown",D,!0)}},[G,Q,$,V,Z,W])}function E7(J,Q,$,V){let Z=J.elementFromPoint(Q,$);if(!Z)return null;if(Z.closest?.(".dc-mm, .dc-zoom-tb, .dc-tool-palette, .dc-context-menu, .dc-cv-group-bbox"))return null;let G=Z.closest?.("[data-dc-screen]")??null,W=G?.getAttribute("data-dc-screen")??null,K=Z.closest?.(".dc-artboard-body")??null;if(!K){if(G&&W)return{el:G,cdId:null,artboardId:W};return null}if(Z===K){if(G&&W)return{el:G,cdId:null,artboardId:W};return null}if(V.deep){let z=Z.getAttribute?.("data-cd-id")??null;return{el:Z,cdId:z,artboardId:W}}let H=Z,j=null;while(H&&H!==K){if(H.hasAttribute?.("data-cd-id"))j=H;H=H.parentElement}let N=j??Z,X=N.getAttribute?.("data-cd-id")??null;return{el:N,cdId:X,artboardId:W}}import{useCallback as gQ,useEffect as NJ,useRef as F7}from"react";var _Q=!1;function FJ(){return _Q}import{createContext as xQ,useCallback as V7,useContext as MJ,useEffect as x7,useMemo as PJ,useRef as y7,useState as H7}from"react";function m(J,Q,$,V){return`url("data:image/svg+xml,${encodeURIComponent(J.trim())}") ${Q} ${$}, ${V}`}var w7="width='24' height='24' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'",b7="#1f1f1f",T7="stroke='#ffffff' stroke-linejoin='round' stroke-linecap='round'";function c(J,Q,$){let V=$?`<g transform='${$}'>`:"";return`<svg ${w7}>${V}<path fill='#ffffff' d='${J}'/><path fill='${b7}' d='${Q}'/>${$?"</g>":""}</svg>`}var YJ="translate(0,32) scale(1,-1)",AQ=m(c("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"),IQ=m(c("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"),OQ=m(c("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"),kQ=m(c("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",YJ),6,18,"crosshair"),EQ=m(c("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",YJ),6,18,"crosshair"),$7=m(c("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"),TQ=m(c("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"),wQ=m(`<svg ${w7}><path d='M16 4V28M11 4H21M11 28H21' fill='none' ${T7} stroke-width='5'/><path d='M16 4V28M11 4H21M11 28H21' fill='none' stroke='${b7}' stroke-width='2.25' stroke-linecap='round'/></svg>`,12,12,"text"),bQ=m(`<svg ${w7}><path d='M6 5H21L26 10V27H6Z' fill='${b7}' ${T7} stroke-width='2.5'/><path d='M21 5V11H26' fill='none' ${T7} stroke-width='2.25'/></svg>`,5,5,"crosshair"),v=Object.freeze({browse:"default",move:AQ,hand:IQ,comment:OQ,pen:kQ,section:$7,highlighter:EQ,shape:$7,rect:$7,ellipse:$7,sticky:bQ,arrow:$7,text:wQ,eraser:TQ});import{jsx as v7,Fragment as RQ}from"react/jsx-runtime";var C7="maude:tool-sync",LJ=Object.freeze({preview:"browse",edit:"move"});function DJ(J){if(J==="browse")return"preview";if(J==="move")return"edit";return null}var yQ=Object.freeze([{id:"browse",label:"Browse",shortcut:"",cursor:v.browse},{id:"move",label:"Select",shortcut:"V",cursor:v.move},{id:"hand",label:"Hand",shortcut:"H",cursor:v.hand},{id:"comment",label:"Comment",shortcut:"C",cursor:v.comment},{id:"pen",label:"Pen",shortcut:"B",cursor:v.pen},{id:"highlighter",label:"Highlighter",shortcut:"I",cursor:v.highlighter},{id:"shape",label:"Shape",shortcut:"R",cursor:v.shape},{id:"sticky",label:"Sticky",shortcut:"N",cursor:v.sticky},{id:"section",label:"Section",shortcut:"⇧S",cursor:v.shape},{id:"arrow",label:"Arrow",shortcut:"A",cursor:v.arrow},{id:"text",label:"Text",shortcut:"T",cursor:v.text},{id:"eraser",label:"Eraser",shortcut:"E",cursor:v.eraser}]),CQ=new Set(["browse","move","hand"]);function vQ(J,Q){return Q?J.filter(($)=>CQ.has($.id)):J}var S7=xQ(null);function SQ({children:J,tools:Q=yQ,initial:$,initialMode:V}){let Z=a(),G=PJ(()=>vQ(Q,Z),[Q,Z]),W=$??(Z?"browse":"move"),K=V??DJ(W)??(Z?"preview":"edit"),[H,j]=H7(W),[N,X]=H7(K),[z,Y]=H7(()=>({tool:null,locked:!1})),U=V7((I)=>{if(!G.some((k)=>k.id===I))return;j(I);let E=DJ(I);if(E)X(E);Y((k)=>k.locked&&k.tool===I?k:{tool:null,locked:!1})},[G]),D=V7((I)=>{let E=LJ[I];if(!G.some((k)=>k.id===E))return;X(I),j(E),Y((k)=>k.locked&&k.tool===E?k:{tool:null,locked:!1})},[G]),A=V7(()=>{U(LJ[N])},[N,U]),q=V7((I)=>{Y((E)=>{if(E.locked&&E.tool===I)return{tool:null,locked:!1};return{tool:I,locked:!0}}),j(I)},[]),F=V7(()=>{Y({tool:null,locked:!1})},[]),[_,P]=H7("rounded"),B=y7(Math.random().toString(36).slice(2)),L=y7(H);L.current=H;let O=y7(!1);x7(()=>{if(!O.current){O.current=!0;return}if(typeof document>"u")return;document.dispatchEvent(new CustomEvent(C7,{detail:{tool:H,from:B.current}}))},[H]),x7(()=>{if(typeof document>"u")return;let I=(E)=>{let k=E.detail;if(!k||k.from===B.current||typeof k.tool!=="string")return;if(k.tool===L.current)return;U(k.tool)};return document.addEventListener(C7,I),()=>document.removeEventListener(C7,I)},[U]),x7(()=>{if(typeof document>"u")return;let I=G.find((w)=>w.id===H);if(!I)return;let E=document.body.style.cursor,k=document.getElementById("dc-tool-cursor");if(!k)k=document.createElement("style"),k.id="dc-tool-cursor",document.head.appendChild(k);if(H==="browse"){if(document.body.style.cursor="",k.textContent="",typeof window<"u"&&window.parent&&window.parent!==window)try{window.parent.postMessage({dgn:"tool-cursor",tool:H},"*")}catch{}return()=>{document.body.style.cursor=E}}if(document.body.style.cursor=I.cursor,k.textContent=`* { cursor: ${I.cursor} !important; }`,typeof window<"u"&&window.parent&&window.parent!==window)try{window.parent.postMessage({dgn:"tool-cursor",tool:H},"*")}catch{}return()=>{document.body.style.cursor=E;let w=document.getElementById("dc-tool-cursor");if(w)w.textContent=""}},[H,G]);let M=PJ(()=>({tool:H,setTool:U,tools:G,mode:N,setMode:D,resetTool:A,sticky:z,toggleSticky:q,clearSticky:F,shapeKind:_,setShapeKind:P}),[H,U,G,N,D,A,z,q,F,_]);return v7(S7.Provider,{value:M,children:J})}function jJ({children:J,initial:Q,initialMode:$}){if(MJ(S7))return v7(RQ,{children:J});return v7(SQ,{initial:Q,initialMode:$,children:J})}function X7(){let J=MJ(S7);if(!J)throw Error("useToolMode must be used inside <ToolProvider>");return J}import{jsx as oQ}from"react/jsx-runtime";var hQ=`
|
|
2
2
|
.dc-el-resize-handle {
|
|
3
3
|
position: fixed;
|
|
4
4
|
width: 8px;
|
|
@@ -56,4 +56,4 @@ import{Component as pQ,createElement as S7,useCallback as C7,useEffect as p,useM
|
|
|
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 TQ(){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=wQ,document.head.appendChild(J)}var bQ=["nw","n","ne","e","se","s","sw","w"];function xQ(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,H7=1;function yQ(J,Q,$,V,Z,G){let{movesLeft:B,movesRight:K,movesTop:Y,movesBottom:j}=xQ(J),N=Z.center,U=Q.w,z=Q.h;if(K)U=Q.w+(N?2*$:$);else if(B)U=Q.w-(N?2*$:$);if(j)z=Q.h+(N?2*V:V);else if(Y)z=Q.h-(N?2*V:V);if(Z.aspect&&Q.w>0&&Q.h>0){let X=Q.w/Q.h;if((B||K)&&(Y||j)){let O=Math.abs(U-Q.w)/Q.w,q=Math.abs(z-Q.h)/Q.h;if(O>=q)z=U/X;else U=z*X}else if(B||K)z=U/X;else if(Y||j)U=z*X}if(U<H7)U=H7;if(z<H7)z=H7;let P={width:n(U),height:n(z)};if(N){if(G.canMoveLeft&&(B||K))P.left=n(Q.left+(Q.w-U)/2);if(G.canMoveTop&&(Y||j))P.top=n(Q.top+(Q.h-z)/2)}else{if(G.canMoveLeft&&B)P.left=n(Q.left+Q.w-U);if(G.canMoveTop&&Y)P.top=n(Q.top+Q.h-z)}return P}function YJ(J){if(!J||J==="none")return 0;let Q=/matrix\(([^)]+)\)/.exec(J);if(!Q)return 0;let $=Q[1].split(",").map(Number),V=$[0]??1,Z=$[1]??0;return Math.round(Math.atan2(Z,V)*(180/Math.PI)*100)/100}function vQ(J){if(!J||J==="none")return 1;let Q=/matrix\(([^)]+)\)/.exec(J);if(!Q)return 1;let $=Q[1].split(",").map(Number),V=$[0]??1,Z=$[1]??0,G=Math.hypot(V,Z);return G>0?G:1}function CQ(J){let Q=J.closest(".dc-world");if(!Q)return 1;let $=getComputedStyle(Q),V=Number.parseFloat($.zoom||"1")||1;return vQ($.transform)*V}function FJ(J,Q,$){let V=$*Math.PI/180,Z=Math.cos(V),G=Math.sin(V);return[J*Z-Q*G,J*G+Q*Z]}function PJ(J,Q,$,V){return Math.atan2(V-Q,$-J)}function SQ(J,Q,$,V){let Z=J+($-Q)*(180/Math.PI);while(Z>180)Z-=360;while(Z<=-180)Z+=360;if(V)Z=Math.round(Z/15)*15;return Math.round(Z*100)/100}function RQ(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 gQ(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 hQ(J,Q){try{window.parent.postMessage({dgn:"resize-request",id:J.cdId,patch:{transform:Q},before:J.before,idIndex:J.idIndex},"*")}catch{}}function DJ(){TQ();let{selected:J}=W7(),{tool:Q}=U7(),$=X7(null),V=X7(null),Z=X7(null),G=X7(null),B=J.length===1?J[0]:null,K=B&&typeof B.id==="string"?B.id:null,Y=B&&!K&&typeof B.artboardId==="string"?B.artboardId:null,j=Q==="move"&&(!!K||!!Y);HJ(()=>{let U=$.current;if(!U)return;let z=()=>{for(let X of Array.from(U.children)){let M=X;M.style.opacity="0",M.style.pointerEvents="none"}};if(!j||!B){z();return}let P=()=>{if(V.current=null,GJ()){z(),V.current=requestAnimationFrame(P);return}let X=P7(document,B);if(!X){z(),V.current=requestAnimationFrame(P);return}let M=X.getBoundingClientRect();if(M.width<=0&&M.height<=0){z(),V.current=requestAnimationFrame(P);return}let O=Y?["e","s","se"]:bQ,q=Y?[]:["rot-nw","rot-ne","rot-sw","rot-se"],H=O.length+q.length+1;while(U.children.length<H)U.appendChild(document.createElement("div"));while(U.children.length>H)U.lastChild&&U.removeChild(U.lastChild);let _=M.left+M.width/2,F=M.top+M.height/2,W=YJ(getComputedStyle(X).transform),D=CQ(X),A=X.offsetWidth*D/2,L=X.offsetHeight*D/2,I={nw:[-A,-L],n:[0,-L],ne:[A,-L],e:[A,0],se:[A,L],s:[0,L],sw:[-A,L],w:[-A,0],"rot-nw":[-A,-L],"rot-ne":[A,-L],"rot-sw":[-A,L],"rot-se":[A,L]},E=[...q,...O];for(let f=0;f<E.length;f++){let y=E[f],v=U.children[f],[d,c]=I[y]??[0,0],[IJ,AJ]=FJ(d,c,W),OJ=_+IJ,kJ=F+AJ,Y7=y.startsWith("rot-"),g7=y==="n"||y==="s",h7=y==="e"||y==="w",EJ=Y7?10:g7?7:h7?3:4,wJ=Y7?10:g7?3:h7?7:4;v.className="dc-el-resize-handle",v.dataset.corner=y,v.style.opacity="1",v.style.pointerEvents="auto",v.style.left=`${Math.round(OJ-EJ)}px`,v.style.top=`${Math.round(kJ-wJ)}px`,v.style.transform=Y7?"":`rotate(${W}deg)`}let k=U.children[E.length],T=Z.current;if(T&&T.el===X&&!T.corner.startsWith("rot-")){let f=T.lastResult?.width??X.offsetWidth,y=T.lastResult?.height??X.offsetHeight,v=`${Math.round(f)} × ${Math.round(y)}`,d=T.lastResult?.left,c=T.lastResult?.top;if(typeof d==="number"||typeof c==="number")v+=` · ${Math.round(d??T.start.left)}, ${Math.round(c??T.start.top)}`;k.className="dc-el-resize-readout",k.textContent=v,k.style.opacity="1",k.style.left=`${Math.round(_)}px`,k.style.top=`${Math.round(F+L)}px`}else k.style.opacity="0";V.current=requestAnimationFrame(P)};return V.current=requestAnimationFrame(P),()=>{if(V.current!=null)cancelAnimationFrame(V.current)}},[j,B,Y]);let N=EQ((U,z)=>{if(U.el.style.width=`${z.width}px`,U.el.style.height=`${z.height}px`,typeof z.left==="number")U.el.style.left=`${z.left}px`;if(typeof z.top==="number")U.el.style.top=`${z.top}px`;U.lastResult=z},[]);return HJ(()=>{let U=$.current;if(!U)return;let z=(q,H)=>{let[_,F]=FJ(H.clientX-q.startClientX,H.clientY-q.startClientY,-q.angle);return yQ(q.corner,q.start,_/q.elZoom,F/q.elZoom,{aspect:!!H.shiftKey,center:!q.artboardId&&!!H.altKey},q.flags)},P=(q)=>{let H=q.target;if(!H?.classList.contains("dc-el-resize-handle"))return;let _=H.dataset.corner;if(!_||!B)return;let F=typeof B.id==="string"?B.id:null,W=!F&&typeof B.artboardId==="string"?B.artboardId:null;if(!F&&!W)return;let D=P7(document,B);if(!D)return;q.preventDefault(),q.stopPropagation();let A=D.getBoundingClientRect(),L=D.offsetWidth?A.width/D.offsetWidth:1,I=getComputedStyle(D),E=!W&&(I.position==="absolute"||I.position==="fixed"),k=W?Number.NaN:Number.parseFloat(D.style.left),T=W?Number.NaN:Number.parseFloat(D.style.top),f=W?0:YJ(I.transform),y=L>0?L:1,v=A.left+A.width/2,d=A.top+A.height/2,c={pointerId:q.pointerId,corner:_,el:D,cdId:F??"",artboardId:W,idIndex:F?d7(document,F,D):0,startClientX:q.clientX,startClientY:q.clientY,elZoom:y,angle:f,cx:v,cy:d,rotStartPointer:PJ(v,d,q.clientX,q.clientY),start:{w:(f?D.offsetWidth:A.width/y)||A.width/y,h:(f?D.offsetHeight:A.height/y)||A.height/y,left:k,top:T},flags:{canMoveLeft:E&&Number.isFinite(k),canMoveTop:E&&Number.isFinite(T)},before:{width:D.style.width||null,height:D.style.height||null,left:D.style.left||null,top:D.style.top||null,transform:D.style.transform||null},lastResult:null,lastTransform:null};Z.current=c;try{H.setPointerCapture(q.pointerId)}catch{}},X=(q)=>{let H=Z.current;if(!H||q.pointerId!==H.pointerId)return;if(q.preventDefault(),H.corner.startsWith("rot-")){let F=`rotate(${SQ(H.angle,H.rotStartPointer,PJ(H.cx,H.cy,q.clientX,q.clientY),!!q.shiftKey)}deg)`;H.el.style.transform=F,H.lastTransform=F;return}N(H,z(H,q))},M=(q)=>{let H=Z.current;if(!H||q.pointerId!==H.pointerId)return;if(Z.current=null,H.corner.startsWith("rot-")){let W=H.lastTransform;if(!W||W===H.before.transform)return;G.current={el:H.el,before:H.before},hQ(H,W);return}let _=H.lastResult??z(H,q);if(!(`${_.width}px`!==H.before.width||`${_.height}px`!==H.before.height||typeof _.left==="number"&&`${_.left}px`!==H.before.left||typeof _.top==="number"&&`${_.top}px`!==H.before.top))return;if(G.current={el:H.el,before:H.before},H.artboardId)gQ(H,_);else RQ(H,_)},O=(q)=>{let H=q.data;if(H?.dgn!=="resize-failed"&&H?.dgn!=="resize-artboard-failed")return;if(q.source!==window.parent)return;let _=G.current;if(!_)return;if(_.el.style.width=_.before.width??"",_.el.style.height=_.before.height??"",_.before.left!==null||_.el.style.left)_.el.style.left=_.before.left??"";if(_.before.top!==null||_.el.style.top)_.el.style.top=_.before.top??"";if(_.before.transform!==null||_.el.style.transform)_.el.style.transform=_.before.transform??"";G.current=null};return U.addEventListener("pointerdown",P),window.addEventListener("pointermove",X),window.addEventListener("pointerup",M),window.addEventListener("pointercancel",M),window.addEventListener("message",O),()=>{U.removeEventListener("pointerdown",P),window.removeEventListener("pointermove",X),window.removeEventListener("pointerup",M),window.removeEventListener("pointercancel",M),window.removeEventListener("message",O)}},[B,N]),fQ("div",{ref:$,"aria-hidden":"true"})}import{jsx as S,jsxs as _J,Fragment as tQ}from"react/jsx-runtime";var dQ=new Set(["drop-comment","tool","escape","hover"]);function Z7(){return typeof document<"u"&&!document.querySelector(".dc-canvas")}function R7(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 V=$.tagName;if(V==="HTML"||V==="BODY")return null;return $}function iQ(J,Q){let $=R7(J,Q);if(!$)return null;return $.closest("[data-cd-id]")??$}function cQ({children:J,file:Q}){let{tool:$,setTool:V}=U7(),Z=W7(),G=u(null),[B,K]=V7(null),Y=u($);Y.current=$;let j=uQ(()=>()=>Y.current,[]);p(()=>{if($!=="comment")K(null)},[$]);let[N,U]=V7(null),[z,P]=V7(!1);return p(()=>{let X=()=>P(Z7());X();let M=requestAnimationFrame(X),O=setTimeout(X,120);return()=>{cancelAnimationFrame(M),clearTimeout(O)}},[]),p(()=>{if(typeof document>"u")return;let X=(M)=>{if(M.button!==0||!(M.metaKey||M.ctrlKey))return;if(!Z7())return;if(J7(M.target))return;let O=iQ(M.clientX,M.clientY);if(!O)return;M.preventDefault(),M.stopImmediatePropagation();let q=O.getAttribute("data-cd-id"),H=D7({el:O,cdId:q,artboardId:null});if(M.shiftKey)Z.add(H);else Z.replace(H);U(O)};return document.addEventListener("pointerdown",X,!0),()=>document.removeEventListener("pointerdown",X,!0)},[Z]),p(()=>{if(Z.selected.length===0)U(null)},[Z.selected]),p(()=>{let X=G.current;if(X)X.setAttribute("data-active-tool",$);if(typeof document<"u"&&document.body)document.body.setAttribute("data-active-tool",$);return()=>{X?.removeAttribute("data-active-tool")}},[$]),p(()=>{if(typeof window>"u")return;let X=(M)=>{let O=M.data;if(!O||typeof O!=="object"||O.dgn!=="tool-set")return;if(typeof O.tool==="string")V(O.tool)};return window.addEventListener("message",X),()=>window.removeEventListener("message",X)},[V]),qJ({hostRef:G,getActiveTool:j,claimableActions:dQ,callbacks:{onHover:({clientX:X,clientY:M})=>{if(Y.current!=="comment"||!Z7()){K(null);return}let O=R7(X,M);K((q)=>q===O?q:O)},onTool:({tool:X})=>V(X),onEscape:()=>{if(Y.current!=="move")V("move");if(K(null),Z.clear(),typeof window<"u")try{window.parent.postMessage({dgn:"force-clear"},"*")}catch{}},onDropComment:({clientX:X,clientY:M})=>nQ(X,M,Z,Q)}}),_J("div",{"data-mc-host":!0,ref:G,style:{display:"contents"},children:[J,B?S(rQ,{el:B}):null,N?S(lQ,{el:N}):null,z?S(DJ,{}):null,S($J,{})]})}function lQ({el:J}){let Q=u(null),$=u(J);$.current=J;let V=u(null);return p(()=>{let Z=()=>{V.current=null;let G=Q.current,B=$.current;if(G&&B?.isConnected){let K=B.getBoundingClientRect();if(K.width===0&&K.height===0)G.style.display="none";else G.style.display="block",G.style.left=`${Math.round(K.left)}px`,G.style.top=`${Math.round(K.top)}px`,G.style.width=`${Math.round(K.width)}px`,G.style.height=`${Math.round(K.height)}px`}else if(G)G.style.display="none";V.current=requestAnimationFrame(Z)};return V.current=requestAnimationFrame(Z),()=>{if(V.current!=null)cancelAnimationFrame(V.current)}},[]),S("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 rQ({el:J}){let Q=u(null),$=u(J);$.current=J;let V=u(null);return p(()=>{let Z=()=>{V.current=null;let G=Q.current,B=$.current;if(G&&B?.isConnected){let K=B.getBoundingClientRect();if(K.width===0&&K.height===0)G.style.display="none";else G.style.display="block",G.style.left=`${Math.round(K.left)}px`,G.style.top=`${Math.round(K.top)}px`,G.style.width=`${Math.round(K.width)}px`,G.style.height=`${Math.round(K.height)}px`}else if(G)G.style.display="none";V.current=requestAnimationFrame(Z)};return V.current=requestAnimationFrame(Z),()=>{if(V.current!=null)cancelAnimationFrame(V.current)}},[]),S("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 nQ(J,Q,$,V){if(typeof document>"u")return;let Z=O7(document,J,Q,{deep:!0});if(!Z)Z=O7(document,J,Q,{deep:!1});if(!Z&&!Z7()&&typeof document.elementsFromPoint==="function"){let B=document.elementsFromPoint(J,Q);for(let K of B){let Y=K.closest?.("[data-cd-id]");if(!Y)continue;if(!Y.closest(".dc-artboard-body"))continue;let j=Y.closest("[data-dc-screen]");Z={el:Y,cdId:Y.getAttribute("data-cd-id"),artboardId:j?.getAttribute("data-dc-screen")??null};break}}if(!Z&&Z7()){let B=R7(J,Q);if(B)Z={el:B,cdId:B.getAttribute("data-cd-id"),artboardId:null}}if(!Z){let B={file:V,id:void 0,selector:"",artboardId:null,tag:"",classes:"",text:"",dom_path:[],bounds:{x:J-12,y:Q-12,w:24,h:24},html:""};LJ(B,J,Q);return}let G=D7(Z,V);$.replace(G),LJ(G,J,Q)}function LJ(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 NJ(J,Q){return S(XJ,{initial:"browse",children:S(a7,{children:S(cQ,{file:Q,children:S(J,{})})})})}function q3(J,Q){let $=mQ(Q.rootEl);if(!Q.commentsEnabled){$.render(S7(J));return}let V=Q.file??F7();$.render(S7(sQ,{initialCanvas:J,file:V}))}var MJ="__maudeCanvasRuntime";function aQ({Canvas:J,file:Q,onOk:$}){return p(()=>{$()},[]),NJ(J,Q)}class jJ extends pQ{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 oQ({message:J}){return S7("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 sQ({initialCanvas:J,file:Q}){let[{canvas:$,attempt:V},Z]=V7({canvas:J,attempt:0}),[G,B]=V7({on:!1}),K=u(null),Y=u($);Y.current=$,p(()=>{let z={remount:(P)=>Z((X)=>({canvas:P,attempt:X.attempt+1})),setHolding:(P,X)=>B(P?{on:!0,message:X}:{on:!1})};return window[MJ]=z,()=>{window[MJ]=void 0}},[]);let j=C7(()=>{if(K.current=Y.current,B((z)=>z.on?{on:!1}:z),V>0&&Q)try{window.parent.postMessage({dgn:"loaded",file:Q},"*")}catch{}},[V,Q]),N=C7(()=>{B({on:!0,message:"render error"})},[]),U=C7(()=>{let z=K.current;return z?NJ(z,Q):null},[Q]);return _J(tQ,{children:[S(jJ,{attempt:V,onError:N,fallback:U,children:S(aQ,{Canvas:$,file:Q,onOk:j},V)}),G.on?S(oQ,{message:G.message}):null]})}export{iQ as pickSpecimenSelectEl,q3 as mountCanvas,Z7 as isBareSpecimen,jJ as CanvasErrorBoundary};
|
|
59
|
+
`.trim();function fQ(){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=hQ,document.head.appendChild(J)}var pQ=["nw","n","ne","e","se","s","sw","w"];function uQ(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,Y7=1;function mQ(J,Q,$,V,Z,G){let{movesLeft:W,movesRight:K,movesTop:H,movesBottom:j}=uQ(J),N=Z.center,X=Q.w,z=Q.h;if(K)X=Q.w+(N?2*$:$);else if(W)X=Q.w-(N?2*$:$);if(j)z=Q.h+(N?2*V:V);else if(H)z=Q.h-(N?2*V:V);if(Z.aspect&&Q.w>0&&Q.h>0){let U=Q.w/Q.h;if((W||K)&&(H||j)){let A=Math.abs(X-Q.w)/Q.w,q=Math.abs(z-Q.h)/Q.h;if(A>=q)z=X/U;else X=z*U}else if(W||K)z=X/U;else if(H||j)X=z*U}if(X<Y7)X=Y7;if(z<Y7)z=Y7;let Y={width:n(X),height:n(z)};if(N){if(G.canMoveLeft&&(W||K))Y.left=n(Q.left+(Q.w-X)/2);if(G.canMoveTop&&(H||j))Y.top=n(Q.top+(Q.h-z)/2)}else{if(G.canMoveLeft&&W)Y.left=n(Q.left+Q.w-X);if(G.canMoveTop&&H)Y.top=n(Q.top+Q.h-z)}return Y}function _J(J){if(!J||J==="none")return 0;let Q=/matrix\(([^)]+)\)/.exec(J);if(!Q)return 0;let $=Q[1].split(",").map(Number),V=$[0]??1,Z=$[1]??0;return Math.round(Math.atan2(Z,V)*(180/Math.PI)*100)/100}function dQ(J){if(!J||J==="none")return 1;let Q=/matrix\(([^)]+)\)/.exec(J);if(!Q)return 1;let $=Q[1].split(",").map(Number),V=$[0]??1,Z=$[1]??0,G=Math.hypot(V,Z);return G>0?G:1}function cQ(J){let Q=J.closest(".dc-world");if(!Q)return 1;let $=getComputedStyle(Q),V=Number.parseFloat($.zoom||"1")||1;return dQ($.transform)*V}function AJ(J,Q,$){let V=$*Math.PI/180,Z=Math.cos(V),G=Math.sin(V);return[J*Z-Q*G,J*G+Q*Z]}function IJ(J,Q,$,V){return Math.atan2(V-Q,$-J)}function iQ(J,Q,$,V){let Z=J+($-Q)*(180/Math.PI);while(Z>180)Z-=360;while(Z<=-180)Z+=360;if(V)Z=Math.round(Z/15)*15;return Math.round(Z*100)/100}function lQ(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 rQ(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 nQ(J,Q){try{window.parent.postMessage({dgn:"resize-request",id:J.cdId,patch:{transform:Q},before:J.before,idIndex:J.idIndex},"*")}catch{}}function OJ(){fQ();let{selected:J}=z7(),{tool:Q}=X7(),$=F7(null),V=F7(null),Z=F7(null),G=F7(null),W=J.length===1?J[0]:null,K=W&&typeof W.id==="string"?W.id:null,H=W&&!K&&typeof W.artboardId==="string"?W.artboardId:null,j=Q==="move"&&(!!K||!!H);NJ(()=>{let X=$.current;if(!X)return;let z=()=>{for(let U of Array.from(X.children)){let D=U;D.style.opacity="0",D.style.pointerEvents="none"}};if(!j||!W){z();return}let Y=()=>{if(V.current=null,FJ()){z(),V.current=requestAnimationFrame(Y);return}let U=D7(document,W);if(!U){z(),V.current=requestAnimationFrame(Y);return}let D=U.getBoundingClientRect();if(D.width<=0&&D.height<=0){z(),V.current=requestAnimationFrame(Y);return}let A=H?["e","s","se"]:pQ,q=H?[]:["rot-nw","rot-ne","rot-sw","rot-se"],F=A.length+q.length+1;while(X.children.length<F)X.appendChild(document.createElement("div"));while(X.children.length>F)X.lastChild&&X.removeChild(X.lastChild);let _=D.left+D.width/2,P=D.top+D.height/2,B=_J(getComputedStyle(U).transform),L=cQ(U),O=U.offsetWidth*L/2,M=U.offsetHeight*L/2,I={nw:[-O,-M],n:[0,-M],ne:[O,-M],e:[O,0],se:[O,M],s:[0,M],sw:[-O,M],w:[-O,0],"rot-nw":[-O,-M],"rot-ne":[O,-M],"rot-sw":[-O,M],"rot-se":[O,M]},E=[...q,...A];for(let f=0;f<E.length;f++){let y=E[f],C=X.children[f],[d,i]=I[y]??[0,0],[bJ,xJ]=AJ(d,i,B),yJ=_+bJ,CJ=P+xJ,P7=y.startsWith("rot-"),p7=y==="n"||y==="s",u7=y==="e"||y==="w",vJ=P7?10:p7?7:u7?3:4,SJ=P7?10:p7?3:u7?7:4;C.className="dc-el-resize-handle",C.dataset.corner=y,C.style.opacity="1",C.style.pointerEvents="auto",C.style.left=`${Math.round(yJ-vJ)}px`,C.style.top=`${Math.round(CJ-SJ)}px`,C.style.transform=P7?"":`rotate(${B}deg)`}let k=X.children[E.length],w=Z.current;if(w&&w.el===U&&!w.corner.startsWith("rot-")){let f=w.lastResult?.width??U.offsetWidth,y=w.lastResult?.height??U.offsetHeight,C=`${Math.round(f)} × ${Math.round(y)}`,d=w.lastResult?.left,i=w.lastResult?.top;if(typeof d==="number"||typeof i==="number")C+=` · ${Math.round(d??w.start.left)}, ${Math.round(i??w.start.top)}`;k.className="dc-el-resize-readout",k.textContent=C,k.style.opacity="1",k.style.left=`${Math.round(_)}px`,k.style.top=`${Math.round(P+M)}px`}else k.style.opacity="0";V.current=requestAnimationFrame(Y)};return V.current=requestAnimationFrame(Y),()=>{if(V.current!=null)cancelAnimationFrame(V.current)}},[j,W,H]);let N=gQ((X,z)=>{if(X.el.style.width=`${z.width}px`,X.el.style.height=`${z.height}px`,typeof z.left==="number")X.el.style.left=`${z.left}px`;if(typeof z.top==="number")X.el.style.top=`${z.top}px`;X.lastResult=z},[]);return NJ(()=>{let X=$.current;if(!X)return;let z=(q,F)=>{let[_,P]=AJ(F.clientX-q.startClientX,F.clientY-q.startClientY,-q.angle);return mQ(q.corner,q.start,_/q.elZoom,P/q.elZoom,{aspect:!!F.shiftKey,center:!q.artboardId&&!!F.altKey},q.flags)},Y=(q)=>{let F=q.target;if(!F?.classList.contains("dc-el-resize-handle"))return;let _=F.dataset.corner;if(!_||!W)return;let P=typeof W.id==="string"?W.id:null,B=!P&&typeof W.artboardId==="string"?W.artboardId:null;if(!P&&!B)return;let L=D7(document,W);if(!L)return;q.preventDefault(),q.stopPropagation();let O=L.getBoundingClientRect(),M=L.offsetWidth?O.width/L.offsetWidth:1,I=getComputedStyle(L),E=!B&&(I.position==="absolute"||I.position==="fixed"),k=B?Number.NaN:Number.parseFloat(L.style.left),w=B?Number.NaN:Number.parseFloat(L.style.top),f=B?0:_J(I.transform),y=M>0?M:1,C=O.left+O.width/2,d=O.top+O.height/2,i={pointerId:q.pointerId,corner:_,el:L,cdId:P??"",artboardId:B,idIndex:P?s7(document,P,L):0,startClientX:q.clientX,startClientY:q.clientY,elZoom:y,angle:f,cx:C,cy:d,rotStartPointer:IJ(C,d,q.clientX,q.clientY),start:{w:(f?L.offsetWidth:O.width/y)||O.width/y,h:(f?L.offsetHeight:O.height/y)||O.height/y,left:k,top:w},flags:{canMoveLeft:E&&Number.isFinite(k),canMoveTop:E&&Number.isFinite(w)},before:{width:L.style.width||null,height:L.style.height||null,left:L.style.left||null,top:L.style.top||null,transform:L.style.transform||null},lastResult:null,lastTransform:null};Z.current=i;try{F.setPointerCapture(q.pointerId)}catch{}},U=(q)=>{let F=Z.current;if(!F||q.pointerId!==F.pointerId)return;if(q.preventDefault(),F.corner.startsWith("rot-")){let P=`rotate(${iQ(F.angle,F.rotStartPointer,IJ(F.cx,F.cy,q.clientX,q.clientY),!!q.shiftKey)}deg)`;F.el.style.transform=P,F.lastTransform=P;return}N(F,z(F,q))},D=(q)=>{let F=Z.current;if(!F||q.pointerId!==F.pointerId)return;if(Z.current=null,F.corner.startsWith("rot-")){let B=F.lastTransform;if(!B||B===F.before.transform)return;G.current={el:F.el,before:F.before},nQ(F,B);return}let _=F.lastResult??z(F,q);if(!(`${_.width}px`!==F.before.width||`${_.height}px`!==F.before.height||typeof _.left==="number"&&`${_.left}px`!==F.before.left||typeof _.top==="number"&&`${_.top}px`!==F.before.top))return;if(G.current={el:F.el,before:F.before},F.artboardId)rQ(F,_);else lQ(F,_)},A=(q)=>{let F=q.data;if(F?.dgn!=="resize-failed"&&F?.dgn!=="resize-artboard-failed")return;if(q.source!==window.parent)return;let _=G.current;if(!_)return;if(_.el.style.width=_.before.width??"",_.el.style.height=_.before.height??"",_.before.left!==null||_.el.style.left)_.el.style.left=_.before.left??"";if(_.before.top!==null||_.el.style.top)_.el.style.top=_.before.top??"";if(_.before.transform!==null||_.el.style.transform)_.el.style.transform=_.before.transform??"";G.current=null};return X.addEventListener("pointerdown",Y),window.addEventListener("pointermove",U),window.addEventListener("pointerup",D),window.addEventListener("pointercancel",D),window.addEventListener("message",A),()=>{X.removeEventListener("pointerdown",Y),window.removeEventListener("pointermove",U),window.removeEventListener("pointerup",D),window.removeEventListener("pointercancel",D),window.removeEventListener("message",A)}},[W,N]),oQ("div",{ref:$,"aria-hidden":"true"})}import{jsx as S,jsxs as wJ,Fragment as W0}from"react/jsx-runtime";var eQ=new Set(["drop-comment","tool","escape","hover"]);function q7(){return typeof document<"u"&&!document.querySelector(".dc-canvas")}function f7(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 V=$.tagName;if(V==="HTML"||V==="BODY")return null;return $}function J0(J,Q){let $=f7(J,Q);if(!$)return null;return $.closest("[data-cd-id]")??$}function Q0({children:J,file:Q}){let{tool:$,setTool:V}=X7(),Z=z7(),G=u(null),[W,K]=Z7(null),H=u($);H.current=$;let j=sQ(()=>()=>H.current,[]);p(()=>{if($!=="comment")K(null)},[$]);let[N,X]=Z7(null),[z,Y]=Z7(!1);return p(()=>{let U=()=>Y(q7());U();let D=requestAnimationFrame(U),A=setTimeout(U,120);return()=>{cancelAnimationFrame(D),clearTimeout(A)}},[]),p(()=>{if(typeof document>"u")return;let U=(D)=>{if(D.button!==0||!(D.metaKey||D.ctrlKey))return;if(!q7())return;if(Q7(D.target))return;let A=J0(D.clientX,D.clientY);if(!A)return;D.preventDefault(),D.stopImmediatePropagation();let q=A.getAttribute("data-cd-id"),F=M7({el:A,cdId:q,artboardId:null});if(D.shiftKey)Z.add(F);else Z.replace(F);X(A)};return document.addEventListener("pointerdown",U,!0),()=>document.removeEventListener("pointerdown",U,!0)},[Z]),p(()=>{if(Z.selected.length===0)X(null)},[Z.selected]),p(()=>{let U=G.current;if(U)U.setAttribute("data-active-tool",$);if(typeof document<"u"&&document.body)document.body.setAttribute("data-active-tool",$);return()=>{U?.removeAttribute("data-active-tool")}},[$]),p(()=>{if(typeof window>"u")return;let U=(D)=>{let A=D.data;if(!A||typeof A!=="object"||A.dgn!=="tool-set")return;if(typeof A.tool==="string")V(A.tool)};return window.addEventListener("message",U),()=>window.removeEventListener("message",U)},[V]),XJ({hostRef:G,getActiveTool:j,claimableActions:eQ,callbacks:{onHover:({clientX:U,clientY:D})=>{if(H.current!=="comment"||!q7()){K(null);return}let A=f7(U,D);K((q)=>q===A?q:A)},onTool:({tool:U})=>V(U),onEscape:()=>{if(H.current!=="move")V("move");if(K(null),Z.clear(),typeof window<"u")try{window.parent.postMessage({dgn:"force-clear"},"*")}catch{}},onDropComment:({clientX:U,clientY:D})=>Z0(U,D,Z,Q)}}),wJ("div",{"data-mc-host":!0,ref:G,style:{display:"contents"},children:[J,W?S(V0,{el:W}):null,N?S($0,{el:N}):null,z?S(OJ,{}):null,S(zJ,{})]})}function $0({el:J}){let Q=u(null),$=u(J);$.current=J;let V=u(null);return p(()=>{let Z=()=>{V.current=null;let G=Q.current,W=$.current;if(G&&W?.isConnected){let K=W.getBoundingClientRect();if(K.width===0&&K.height===0)G.style.display="none";else G.style.display="block",G.style.left=`${Math.round(K.left)}px`,G.style.top=`${Math.round(K.top)}px`,G.style.width=`${Math.round(K.width)}px`,G.style.height=`${Math.round(K.height)}px`}else if(G)G.style.display="none";V.current=requestAnimationFrame(Z)};return V.current=requestAnimationFrame(Z),()=>{if(V.current!=null)cancelAnimationFrame(V.current)}},[]),S("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 V0({el:J}){let Q=u(null),$=u(J);$.current=J;let V=u(null);return p(()=>{let Z=()=>{V.current=null;let G=Q.current,W=$.current;if(G&&W?.isConnected){let K=W.getBoundingClientRect();if(K.width===0&&K.height===0)G.style.display="none";else G.style.display="block",G.style.left=`${Math.round(K.left)}px`,G.style.top=`${Math.round(K.top)}px`,G.style.width=`${Math.round(K.width)}px`,G.style.height=`${Math.round(K.height)}px`}else if(G)G.style.display="none";V.current=requestAnimationFrame(Z)};return V.current=requestAnimationFrame(Z),()=>{if(V.current!=null)cancelAnimationFrame(V.current)}},[]),S("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 Z0(J,Q,$,V){if(typeof document>"u")return;let Z=c7(J,Q)??void 0,G=l7(J,Q);if(G){let H=G7(G),j=H?.getBoundingClientRect(),N={file:V,id:void 0,selector:"",artboardId:null,tag:H?.getAttribute("data-tool")??"annotation",classes:"",text:"",dom_path:[],bounds:j?{x:j.left,y:j.top,w:j.width,h:j.height}:{x:J-12,y:Q-12,w:24,h:24},html:"",annotationId:G,...Z?{world:Z}:{}};g7(N,J,Q);return}let W=E7(document,J,Q,{deep:!0});if(!W)W=E7(document,J,Q,{deep:!1});if(!W&&!q7()&&typeof document.elementsFromPoint==="function"){let H=document.elementsFromPoint(J,Q);for(let j of H){let N=j.closest?.("[data-cd-id]");if(!N)continue;if(!N.closest(".dc-artboard-body"))continue;let X=N.closest("[data-dc-screen]");W={el:N,cdId:N.getAttribute("data-cd-id"),artboardId:X?.getAttribute("data-dc-screen")??null};break}}if(!W&&q7()){let H=f7(J,Q);if(H)W={el:H,cdId:H.getAttribute("data-cd-id"),artboardId:null}}if(!W){let H={file:V,id:void 0,selector:"",artboardId:null,tag:"",classes:"",text:"",dom_path:[],bounds:{x:J-12,y:Q-12,w:24,h:24},html:"",...Z?{world:Z}:{}};g7(H,J,Q);return}let K=M7(W,V);$.replace(K),g7(K,J,Q)}function g7(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 EJ(J,Q){return S(jJ,{initial:"browse",children:S(VJ,{children:S(Q0,{file:Q,children:S(J,{})})})})}function D3(J,Q){let $=tQ(Q.rootEl);if(!Q.commentsEnabled){$.render(h7(J));return}let V=Q.file??L7();$.render(h7(B0,{initialCanvas:J,file:V}))}var kJ="__maudeCanvasRuntime";function q0({Canvas:J,file:Q,onOk:$}){return p(()=>{$()},[]),EJ(J,Q)}class TJ extends aQ{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 G0({message:J}){return h7("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 B0({initialCanvas:J,file:Q}){let[{canvas:$,attempt:V},Z]=Z7({canvas:J,attempt:0}),[G,W]=Z7({on:!1}),K=u(null),H=u($);H.current=$,p(()=>{let z={remount:(Y)=>Z((U)=>({canvas:Y,attempt:U.attempt+1})),setHolding:(Y,U)=>W(Y?{on:!0,message:U}:{on:!1})};return window[kJ]=z,()=>{window[kJ]=void 0}},[]);let j=R7(()=>{if(K.current=H.current,W((z)=>z.on?{on:!1}:z),V>0&&Q)try{window.parent.postMessage({dgn:"loaded",file:Q},"*")}catch{}},[V,Q]),N=R7(()=>{W({on:!0,message:"render error"})},[]),X=R7(()=>{let z=K.current;return z?EJ(z,Q):null},[Q]);return wJ(W0,{children:[S(TJ,{attempt:V,onError:N,fallback:X,children:S(q0,{Canvas:$,file:Q,onOk:j},V)}),G.on?S(G0,{message:G.message}):null]})}export{J0 as pickSpecimenSelectEl,D3 as mountCanvas,q7 as isBareSpecimen,TJ as CanvasErrorBoundary};
|
|
@@ -18,16 +18,31 @@
|
|
|
18
18
|
// A canvas the project does not know yet is proposed as `doc.create` with all
|
|
19
19
|
// of its lanes, so it arrives on every peer as ONE action.
|
|
20
20
|
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
21
|
+
// Annotations are never re-proposed from disk here: every change the studio
|
|
22
|
+
// made to them went through the durable outbox (drained before any cold start),
|
|
23
|
+
// so a difference on disk is an older accepted state the room had not
|
|
24
|
+
// re-projected — the accepted value wins, and the local file is kept in a
|
|
25
25
|
// recovery slot in case a raw edit made while the studio was down lived there.
|
|
26
|
+
//
|
|
27
|
+
// Comments had the same rule, and the premise did not hold for them (issue
|
|
28
|
+
// #133, reproduced end-to-end): a comment added while the sync runtime was not
|
|
29
|
+
// up yet (`proposeLane` unavailable, server.ts) went to the local room and disk
|
|
30
|
+
// only, never into the outbox — so the web never saw it, and the file then
|
|
31
|
+
// froze behind it. Comments carry stable ids, so the difference is decidable:
|
|
32
|
+
// an id on disk that the accepted state lacks and that the comment ledger says
|
|
33
|
+
// was never synced from here is a local comment still owed to the project; it
|
|
34
|
+
// is proposed, as the accepted list plus those comments (a three-way id merge
|
|
35
|
+
// on the hub). Ids the ledger knows were synced are deletions made while this
|
|
36
|
+
// machine was away and are not proposed back. With no ledger record for the
|
|
37
|
+
// canvas (first launch after upgrading) nothing is decidable: the old rule —
|
|
38
|
+
// accepted wins, local kept in recovery — stands.
|
|
26
39
|
|
|
27
40
|
import { existsSync, readFileSync } from 'node:fs';
|
|
28
41
|
import type * as Y from 'yjs';
|
|
29
42
|
|
|
30
43
|
import { cssFromDoc, htmlFromDoc, laneValueFromFile, readLaneFromDoc } from './codec.ts';
|
|
44
|
+
import { commentKey } from './comment-identity.ts';
|
|
45
|
+
import type { CommentLedger } from './comment-ledger.ts';
|
|
31
46
|
import { hashBytes } from './echo-guard.ts';
|
|
32
47
|
import type { SyncJournal } from './journal.ts';
|
|
33
48
|
import type { DocProjection, ProjectionPaths, ProposalLane } from './projection.ts';
|
|
@@ -53,6 +68,38 @@ function readText(p: string | undefined): string | null {
|
|
|
53
68
|
}
|
|
54
69
|
}
|
|
55
70
|
|
|
71
|
+
function parseList(v: string): unknown[] {
|
|
72
|
+
if (!v) return [];
|
|
73
|
+
try {
|
|
74
|
+
const parsed = JSON.parse(v) as unknown;
|
|
75
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
76
|
+
} catch {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The comments list to propose at cold start — the accepted list plus the local
|
|
83
|
+
* comments never synced from here — or null when there is nothing owed (or no
|
|
84
|
+
* ledger record to decide by). See the header.
|
|
85
|
+
*/
|
|
86
|
+
export function commentsOwedToProject(
|
|
87
|
+
local: string,
|
|
88
|
+
accepted: string,
|
|
89
|
+
slug: string,
|
|
90
|
+
ledger: CommentLedger | undefined
|
|
91
|
+
): string | null {
|
|
92
|
+
if (!ledger?.known(slug)) return null;
|
|
93
|
+
const acceptedList = parseList(accepted);
|
|
94
|
+
const inProject = new Set(acceptedList.map(commentKey));
|
|
95
|
+
const synced = ledger.get(slug);
|
|
96
|
+
const owed = parseList(local).filter((c) => {
|
|
97
|
+
const k = commentKey(c);
|
|
98
|
+
return !inProject.has(k) && !synced.has(k);
|
|
99
|
+
});
|
|
100
|
+
return owed.length > 0 ? JSON.stringify([...acceptedList, ...owed]) : null;
|
|
101
|
+
}
|
|
102
|
+
|
|
56
103
|
/**
|
|
57
104
|
* Pure decision for the source lanes. `knownBase` is the last value disk and
|
|
58
105
|
* the accepted replica agreed on (recovery slot), `baseHash` the journal's
|
|
@@ -92,6 +139,8 @@ export interface AcceptedColdStartInput {
|
|
|
92
139
|
projection: DocProjection;
|
|
93
140
|
historyDir?: string;
|
|
94
141
|
journal?: SyncJournal;
|
|
142
|
+
/** Issue #133 — comment ids synced from here before (see the header). */
|
|
143
|
+
commentLedger?: CommentLedger;
|
|
95
144
|
/**
|
|
96
145
|
* This disk's own html proposal a previous run left unanswered, which the
|
|
97
146
|
* outbox drain has just had accepted. The disk was saved on top of it, so it
|
|
@@ -225,6 +274,13 @@ export async function acceptedColdStart(
|
|
|
225
274
|
verdicts.push({ lane, decision: local === null ? 'materialize' : 'agreed' });
|
|
226
275
|
continue;
|
|
227
276
|
}
|
|
277
|
+
if (lane === 'comments') {
|
|
278
|
+
const owed = commentsOwedToProject(local, accepted, i.slug, i.commentLedger);
|
|
279
|
+
if (owed) {
|
|
280
|
+
verdicts.push({ lane, decision: 'propose', base: accepted, local: owed });
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
228
284
|
if (i.historyDir && text) {
|
|
229
285
|
try {
|
|
230
286
|
saveRecoveryBody(i.historyDir, p, 'local', text);
|
|
@@ -67,7 +67,8 @@ import {
|
|
|
67
67
|
unionCommentsById,
|
|
68
68
|
} from './cold-start.ts';
|
|
69
69
|
import { applyColdStart, type ColdStartSnapshotReason } from './cold-start-apply.ts';
|
|
70
|
-
import { dedupeCommentsById, hasDuplicateComments } from './comment-identity.ts';
|
|
70
|
+
import { commentKey, dedupeCommentsById, hasDuplicateComments } from './comment-identity.ts';
|
|
71
|
+
import { type CommentLedger, withoutRemotelyDeleted } from './comment-ledger.ts';
|
|
71
72
|
import { type EchoGuard, hashBytes } from './echo-guard.ts';
|
|
72
73
|
import type { SyncJournal } from './journal.ts';
|
|
73
74
|
import { rememberSeed, repairSeedDuplication } from './seed-repair.ts';
|
|
@@ -119,6 +120,20 @@ export interface CanvasSyncAgentOptions {
|
|
|
119
120
|
* without it simply degrade to the conservative conflict path.
|
|
120
121
|
*/
|
|
121
122
|
journal?: SyncJournal;
|
|
123
|
+
/**
|
|
124
|
+
* Issue #133 — comment ids synced from this machine before
|
|
125
|
+
* (sync/comment-ledger.ts). The cold-start union drops a local comment the
|
|
126
|
+
* ledger knows and the hub's doc no longer holds: that is a delete made
|
|
127
|
+
* while this machine was away, not a local-only comment. Optional — absent,
|
|
128
|
+
* the union keeps everything, as before.
|
|
129
|
+
*/
|
|
130
|
+
commentLedger?: CommentLedger;
|
|
131
|
+
/**
|
|
132
|
+
* Does the hub hold this doc's current state (nothing unacknowledged)? The
|
|
133
|
+
* ledger records comment ids as synced only then — see
|
|
134
|
+
* `commentsConfirmedOnHub` in sync/index.ts. Absent → never records.
|
|
135
|
+
*/
|
|
136
|
+
commentsConfirmed?: () => boolean;
|
|
122
137
|
/**
|
|
123
138
|
* Snapshot writer (DDR-102 conflict protocol) — persists a body version to
|
|
124
139
|
* `_history/<slug>/` and resolves with the snapshot's ISO ts (null on
|
|
@@ -339,6 +354,7 @@ export function createCanvasSyncAgent(opts: CanvasSyncAgentOptions): CanvasSyncA
|
|
|
339
354
|
echoGuard.record(paths.comments, hash);
|
|
340
355
|
writer(paths.comments, serialized);
|
|
341
356
|
lastComments = serialized;
|
|
357
|
+
if (opts.commentsConfirmed?.()) opts.commentLedger?.record(slug, next.map(commentKey));
|
|
342
358
|
}
|
|
343
359
|
|
|
344
360
|
function writeAnnotationsIfChanged(): void {
|
|
@@ -411,6 +427,8 @@ export function createCanvasSyncAgent(opts: CanvasSyncAgentOptions): CanvasSyncA
|
|
|
411
427
|
if (parsed === null) return false;
|
|
412
428
|
const changed = applyCommentsToDoc(doc, parsed, origin);
|
|
413
429
|
if (changed) lastComments = str;
|
|
430
|
+
if (opts.commentsConfirmed?.())
|
|
431
|
+
opts.commentLedger?.record(slug, commentsFromDoc(doc).map(commentKey));
|
|
414
432
|
return changed;
|
|
415
433
|
}
|
|
416
434
|
if (evt.path === paths.annotations) {
|
|
@@ -562,7 +580,13 @@ export function createCanvasSyncAgent(opts: CanvasSyncAgentOptions): CanvasSyncA
|
|
|
562
580
|
const bodyWinner = applied.bodyWinner;
|
|
563
581
|
|
|
564
582
|
// ---- comments: id-union merge (DDR-102 — union loses nothing) ----------
|
|
565
|
-
const
|
|
583
|
+
const localParsed = localComments !== null ? tryParseJsonArray(localComments) : null;
|
|
584
|
+
// Issue #133 — a local comment that was synced from here before and that
|
|
585
|
+
// the hub's doc no longer holds was deleted while this machine was away.
|
|
586
|
+
// Unioning it back resurrected it for everyone.
|
|
587
|
+
const localParsedComments = localParsed
|
|
588
|
+
? withoutRemotelyDeleted(localParsed, docComments, opts.commentLedger?.get(slug))
|
|
589
|
+
: null;
|
|
566
590
|
if (localParsedComments !== null && localParsedComments.length > 0) {
|
|
567
591
|
const merged = unionCommentsById(docComments, localParsedComments);
|
|
568
592
|
const mergedStr = merged.length > 0 ? `${JSON.stringify(merged, null, 2)}\n` : '';
|
|
@@ -573,6 +597,7 @@ export function createCanvasSyncAgent(opts: CanvasSyncAgentOptions): CanvasSyncA
|
|
|
573
597
|
writer(paths.comments, mergedStr);
|
|
574
598
|
}
|
|
575
599
|
lastComments = mergedStr;
|
|
600
|
+
if (opts.commentsConfirmed?.()) opts.commentLedger?.record(slug, merged.map(commentKey));
|
|
576
601
|
} else {
|
|
577
602
|
// No (parseable) local comments — hub state materializes as before.
|
|
578
603
|
lastComments = docCommentsStr;
|
|
@@ -581,6 +606,7 @@ export function createCanvasSyncAgent(opts: CanvasSyncAgentOptions): CanvasSyncA
|
|
|
581
606
|
echoGuard.record(paths.comments, hash);
|
|
582
607
|
writer(paths.comments, docCommentsStr);
|
|
583
608
|
}
|
|
609
|
+
if (opts.commentsConfirmed?.()) opts.commentLedger?.record(slug, docComments.map(commentKey));
|
|
584
610
|
}
|
|
585
611
|
|
|
586
612
|
// ---- annotations: PER-LANE newest-wins (the 2026-08-14 eraser fix) -----
|