vzcode 1.55.0 → 1.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -375,7 +375,7 @@ https://fb.me/react-async-component-lifecycle-hooks`)}if(typeof t.getDerivedStat
375
375
  `+n),r.b(" </div>"),r.b(`
376
376
  `+n),r.b(" </div>"),r.b(`
377
377
  `+n),r.b(" </div>"),r.b(`
378
- `+n),r.b("</div>"),r.fl()},partials:{},subs:{}});mi["tag-file-added"]=new ii.Template({code:function(t,e,n){var r=this;return r.b(n=n||""),r.b('<span class="d2h-tag d2h-added d2h-added-tag">ADDED</span>'),r.fl()},partials:{},subs:{}});mi["tag-file-changed"]=new ii.Template({code:function(t,e,n){var r=this;return r.b(n=n||""),r.b('<span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span>'),r.fl()},partials:{},subs:{}});mi["tag-file-deleted"]=new ii.Template({code:function(t,e,n){var r=this;return r.b(n=n||""),r.b('<span class="d2h-tag d2h-deleted d2h-deleted-tag">DELETED</span>'),r.fl()},partials:{},subs:{}});mi["tag-file-renamed"]=new ii.Template({code:function(t,e,n){var r=this;return r.b(n=n||""),r.b('<span class="d2h-tag d2h-moved d2h-moved-tag">RENAMED</span>'),r.fl()},partials:{},subs:{}});class v_e{constructor({compiledTemplates:e={},rawTemplates:n={}}){const r=Object.entries(n).reduce((i,[o,s])=>{const a=ii.compile(s,{asString:!1});return Object.assign(Object.assign({},i),{[o]:a})},{});this.preCompiledTemplates=Object.assign(Object.assign(Object.assign({},mi),e),r)}static compile(e){return ii.compile(e,{asString:!1})}render(e,n,r,i,o){const s=this.templateKey(e,n);try{return this.preCompiledTemplates[s].render(r,i,o)}catch{throw new Error(`Could not find template to render '${s}'`)}}template(e,n){return this.preCompiledTemplates[this.templateKey(e,n)]}templateKey(e,n){return`${e}-${n}`}}const y_e=Object.assign(Object.assign(Object.assign({},nW),rW),{outputFormat:Lxe.LINE_BY_LINE,drawFileList:!0});function O_e(t,e={}){const n=Object.assign(Object.assign({},y_e),e),r=typeof t=="string"?zxe(t,n):t,i=new v_e(n),{colorScheme:o}=n,s={colorScheme:o},a=n.drawFileList?new s_e(i,s).render(r):"",l=n.outputFormat==="side-by-side"?new h_e(i,n).render(r):new u_e(i,n).render(r);return a+l}const b_e=({diffData:t})=>{const e=Object.values(t).filter(s=>s.length>0);if(e.length===0)return null;let n=0,r=0;for(const s of e){const a=Dxe(s);n+=a.additions,r+=a.deletions}const i=$xe(t),o=O_e(i,{drawFileList:!1,matching:"words",diffStyle:"word",outputFormat:"line-by-line"});return H.jsxs("div",{className:"diff-view",children:[H.jsx("div",{className:"diff-summary",children:H.jsxs("div",{className:"diff-stats",children:[H.jsxs("span",{className:"files-changed",children:[e.length," file",e.length!==1?"s":""," changed"]}),n>0&&H.jsxs("span",{className:"additions",children:["+",n]}),r>0&&H.jsxs("span",{className:"deletions",children:["-",r]})]})}),H.jsx("div",{className:"diff-files",dangerouslySetInnerHTML:{__html:o}})]})},w_e=({id:t,role:e,content:n,timestamp:r,isStreaming:i,diffData:o,beforeFiles:s,chatId:a,canUndo:l})=>{const[u,c]=N.useState(!1),{aiChatUndoEndpoint:f,aiChatOptions:d={}}=N.useContext(Ur),h=N.useMemo(()=>nhe(r).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}),[r]),p=N.useMemo(()=>`ai-chat-message ${e}${i?" streaming":""}`,[e,i]),g=async()=>{if(!(!t||!a||!s||u||!f)){c(!0);try{const y=await fetch(f,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({vizId:d.vizId,chatId:a,messageId:t})});if(!y.ok)throw new Error(`HTTP error! status: ${y.status}`)}catch(y){console.error("Error undoing AI edit:",y)}finally{c(!1)}}};return H.jsxs("div",{className:p,children:[H.jsxs("div",{className:"ai-chat-message-content",children:[H.jsx(Cz,{remarkPlugins:[Gz],children:n}),o&&Object.keys(o).length>0&&H.jsx(b_e,{diffData:o}),l&&s&&H.jsx("div",{className:"undo-button-container",children:H.jsx("button",{className:"undo-button",onClick:g,disabled:u,title:"Undo this AI edit",children:u?"Undoing...":"Undo"})})]}),H.jsx("div",{className:"ai-chat-message-time",children:h})]})},S_e=N.memo(w_e),k_e=()=>H.jsx("div",{className:"ai-chat-message assistant",children:H.jsx("div",{className:"ai-chat-message-content",children:H.jsxs("div",{className:"ai-chat-typing",children:[H.jsx("span",{}),H.jsx("span",{}),H.jsx("span",{})]})})}),x_e=N.memo(k_e),__e=({content:t,isVisible:e})=>!e||!t?null:H.jsxs("div",{className:"thinking-scratchpad",children:[H.jsxs("div",{className:"thinking-scratchpad-header",children:[H.jsx("span",{className:"thinking-scratchpad-icon",children:"🧠"}),H.jsx("span",{className:"thinking-scratchpad-title",children:"AI is thinking..."})]}),H.jsx("div",{className:"thinking-scratchpad-content",children:H.jsx(Cz,{remarkPlugins:[Gz],children:t})})]}),P_e=N.memo(__e),C_e=({messages:t,aiStatus:e,isLoading:n,chatId:r,aiScratchpad:i})=>{const o=N.useRef(null),s=N.useRef(null),[a,l]=N.useState(!1),[u,c]=N.useState(!0),f=N.useRef(),d=N.useCallback(()=>{const S=s.current;if(!S)return!0;const k=50,{scrollTop:x,scrollHeight:_,clientHeight:I}=S;return _-x-I<k},[]),h=N.useCallback(()=>{u&&o.current?.scrollIntoView({behavior:"smooth",block:"end"})},[u]),p=N.useCallback(()=>{if(!s.current)return;const k=d();f.current&&clearTimeout(f.current),!k&&!a&&(l(!0),c(!1)),k&&a&&(f.current=setTimeout(()=>{l(!1),c(!0)},500))},[a,d]);N.useEffect(()=>(u&&!a&&(f.current&&clearTimeout(f.current),f.current=setTimeout(()=>{h()},100)),()=>{f.current&&clearTimeout(f.current)}),[t,u,a,h]),N.useEffect(()=>()=>{f.current&&clearTimeout(f.current)},[]);const g=t[t.length-1],y=g?.role==="assistant"&&g.content!=="",O=n&&!y,b=!!(i&&i.trim());return H.jsxs("div",{className:"ai-chat-messages",ref:s,onScroll:p,children:[t.map((S,k)=>{const _=S.role==="assistant"&&k===t.length-1&&!n&&S.diffData&&S.beforeFiles&&Object.keys(S.diffData||{}).length>0;return H.jsx(S_e,{id:S.id,role:S.role,content:S.content,timestamp:S.timestamp,diffData:S.diffData,beforeFiles:S.beforeFiles,chatId:r,canUndo:_},S.id)}),b&&H.jsx(P_e,{content:i||"",isVisible:b}),O&&H.jsx(x_e,{}),H.jsx("div",{ref:o})]})},E_e=N.memo(C_e),T_e=({aiChatMessage:t,setAIChatMessage:e,onSendMessage:n,isLoading:r,focused:i,aiChatMode:o,setAIChatMode:s})=>{const a=N.useRef(null);N.useEffect(()=>{i&&a.current&&a.current.focus()},[i]);const l=N.useCallback(c=>{c.key==="Enter"&&!c.shiftKey&&(c.preventDefault(),n())},[n]),u=N.useCallback(c=>{e(c.target.value)},[e]);return H.jsxs("div",{className:"ai-chat-input-container",children:[C1e,H.jsxs(Dr.Group,{className:"ai-chat-input-group",children:[H.jsx(Dr.Control,{as:"textarea",rows:2,value:t,onChange:u,onKeyDown:l,ref:a,placeholder:o==="edit"?"Ask me to make code changes...":"Ask me anything about your code...",spellCheck:"false",disabled:r,"aria-label":"Chat message input"}),t&&H.jsxs("div",{className:"ai-chat-input-info",children:[H.jsx("span",{className:"ai-chat-hint",children:"Shift+Enter for new line"}),H.jsx("span",{className:"ai-chat-hint",children:"Press Enter to send"})]}),H.jsx(Uu,{variant:"primary",onClick:n,disabled:!t.trim()||r,className:"ai-chat-send-button","aria-label":"Send message",title:"Send message (Enter)",children:"Send"})]})]})},R_e=N.memo(T_e),A_e="/api/ai-chat/",YQ=!1,M_e=()=>{const{aiChatMessage:t,setAIChatMessage:e}=N.useContext(Ur),[n,r]=N.useState(!1),[i]=N.useState(()=>aB()),[o,s]=N.useState(null),{aiChatFocused:a,content:l,aiChatEndpoint:u=A_e,aiChatOptions:c={},aiChatMode:f,setAIChatMode:d,autoForkAndRetryAI:h,clearStoredAIPrompt:p,getStoredAIPrompt:g}=N.useContext(Ur),y=l?.chats?.[i],O=y?.messages||[],b=y?.aiStatus,S=y?.aiScratchpad,k=N.useMemo(()=>O.map((I,M)=>({...I,id:I.id||`msg-${M}`})),[O]),x=O.length===0,_=N.useCallback(async I=>{const M=I||t;if(!M||typeof M!="string"||!M.trim()||n)return;const C=t.trim();e(""),r(!0),s(null);try{const P=await fetch(u,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({...c,vizId:c.vizId,content:M.trim(),chatId:i,mode:f})});if(!P.ok)throw new Error(`HTTP error! status: ${P.status}`);const A=await P.json();if(A.outcome==="failure"&&A.error){const T=A.error.message;if(T==="You do not have permission to use AI chat on this visualization. Only users with edit access can use this feature. Fork the viz to edit it.")try{await h?.(C,f);return}catch(L){console.error("Auto-fork failed:",L),s("Failed to fork visualization. Please try forking manually.");return}s(T);return}}catch(P){console.error("Error getting AI response:",P),s("Failed to send message. Please try again.")}finally{r(!1)}},[t,n,u,c,i,f,h]);return N.useEffect(()=>{if(g){const I=g();I&&(e(I.prompt),d(I.modelName==="ask"?"ask":"edit"),p(),setTimeout(()=>{_(I.prompt)},100))}},[g,p,e,d,_]),H.jsx("div",{className:"ai-chat-container",children:H.jsxs("div",{style:{padding:"10px",flex:1,display:"flex",flexDirection:"column"},children:[x?H.jsxs("div",{className:"ai-chat-empty",children:[H.jsx("div",{className:"ai-chat-empty-icon",children:"✨"}),H.jsx("h3",{className:"ai-chat-empty-title",children:"Edit with AI"}),H.jsx("div",{className:"ai-chat-empty-text",children:"How can I help you?"}),YQ,YQ]}):H.jsx(E_e,{messages:k,aiStatus:b,isLoading:n,chatId:i,aiScratchpad:S}),o&&H.jsx("div",{className:"ai-chat-error",children:H.jsxs("div",{className:"ai-chat-error-content",children:[H.jsx("span",{className:"ai-chat-error-icon",children:"⚠️"}),H.jsx("span",{className:"ai-chat-error-message",children:o}),H.jsx("button",{className:"ai-chat-error-dismiss",onClick:()=>s(null),"aria-label":"Dismiss error",children:"×"})]})}),H.jsx(R_e,{aiChatMessage:t,setAIChatMessage:e,onSendMessage:_,isLoading:n,focused:a,aiChatMode:f,setAIChatMode:d})]})})};function I_e(t){const e=t.split(".");switch(e[e.length-1]){case"jsx":case"tsx":return H.jsx(sOe,{});case"js":return H.jsx(iOe,{});case"ts":return H.jsx(oOe,{});case"json":return H.jsx(cOe,{});case"md":return H.jsx(fOe,{});case"html":return H.jsx(lOe,{});case"css":return H.jsx(uOe,{});case"svelte":return H.jsx(aOe,{});default:return H.jsx(qV,{})}}const dR=({name:t})=>H.jsx("i",{className:"file-icon",children:N.useMemo(()=>I_e(t),[t])}),D_e=({show:t,onClose:e,onConfirm:n,isDirectory:r,name:i})=>{const o=N.useCallback(s=>{s.key==="Enter"&&n()},[n]);return N.useEffect(()=>(t?window.addEventListener("keydown",o):window.removeEventListener("keydown",o),()=>{window.removeEventListener("keydown",o)}),[t,o]),H.jsxs($r,{show:t,onHide:e,centered:!0,children:[H.jsx($r.Header,{closeButton:!0,onClick:e,children:H.jsxs($r.Title,{children:["Delete ",r?"Directory":"File"]})}),H.jsx($r.Body,{children:H.jsxs("p",{children:["This will delete the"," ",r?"directory":"file"," ",H.jsx("strong",{children:i}),"."]})}),H.jsxs($r.Footer,{children:[H.jsx(Uu,{variant:"secondary",type:"button",onClick:e,children:"Cancel"}),H.jsx(Uu,{variant:"primary",onClick:n,children:"Delete"})]})]})},$_e=!0,iW=({id:t,name:e,children:n,handleClick:r,handleDoubleClick:i,handleRenameClick:o,handleDeleteClick:s,isDirectory:a=!1,isActive:l=!1,renameFileTooltipText:u=a?"Rename Directory":"Rename File",deleteFileTooltipText:c=a?"Delete Directory":"Delete File"})=>{const{hoveredItemId:f,setHoveredItemId:d}=N.useContext(Ur),h=f===t,p=N.useCallback(X=>{d(X?t:null)},[t,d]),[g,y]=N.useState(!1),[O,b]=N.useState(""),[S,k]=N.useState(!1),x=N.useRef(null),_=N.useCallback(X=>{X.key==="Escape"?y(!1):X.key==="Enter"&&x.current.blur()},[]),I=N.useCallback(()=>{y(!1),x.current.value.trim()===""?k(!0):o(x.current.value)},[o]),M=N.useCallback(X=>{X.stopPropagation(),y(!g),b(e)},[e,g]);N.useEffect(()=>{g&&x.current.focus()},[g]);const C=N.useCallback(X=>{X.stopPropagation(),k(!0)},[]),P=N.useCallback(()=>{k(!1)},[]),A=N.useCallback(X=>{X?.stopPropagation(),k(!1),s()},[s]),T=N.useCallback(()=>{p(!0)},[]),L=N.useCallback(()=>{p(!1)},[]),R=N.useCallback(()=>{b(x.current.value)},[]);return H.jsxs("div",{className:`file-or-directory user-select-none ${l?"active-file":""}`,onClick:g?null:r,onDoubleClick:g||!i?null:i,onMouseEnter:T,onMouseLeave:L,children:[H.jsx("div",{className:"name",children:g?H.jsxs(H.Fragment,{children:[H.jsx(dR,{name:O}),H.jsx("input",{className:"rename-input",ref:x,type:"text","aria-label":"Field name",value:O,onKeyDown:_,onBlur:I,onChange:R})]}):n}),h&&!g?H.jsxs("div",{className:"utils",style:{position:"relative"},children:[!a||$_e?H.jsx(ns,{placement:"top",overlay:H.jsx(rs,{id:"rename-file-tooltip",children:u}),children:H.jsx("i",{onClick:M,className:"icon-button icon-button-dark",children:H.jsx(Xye,{})})}):null,H.jsx(ns,{placement:"top",overlay:H.jsx(rs,{id:"delete-file-tooltip",children:c}),children:H.jsx("i",{onClick:C,className:"icon-button icon-button-dark",children:H.jsx(Gye,{})})})]}):null,S&&H.jsx(D_e,{show:S,onClose:P,onConfirm:A,isDirectory:a,name:e})]})},L_e=({name:t,path:e,children:n,handleFileClick:r,handleFileDoubleClick:i})=>{const{renameDirectory:o,deleteDirectory:s,isDirectoryOpen:a,toggleDirectory:l,sidebarPresenceIndicators:u}=N.useContext(Ur),c=N.useCallback(()=>{l(e)},[l,e]),f=N.useCallback(()=>{s(e)},[s,e]),d=N.useCallback(p=>{o(e,t,p)},[o,e,t]),h=N.useMemo(()=>a(e),[a,e]);return H.jsxs(H.Fragment,{children:[H.jsxs(iW,{id:e,name:t,handleClick:c,handleDeleteClick:f,handleRenameClick:d,isDirectory:!0,children:[H.jsx("div",{className:"arrow-wrapper",style:{transform:`rotate(${h?90:0}deg)`},children:H.jsx(VV,{})}),H.jsx("div",{className:"name",children:t})]}),n&&h?H.jsx("div",{className:"indentation",children:n.map(p=>{const{fileId:g}=p,{path:y}=p;return H.jsx(oW,{entity:p,handleFileClick:r,handleFileDoubleClick:i},g||y)})}):null]})},N_e=({presence:t})=>H.jsx("div",{className:"presence-indicators",children:t.map((e,n)=>{const i=`rgb(${$8(e.username)})`;return H.jsx("div",{className:"presence-indicator",style:{backgroundColor:i},children:e.username[0]},n)})}),j_e=({name:t,fileId:e,handleFileClick:n,handleFileDoubleClick:r,isActive:i,presence:o})=>{const{renameFile:s,deleteFile:a}=N.useContext(Ur),l=N.useCallback(()=>{n(e)},[e,n]),u=N.useCallback(()=>{r(e)},[e,r]),c=N.useCallback(()=>{a(e)},[e,a]),f=N.useCallback(d=>{s(e,d)},[e,s]);return H.jsxs(iW,{id:e,name:t,handleClick:l,handleDoubleClick:u,handleDeleteClick:c,handleRenameClick:f,isActive:i,children:[H.jsx(N_e,{presence:o}),H.jsx(dR,{name:t}),t]})},oW=({entity:t,handleFileClick:e,handleFileDoubleClick:n})=>{const{activePane:r,sidebarPresenceIndicators:i}=N.useContext(Ur),{name:o,file:s,fileId:a}=t,{path:l,children:u}=t,c=i?.filter(f=>f.fileId===a)||[];return s?H.jsx(j_e,{fileId:a,name:o,handleFileClick:e,handleFileDoubleClick:n,isActive:a===r.activeFileId,presence:c}):H.jsx(L_e,{name:o,path:l,children:u,handleFileClick:e,handleFileDoubleClick:n})};function GQ(t,e,n,r){const i=t.state.doc.line(n).from+r;t.dispatch({selection:{anchor:i,head:i+e.length},scrollIntoView:!0,effects:St.scrollIntoView(i,{y:"center"})})}function KQ(t,e){const n=t.scrollTop,r=n+t.clientHeight,i=e.offsetTop-t.offsetTop,o=i+e.clientHeight;return i>=n+100&&o<=r-100}const Q_e=()=>{const[t,e]=N.useState(!1),[n,r]=N.useState(!1),{search:i,setSearch:o,activePaneId:s,setActiveFileId:a,setSearchResults:l,setSearchFileVisibility:u,setSearchLineVisibility:c,setSearchFocusedIndex:f,shareDBDoc:d,editorCache:h,openTab:p}=N.useContext(Ur),{pattern:g,results:y,focusedIndex:O,focusedChildIndex:b,focused:S}=i,k=N.useRef(null),x=Object.entries(y).filter(([P,A])=>A.visibility!=="closed");N.useEffect(()=>{if(t){r(g.trim().length>=1);const P=setTimeout(()=>{g.trim().length>=1&&k.current&&(l(d),r(!1))},2e3);return()=>clearTimeout(P)}else e(!0)},[g]);const _=N.useCallback((P,A)=>{u(d,P,A.visibility==="open"&&b===null?"flattened":"open")},[O,b]),I=N.useCallback(P=>{u(d,P,"closed")},[]),M=N.useCallback((P,A)=>{a(P),f(A,null)},[]),C=P=>{if(P.preventDefault(),x.length===0)return;const A=x[O][1].matches.length;switch(P.key){case"Tab":f(O,null);break;case"ArrowUp":if(O==0&&b==null)break;if(b===null||A==0){const X=x[O-1][1].matches.length;f(O-1,X>0?X-1:null)}else b===0?f(O,null):f(O,b-1);break;case"ArrowDown":if(O==x.length-1&&b==A-1)break;b===null&&A>0?f(O,0):b==A-1||A==0?f(O+1,null):f(O,b+1);break;case"ArrowLeft":b!==null?f(O,null):_(x[O][0],x[O][1]);break;case"ArrowRight":x[O][1].visibility!=="open"?_(x[O][0],x[O][1]):b===null&&A!==0&&f(O,0);break;case"Enter":case" ":const R=x[O][0];if(p({fileId:R,isTransient:!0}),a(R),b!==null){const X=x[O][1].matches[b].line,z=x[O][1].matches[b].index,W=mm(R,s);h.has(W)&&GQ(h.get(W).editor,g,X,z)}break}const T=x[O][0],L=document.getElementById("sidebar-view-container");if(L)if(b===null){const R=document.getElementById(T);KQ(L,R)||R.scrollIntoView({block:"center"})}else{const R=x[O][1].matches[b].line,X=document.getElementById(T+"-"+R);KQ(L,X)||X.scrollIntoView({block:"center"})}};return N.useEffect(()=>{k.current&&k.current.focus()},[S]),H.jsxs("div",{children:[H.jsx(Dr.Group,{className:"sidebar-search-form mb-3",controlId:"searchName",children:H.jsx(Dr.Control,{type:"text",value:g,onChange:P=>o(P.target.value),ref:k,spellCheck:"false"})}),Object.keys(y).length>=1&&g.trim().length>=1?H.jsx("div",{onKeyDown:C,tabIndex:0,className:"search-results",children:x.map(([P,A],T)=>{const L=A.matches;return H.jsxs("div",{className:"search-result",children:[H.jsxs("div",{onClick:()=>M(P,T),id:P,className:`search-file-heading
378
+ `+n),r.b("</div>"),r.fl()},partials:{},subs:{}});mi["tag-file-added"]=new ii.Template({code:function(t,e,n){var r=this;return r.b(n=n||""),r.b('<span class="d2h-tag d2h-added d2h-added-tag">ADDED</span>'),r.fl()},partials:{},subs:{}});mi["tag-file-changed"]=new ii.Template({code:function(t,e,n){var r=this;return r.b(n=n||""),r.b('<span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span>'),r.fl()},partials:{},subs:{}});mi["tag-file-deleted"]=new ii.Template({code:function(t,e,n){var r=this;return r.b(n=n||""),r.b('<span class="d2h-tag d2h-deleted d2h-deleted-tag">DELETED</span>'),r.fl()},partials:{},subs:{}});mi["tag-file-renamed"]=new ii.Template({code:function(t,e,n){var r=this;return r.b(n=n||""),r.b('<span class="d2h-tag d2h-moved d2h-moved-tag">RENAMED</span>'),r.fl()},partials:{},subs:{}});class v_e{constructor({compiledTemplates:e={},rawTemplates:n={}}){const r=Object.entries(n).reduce((i,[o,s])=>{const a=ii.compile(s,{asString:!1});return Object.assign(Object.assign({},i),{[o]:a})},{});this.preCompiledTemplates=Object.assign(Object.assign(Object.assign({},mi),e),r)}static compile(e){return ii.compile(e,{asString:!1})}render(e,n,r,i,o){const s=this.templateKey(e,n);try{return this.preCompiledTemplates[s].render(r,i,o)}catch{throw new Error(`Could not find template to render '${s}'`)}}template(e,n){return this.preCompiledTemplates[this.templateKey(e,n)]}templateKey(e,n){return`${e}-${n}`}}const y_e=Object.assign(Object.assign(Object.assign({},nW),rW),{outputFormat:Lxe.LINE_BY_LINE,drawFileList:!0});function O_e(t,e={}){const n=Object.assign(Object.assign({},y_e),e),r=typeof t=="string"?zxe(t,n):t,i=new v_e(n),{colorScheme:o}=n,s={colorScheme:o},a=n.drawFileList?new s_e(i,s).render(r):"",l=n.outputFormat==="side-by-side"?new h_e(i,n).render(r):new u_e(i,n).render(r);return a+l}const b_e=({diffData:t})=>{const e=Object.values(t).filter(s=>s.length>0);if(e.length===0)return null;let n=0,r=0;for(const s of e){const a=Dxe(s);n+=a.additions,r+=a.deletions}const i=$xe(t),o=O_e(i,{drawFileList:!1,matching:"words",diffStyle:"word",outputFormat:"line-by-line"});return H.jsxs("div",{className:"diff-view",children:[H.jsx("div",{className:"diff-summary",children:H.jsxs("div",{className:"diff-stats",children:[H.jsxs("span",{className:"files-changed",children:[e.length," file",e.length!==1?"s":""," changed"]}),n>0&&H.jsxs("span",{className:"additions",children:["+",n]}),r>0&&H.jsxs("span",{className:"deletions",children:["-",r]})]})}),H.jsx("div",{className:"diff-files",dangerouslySetInnerHTML:{__html:o}})]})},w_e=({id:t,role:e,content:n,timestamp:r,isStreaming:i,diffData:o,beforeFiles:s,chatId:a,canUndo:l})=>{const[u,c]=N.useState(!1),{aiChatUndoEndpoint:f,aiChatOptions:d={}}=N.useContext(Ur),h=N.useMemo(()=>nhe(r).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}),[r]),p=N.useMemo(()=>`ai-chat-message ${e}${i?" streaming":""}`,[e,i]),g=async()=>{if(!(!t||!a||!s||u||!f)){c(!0);try{const y=await fetch(f,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({vizId:d.vizId,chatId:a,messageId:t})});if(!y.ok)throw new Error(`HTTP error! status: ${y.status}`)}catch(y){console.error("Error undoing AI edit:",y)}finally{c(!1)}}};return H.jsxs("div",{className:p,children:[H.jsxs("div",{className:"ai-chat-message-content",children:[H.jsx(Cz,{remarkPlugins:[Gz],children:n}),o&&Object.keys(o).length>0&&H.jsx(b_e,{diffData:o}),l&&s&&H.jsx("div",{className:"undo-button-container",children:H.jsx("button",{className:"undo-button",onClick:g,disabled:u,title:"Undo this AI edit",children:u?"Undoing...":"Undo"})})]}),H.jsx("div",{className:"ai-chat-message-time",children:h})]})},S_e=N.memo(w_e),k_e=()=>H.jsx("div",{className:"ai-chat-message assistant",children:H.jsx("div",{className:"ai-chat-message-content",children:H.jsxs("div",{className:"ai-chat-typing",children:[H.jsx("span",{}),H.jsx("span",{}),H.jsx("span",{})]})})}),x_e=N.memo(k_e),__e=({content:t,isVisible:e})=>!e||!t?null:H.jsxs("div",{className:"thinking-scratchpad",children:[H.jsxs("div",{className:"thinking-scratchpad-header",children:[H.jsx("span",{className:"thinking-scratchpad-icon",children:"🧠"}),H.jsx("span",{className:"thinking-scratchpad-title",children:"AI is thinking..."})]}),H.jsx("div",{className:"thinking-scratchpad-content",children:H.jsx(Cz,{remarkPlugins:[Gz],children:t})})]}),P_e=N.memo(__e),C_e=({messages:t,aiStatus:e,isLoading:n,chatId:r,aiScratchpad:i})=>{const o=N.useRef(null),s=N.useRef(null),[a,l]=N.useState(!1),[u,c]=N.useState(!0),f=N.useRef(),d=N.useCallback(()=>{const S=s.current;if(!S)return!0;const k=50,{scrollTop:x,scrollHeight:_,clientHeight:I}=S;return _-x-I<k},[]),h=N.useCallback(()=>{u&&o.current?.scrollIntoView({behavior:"smooth",block:"end"})},[u]),p=N.useCallback(()=>{if(!s.current)return;const k=d();f.current&&clearTimeout(f.current),!k&&!a&&(l(!0),c(!1)),k&&a&&(f.current=setTimeout(()=>{l(!1),c(!0)},500))},[a,d]);N.useEffect(()=>(u&&!a&&(f.current&&clearTimeout(f.current),f.current=setTimeout(()=>{h()},100)),()=>{f.current&&clearTimeout(f.current)}),[t,u,a,h]),N.useEffect(()=>()=>{f.current&&clearTimeout(f.current)},[]);const g=t[t.length-1],y=g?.role==="assistant"&&g.content!=="",O=n&&!y,b=!!(i&&i.trim());return H.jsxs("div",{className:"ai-chat-messages",ref:s,onScroll:p,children:[t.map((S,k)=>{const _=S.role==="assistant"&&k===t.length-1&&!n&&S.diffData&&S.beforeFiles&&Object.keys(S.diffData||{}).length>0;return H.jsx(S_e,{id:S.id,role:S.role,content:S.content,timestamp:S.timestamp,diffData:S.diffData,beforeFiles:S.beforeFiles,chatId:r,canUndo:_},S.id)}),b&&H.jsx(P_e,{content:i||"",isVisible:b}),O&&H.jsx(x_e,{}),H.jsx("div",{ref:o})]})},E_e=N.memo(C_e),T_e=({aiChatMessage:t,setAIChatMessage:e,onSendMessage:n,isLoading:r,focused:i,aiChatMode:o,setAIChatMode:s})=>{const a=N.useRef(null);N.useEffect(()=>{i&&a.current&&a.current.focus()},[i]);const l=N.useCallback(f=>{f.key==="Enter"&&!f.shiftKey&&(f.preventDefault(),n())},[n]),u=N.useCallback(()=>{n()},[n]),c=N.useCallback(f=>{e(f.target.value)},[e]);return H.jsxs("div",{className:"ai-chat-input-container",children:[C1e,H.jsxs(Dr.Group,{className:"ai-chat-input-group",children:[H.jsx(Dr.Control,{as:"textarea",rows:2,value:t,onChange:c,onKeyDown:l,ref:a,placeholder:o==="edit"?"Ask me to make code changes...":"Ask me anything about your code...",spellCheck:"false",disabled:r,"aria-label":"Chat message input"}),t&&H.jsxs("div",{className:"ai-chat-input-info",children:[H.jsx("span",{className:"ai-chat-hint",children:"Shift+Enter for new line"}),H.jsx("span",{className:"ai-chat-hint",children:"Press Enter to send"})]}),H.jsx(Uu,{variant:"primary",onClick:u,disabled:!t.trim()||r,className:"ai-chat-send-button","aria-label":"Send message",title:"Send message (Enter)",children:"Send"})]})]})},R_e=N.memo(T_e),A_e="/api/ai-chat/",YQ=!1,M_e=()=>{const{aiChatMessage:t,setAIChatMessage:e}=N.useContext(Ur),[n,r]=N.useState(!1),[i]=N.useState(()=>aB()),[o,s]=N.useState(null),{aiChatFocused:a,content:l,aiChatEndpoint:u=A_e,aiChatOptions:c={},aiChatMode:f,setAIChatMode:d,autoForkAndRetryAI:h,clearStoredAIPrompt:p,getStoredAIPrompt:g}=N.useContext(Ur),y=l?.chats?.[i],O=y?.messages||[],b=y?.aiStatus,S=y?.aiScratchpad,k=N.useMemo(()=>O.map((I,M)=>({...I,id:I.id||`msg-${M}`})),[O]),x=O.length===0,_=N.useCallback(async I=>{const M=I||t;if(!M||typeof M!="string"||!M.trim()||n)return;const C=t.trim();e(""),r(!0),s(null);try{const P=await fetch(u,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({...c,vizId:c.vizId,content:M.trim(),chatId:i,mode:f})});if(!P.ok)throw new Error(`HTTP error! status: ${P.status}`);const A=await P.json();if(A.outcome==="failure"&&A.error){const T=A.error.message;if(T==="You do not have permission to use AI chat on this visualization. Only users with edit access can use this feature. Fork the viz to edit it.")try{await h?.(C,f);return}catch(L){console.error("Auto-fork failed:",L),s("Failed to fork visualization. Please try forking manually.");return}s(T);return}}catch(P){console.error("Error getting AI response:",P),s("Failed to send message. Please try again.")}finally{r(!1)}},[t,n,u,c,i,f,h]);return N.useEffect(()=>{if(g){const I=g();I&&(e(I.prompt),d(I.modelName==="ask"?"ask":"edit"),p(),setTimeout(()=>{_(I.prompt)},100))}},[g,p,e,d,_]),H.jsx("div",{className:"ai-chat-container",children:H.jsxs("div",{style:{padding:"10px",flex:1,display:"flex",flexDirection:"column"},children:[x?H.jsxs("div",{className:"ai-chat-empty",children:[H.jsx("div",{className:"ai-chat-empty-icon",children:"✨"}),H.jsx("h3",{className:"ai-chat-empty-title",children:"Edit with AI"}),H.jsx("div",{className:"ai-chat-empty-text",children:"How can I help you?"}),YQ,YQ]}):H.jsx(E_e,{messages:k,aiStatus:b,isLoading:n,chatId:i,aiScratchpad:S}),o&&H.jsx("div",{className:"ai-chat-error",children:H.jsxs("div",{className:"ai-chat-error-content",children:[H.jsx("span",{className:"ai-chat-error-icon",children:"⚠️"}),H.jsx("span",{className:"ai-chat-error-message",children:o}),H.jsx("button",{className:"ai-chat-error-dismiss",onClick:()=>s(null),"aria-label":"Dismiss error",children:"×"})]})}),H.jsx(R_e,{aiChatMessage:t,setAIChatMessage:e,onSendMessage:_,isLoading:n,focused:a,aiChatMode:f,setAIChatMode:d})]})})};function I_e(t){const e=t.split(".");switch(e[e.length-1]){case"jsx":case"tsx":return H.jsx(sOe,{});case"js":return H.jsx(iOe,{});case"ts":return H.jsx(oOe,{});case"json":return H.jsx(cOe,{});case"md":return H.jsx(fOe,{});case"html":return H.jsx(lOe,{});case"css":return H.jsx(uOe,{});case"svelte":return H.jsx(aOe,{});default:return H.jsx(qV,{})}}const dR=({name:t})=>H.jsx("i",{className:"file-icon",children:N.useMemo(()=>I_e(t),[t])}),D_e=({show:t,onClose:e,onConfirm:n,isDirectory:r,name:i})=>{const o=N.useCallback(s=>{s.key==="Enter"&&n()},[n]);return N.useEffect(()=>(t?window.addEventListener("keydown",o):window.removeEventListener("keydown",o),()=>{window.removeEventListener("keydown",o)}),[t,o]),H.jsxs($r,{show:t,onHide:e,centered:!0,children:[H.jsx($r.Header,{closeButton:!0,onClick:e,children:H.jsxs($r.Title,{children:["Delete ",r?"Directory":"File"]})}),H.jsx($r.Body,{children:H.jsxs("p",{children:["This will delete the"," ",r?"directory":"file"," ",H.jsx("strong",{children:i}),"."]})}),H.jsxs($r.Footer,{children:[H.jsx(Uu,{variant:"secondary",type:"button",onClick:e,children:"Cancel"}),H.jsx(Uu,{variant:"primary",onClick:n,children:"Delete"})]})]})},$_e=!0,iW=({id:t,name:e,children:n,handleClick:r,handleDoubleClick:i,handleRenameClick:o,handleDeleteClick:s,isDirectory:a=!1,isActive:l=!1,renameFileTooltipText:u=a?"Rename Directory":"Rename File",deleteFileTooltipText:c=a?"Delete Directory":"Delete File"})=>{const{hoveredItemId:f,setHoveredItemId:d}=N.useContext(Ur),h=f===t,p=N.useCallback(X=>{d(X?t:null)},[t,d]),[g,y]=N.useState(!1),[O,b]=N.useState(""),[S,k]=N.useState(!1),x=N.useRef(null),_=N.useCallback(X=>{X.key==="Escape"?y(!1):X.key==="Enter"&&x.current.blur()},[]),I=N.useCallback(()=>{y(!1),x.current.value.trim()===""?k(!0):o(x.current.value)},[o]),M=N.useCallback(X=>{X.stopPropagation(),y(!g),b(e)},[e,g]);N.useEffect(()=>{g&&x.current.focus()},[g]);const C=N.useCallback(X=>{X.stopPropagation(),k(!0)},[]),P=N.useCallback(()=>{k(!1)},[]),A=N.useCallback(X=>{X?.stopPropagation(),k(!1),s()},[s]),T=N.useCallback(()=>{p(!0)},[]),L=N.useCallback(()=>{p(!1)},[]),R=N.useCallback(()=>{b(x.current.value)},[]);return H.jsxs("div",{className:`file-or-directory user-select-none ${l?"active-file":""}`,onClick:g?null:r,onDoubleClick:g||!i?null:i,onMouseEnter:T,onMouseLeave:L,children:[H.jsx("div",{className:"name",children:g?H.jsxs(H.Fragment,{children:[H.jsx(dR,{name:O}),H.jsx("input",{className:"rename-input",ref:x,type:"text","aria-label":"Field name",value:O,onKeyDown:_,onBlur:I,onChange:R})]}):n}),h&&!g?H.jsxs("div",{className:"utils",style:{position:"relative"},children:[!a||$_e?H.jsx(ns,{placement:"top",overlay:H.jsx(rs,{id:"rename-file-tooltip",children:u}),children:H.jsx("i",{onClick:M,className:"icon-button icon-button-dark",children:H.jsx(Xye,{})})}):null,H.jsx(ns,{placement:"top",overlay:H.jsx(rs,{id:"delete-file-tooltip",children:c}),children:H.jsx("i",{onClick:C,className:"icon-button icon-button-dark",children:H.jsx(Gye,{})})})]}):null,S&&H.jsx(D_e,{show:S,onClose:P,onConfirm:A,isDirectory:a,name:e})]})},L_e=({name:t,path:e,children:n,handleFileClick:r,handleFileDoubleClick:i})=>{const{renameDirectory:o,deleteDirectory:s,isDirectoryOpen:a,toggleDirectory:l,sidebarPresenceIndicators:u}=N.useContext(Ur),c=N.useCallback(()=>{l(e)},[l,e]),f=N.useCallback(()=>{s(e)},[s,e]),d=N.useCallback(p=>{o(e,t,p)},[o,e,t]),h=N.useMemo(()=>a(e),[a,e]);return H.jsxs(H.Fragment,{children:[H.jsxs(iW,{id:e,name:t,handleClick:c,handleDeleteClick:f,handleRenameClick:d,isDirectory:!0,children:[H.jsx("div",{className:"arrow-wrapper",style:{transform:`rotate(${h?90:0}deg)`},children:H.jsx(VV,{})}),H.jsx("div",{className:"name",children:t})]}),n&&h?H.jsx("div",{className:"indentation",children:n.map(p=>{const{fileId:g}=p,{path:y}=p;return H.jsx(oW,{entity:p,handleFileClick:r,handleFileDoubleClick:i},g||y)})}):null]})},N_e=({presence:t})=>H.jsx("div",{className:"presence-indicators",children:t.map((e,n)=>{const i=`rgb(${$8(e.username)})`;return H.jsx("div",{className:"presence-indicator",style:{backgroundColor:i},children:e.username[0]},n)})}),j_e=({name:t,fileId:e,handleFileClick:n,handleFileDoubleClick:r,isActive:i,presence:o})=>{const{renameFile:s,deleteFile:a}=N.useContext(Ur),l=N.useCallback(()=>{n(e)},[e,n]),u=N.useCallback(()=>{r(e)},[e,r]),c=N.useCallback(()=>{a(e)},[e,a]),f=N.useCallback(d=>{s(e,d)},[e,s]);return H.jsxs(iW,{id:e,name:t,handleClick:l,handleDoubleClick:u,handleDeleteClick:c,handleRenameClick:f,isActive:i,children:[H.jsx(N_e,{presence:o}),H.jsx(dR,{name:t}),t]})},oW=({entity:t,handleFileClick:e,handleFileDoubleClick:n})=>{const{activePane:r,sidebarPresenceIndicators:i}=N.useContext(Ur),{name:o,file:s,fileId:a}=t,{path:l,children:u}=t,c=i?.filter(f=>f.fileId===a)||[];return s?H.jsx(j_e,{fileId:a,name:o,handleFileClick:e,handleFileDoubleClick:n,isActive:a===r.activeFileId,presence:c}):H.jsx(L_e,{name:o,path:l,children:u,handleFileClick:e,handleFileDoubleClick:n})};function GQ(t,e,n,r){const i=t.state.doc.line(n).from+r;t.dispatch({selection:{anchor:i,head:i+e.length},scrollIntoView:!0,effects:St.scrollIntoView(i,{y:"center"})})}function KQ(t,e){const n=t.scrollTop,r=n+t.clientHeight,i=e.offsetTop-t.offsetTop,o=i+e.clientHeight;return i>=n+100&&o<=r-100}const Q_e=()=>{const[t,e]=N.useState(!1),[n,r]=N.useState(!1),{search:i,setSearch:o,activePaneId:s,setActiveFileId:a,setSearchResults:l,setSearchFileVisibility:u,setSearchLineVisibility:c,setSearchFocusedIndex:f,shareDBDoc:d,editorCache:h,openTab:p}=N.useContext(Ur),{pattern:g,results:y,focusedIndex:O,focusedChildIndex:b,focused:S}=i,k=N.useRef(null),x=Object.entries(y).filter(([P,A])=>A.visibility!=="closed");N.useEffect(()=>{if(t){r(g.trim().length>=1);const P=setTimeout(()=>{g.trim().length>=1&&k.current&&(l(d),r(!1))},2e3);return()=>clearTimeout(P)}else e(!0)},[g]);const _=N.useCallback((P,A)=>{u(d,P,A.visibility==="open"&&b===null?"flattened":"open")},[O,b]),I=N.useCallback(P=>{u(d,P,"closed")},[]),M=N.useCallback((P,A)=>{a(P),f(A,null)},[]),C=P=>{if(P.preventDefault(),x.length===0)return;const A=x[O][1].matches.length;switch(P.key){case"Tab":f(O,null);break;case"ArrowUp":if(O==0&&b==null)break;if(b===null||A==0){const X=x[O-1][1].matches.length;f(O-1,X>0?X-1:null)}else b===0?f(O,null):f(O,b-1);break;case"ArrowDown":if(O==x.length-1&&b==A-1)break;b===null&&A>0?f(O,0):b==A-1||A==0?f(O+1,null):f(O,b+1);break;case"ArrowLeft":b!==null?f(O,null):_(x[O][0],x[O][1]);break;case"ArrowRight":x[O][1].visibility!=="open"?_(x[O][0],x[O][1]):b===null&&A!==0&&f(O,0);break;case"Enter":case" ":const R=x[O][0];if(p({fileId:R,isTransient:!0}),a(R),b!==null){const X=x[O][1].matches[b].line,z=x[O][1].matches[b].index,W=mm(R,s);h.has(W)&&GQ(h.get(W).editor,g,X,z)}break}const T=x[O][0],L=document.getElementById("sidebar-view-container");if(L)if(b===null){const R=document.getElementById(T);KQ(L,R)||R.scrollIntoView({block:"center"})}else{const R=x[O][1].matches[b].line,X=document.getElementById(T+"-"+R);KQ(L,X)||X.scrollIntoView({block:"center"})}};return N.useEffect(()=>{k.current&&k.current.focus()},[S]),H.jsxs("div",{children:[H.jsx(Dr.Group,{className:"sidebar-search-form mb-3",controlId:"searchName",children:H.jsx(Dr.Control,{type:"text",value:g,onChange:P=>o(P.target.value),ref:k,spellCheck:"false"})}),Object.keys(y).length>=1&&g.trim().length>=1?H.jsx("div",{onKeyDown:C,tabIndex:0,className:"search-results",children:x.map(([P,A],T)=>{const L=A.matches;return H.jsxs("div",{className:"search-result",children:[H.jsxs("div",{onClick:()=>M(P,T),id:P,className:`search-file-heading
379
379
  ${O==T&&b==null?"active":""}`,children:[H.jsxs("div",{className:"search-file-title",children:[H.jsx("div",{className:"arrow-wrapper",onClick:()=>_(P,A),style:{transform:`rotate(${A.visibility==="open"?90:0}deg)`},children:H.jsx(VV,{})}),H.jsxs("div",{className:"search-file-name",children:[H.jsx(dR,{name:A.name}),H.jsx("h5",{children:A.name})]})]}),H.jsx("div",{className:"search-file-info",children:T==O&&b==null?H.jsx("span",{className:"search-file-close",onClick:R=>{R.stopPropagation(),I(P),f(Math.max(0,T-1),null)},children:H.jsx(BO,{})}):H.jsx("h6",{className:"search-file-count",children:L.length})})]}),H.jsx("div",{className:"search-file-lines",children:(A.visibility==="open"||A.visibility==="flattened"&&T==O&&b!==null)&&A.matches.map((R,X)=>{const z=R.text.substring(0,R.index),W=R.text.substring(R.index,R.index+g.length),G=R.text.substring(R.index+g.length),K=A.name+"-"+R.line;return H.jsxs("div",{tabIndex:T==O?0:-1,id:P+"-"+R.line,className:`search-line
380
380
  ${O==T&&b==X?"active":""}`,children:[H.jsxs("p",{onClick:()=>{f(T,X),p({fileId:P,isTransient:!0}),a(P);const U=mm(P,s);h.has(U)&&GQ(h.get(U).editor,g,R.line,R.index)},children:[z,H.jsx("span",{className:"search-pattern",children:W}),G]},A.name+" - "+R.line+" - "+R.index),O==T&&b===X&&H.jsx("span",{className:"search-file-close",onClick:U=>{U.stopPropagation(),c(d,P,R.line),X==0&&f(T,null)},children:H.jsx(BO,{})})]},K)})})]},A.name)})}):H.jsx("div",{className:"search-state",children:H.jsx("h6",{children:n?"Searching...":"No Results"})})]})},Hs=!1,F_e=()=>{const[t,e]=N.useState(!1),[n,r]=N.useState(!1),{createFile:i}=N.useContext(Ur),o=N.useCallback(p=>{p.preventDefault(),p.stopPropagation(),e(!0)},[]),s=N.useCallback(p=>{p.preventDefault(),p.stopPropagation(),t||e(!0)},[t]),a=N.useCallback(p=>{p.preventDefault(),p.stopPropagation(),e(!1)},[]),l=p=>["text/","application/json","application/javascript","application/typescript","application/xml","application/x-httpd-php"].some(O=>p.type.startsWith(O))||p.name.match(/\.(txt|js|jsx|ts|tsx|md|css|scss|html|xml|json|php|py|rb|java|c|cpp|h|hpp)$/i)!==null,u=p=>["image/"].some(O=>p.type.startsWith(O))||p.name.match(/\.(png|jpg|jpeg|gif|bmp|svg|webp)$/i)!==null,c=p=>new Promise((g,y)=>{if(!l(p)){y(new Error(`File ${p.name} is not a text file`));return}const O=new FileReader;O.onload=b=>{b.target?.result?g(b.target.result):y(new Error(`Failed to read file ${p.name}`))},O.onerror=()=>{y(new Error(`Error reading file ${p.name}`))},O.readAsText(p)}),f=p=>new Promise((g,y)=>{if(!u(p)){y(new Error(`File ${p.name} is not an image file`));return}if(p.type==="image/svg+xml"||p.name.toLowerCase().endsWith(".svg")){const b=new FileReader;b.onload=S=>{S.target?.result?g(S.target.result):y(new Error(`Failed to read SVG file ${p.name}`))},b.onerror=()=>y(new Error(`Error reading SVG file ${p.name}`)),b.readAsText(p);return}const O=new FileReader;O.onload=b=>{if(b.target?.result){const S=b.target.result.split(",")[1];g(S)}else y(new Error(`Failed to read image file ${p.name}`))},O.onerror=()=>{y(new Error(`Error reading image file ${p.name}`))},O.readAsDataURL(p)}),d=async(p,g)=>{try{if(Hs&&console.log(`[useDragAndDrop] Processing entry: ${p.name} at path: ${g}`),p.isFile)Hs&&console.log(`[useDragAndDrop] Processing file: ${p.name}`),p.file(async y=>{try{if(u(y)){const O=await f(y);Hs&&console.log(`[useDragAndDrop] Creating image file: ${g}${y.name}`),i(`${g}${y.name}`,O)}else{const O=await c(y);Hs&&console.log(`[useDragAndDrop] Creating text file: ${g}${y.name}`),i(`${g}${y.name}`,O)}}catch(O){console.error(`Error processing file ${y.name}:`,O)}});else if(p.isDirectory)return Hs&&console.log(`[useDragAndDrop] Processing directory: ${p.name}`),new Promise(y=>{const O=p.createReader(),b=()=>{O.readEntries(async S=>{if(S.length===0){Hs&&console.log(`[useDragAndDrop] Finished reading directory: ${p.name}`),y();return}const k=`${g}${p.name}/`;Hs&&console.log(`[useDragAndDrop] Reading ${S.length} entries in directory: ${k}`),await Promise.all(S.map(x=>d(x,k))),b()})};b()})}catch(y){console.error(`Error processing entry ${p.name}:`,y)}},h=N.useCallback(async p=>{p.preventDefault(),p.stopPropagation(),e(!1),r(!0);try{const g=p.dataTransfer.items;Hs&&console.log(`[useDragAndDrop] Processing ${g.length} dropped items`);const y=[];for(const O of Array.from(g)){const b=O.webkitGetAsEntry?.()||O.getAsEntry?.()||O.createEntry?.();if(b)Hs&&console.log(`[useDragAndDrop] Got entry for: ${b.name}`),y.push(b);else if(O.kind==="file"){const S=O.getAsFile();if(S){Hs&&console.log(`[useDragAndDrop] Processing dropped file: ${S.name}`);try{if(u(S)){const k=await f(S);i(S.name,k)}else{const k=await c(S);i(S.name,k)}}catch(k){console.error(`Error processing file ${S.name}:`,k)}}}}Hs&&console.log(`[useDragAndDrop] Processing ${y.length} entries`),await Promise.all(y.map(O=>d(O,"")))}catch(g){console.error("Error processing dropped items:",g)}finally{r(!1)}},[i]);return{isDragOver:t,isProcessing:n,handleDragEnter:o,handleDragOver:s,handleDragLeave:a,handleDrop:h}};function B_e(t,e){const n={},d=[{regex:/^\s*###\s*`([^`]+)`\s*\n```(?:\w+)?\n([\s\S]*?)```/gm,format:"Backtick-Heading Format",key:"backtick-heading"},{regex:/^\s*###\s*File:\s*\*\*(.+?)\*\*\s*\n```(?:\w+)?\n([\s\S]*?)```/gm,format:"File Bold Format",key:"file-bold"},{regex:/^\s*###\s*\d+\.\s*`([^`]+)`(?:[^\n]*\n)*?\s*```(?:\w+)?\n([\s\S]*?)```/gm,format:"Numbered Backtick Format",key:"numbered-backtick"},{regex:/^### \*\*([^\n`]+?)\*\*\s*\n```(?:\w+)?\n([\s\S]*?)```/gm,format:"Heading Bold Format",key:"heading-bold"},{regex:/^\s*###\s*(?!`|File:|\d+\.)\s*([^\n`]+?)\s*\n```(?:\w+)?\n([\s\S]*?)```/gm,format:"Standard Heading Format",key:"standard-heading"},{regex:/^\s*(?!###|\*\*|`)([^\n#*`]+?):\s*\n```(?:\w+)?\n([\s\S]*?)```/gm,format:"Colon Format",key:"colon"},{regex:/^\s*(?!###)\*\*([^\n*`]+?)\*\*(?:[^\n]*)\s*\n```(?:\w+)?\n([\s\S]*?)```/gm,format:"Bold Format",key:"bold"},{regex:/^\s*# ([^\n`]+?)\s*\n```(?:\w+)?\n([\s\S]*?)```/gm,format:"Hash Format",key:"hash"},{regex:/^\s*\d+\.\s*\*\*([^\n`]+?)\*\*[\s\S]*?\n```(?:\w+)?\n([\s\S]*?)```/gm,format:"Numbered Bold Format",key:"numbered-bold"}];let h=d;{const g=d.find(y=>y.key===e);if(!g)throw new Error(`Unsupported format: ${e}`);h=[g]}let p="Unknown Format";for(const{regex:g,format:y}of h){g.lastIndex=0;const O={};let b;for(;(b=g.exec(t))!==null;){let S=b[1].trim();y==="Bold Format"&&(S=S.replace(/\s*\([^)]*\).*$/,"").trim());const k=b[2].trim();O[S]=k}if(Object.keys(O).length>0){Object.assign(n,O),p=y;break}}return{files:n,format:p}}const U_e=t=>t.endsWith(".html")?"html":t.endsWith(".js")?"javascript":t.endsWith(".css")?"css":"",q_e=t=>Object.entries(t).map(([e,n])=>[`**${e}**
381
381
  `,"```"+U_e(e),n,"```\n"].join(`
package/dist/index.html CHANGED
@@ -20,8 +20,8 @@
20
20
  href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap"
21
21
  rel="stylesheet"
22
22
  />
23
- <script type="module" crossorigin src="/assets/index-DILO4YFE.js"></script>
24
- <link rel="stylesheet" crossorigin href="/assets/index-GFaZu2lY.css">
23
+ <script type="module" crossorigin src="/assets/index-Cp6YlJo2.js"></script>
24
+ <link rel="stylesheet" crossorigin href="/assets/index-COSAnnol.css">
25
25
  </head>
26
26
  <body>
27
27
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vzcode",
3
- "version": "1.55.0",
3
+ "version": "1.56.0",
4
4
  "description": "Multiplayer code editor system",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
@@ -50,6 +50,10 @@ const ChatInputComponent = ({
50
50
  [onSendMessage],
51
51
  );
52
52
 
53
+ const handleSendClick = useCallback(() => {
54
+ onSendMessage();
55
+ }, [onSendMessage]);
56
+
53
57
  const handleChange = useCallback(
54
58
  (event: React.ChangeEvent<HTMLTextAreaElement>) => {
55
59
  setAIChatMessage(event.target.value);
@@ -134,7 +138,7 @@ const ChatInputComponent = ({
134
138
  )}
135
139
  <Button
136
140
  variant="primary"
137
- onClick={onSendMessage}
141
+ onClick={handleSendClick}
138
142
  disabled={!aiChatMessage.trim() || isLoading}
139
143
  className="ai-chat-send-button"
140
144
  aria-label="Send message"
@@ -68,13 +68,15 @@ export const AIChat = () => {
68
68
  aiChatMessage,
69
69
  );
70
70
  const messageContent = messageToSend || aiChatMessage;
71
+
71
72
  if (
72
73
  !messageContent ||
73
74
  typeof messageContent !== 'string' ||
74
75
  !messageContent.trim() ||
75
76
  isLoading
76
- )
77
+ ) {
77
78
  return;
79
+ }
78
80
 
79
81
  const currentPrompt = aiChatMessage.trim();
80
82
  setAIChatMessage('');
@@ -146,12 +146,19 @@
146
146
  }
147
147
 
148
148
  .ai-chat-message-content {
149
+ .diff-view .diff-files .d2h-code-linenumber {
150
+ display: none !important;
151
+ }
152
+
153
+ .d2h-code-line {
154
+ padding: 0 1em;
155
+ }
156
+
149
157
  padding: 10px 12px;
150
158
  font-size: 14px;
151
159
  line-height: 1.4;
152
160
  word-wrap: break-word;
153
161
 
154
- // Undo button styles (moved from DiffView)
155
162
  .undo-button-container {
156
163
  display: flex;
157
164
  justify-content: flex-end;
@@ -25,6 +25,9 @@ export function generateFileUnifiedDiff(
25
25
  fileName,
26
26
  beforeContent,
27
27
  afterContent,
28
+ '',
29
+ '',
30
+ { context: 3 },
28
31
  );
29
32
 
30
33
  return unifiedDiff;