llmd 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.js +14 -43
- package/dist/llmd +480 -583
- package/package.json +4 -6
package/dist/client.js
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
var
|
|
1
|
+
var y=()=>{let C=document.querySelector(".admin-section"),q=document.querySelector(".admin-header");if(!(C&&q))return;if(localStorage.getItem("llmd-admin-collapsed")==="true")C.classList.add("collapsed");q.addEventListener("click",()=>{let K=C.classList.toggle("collapsed");localStorage.setItem("llmd-admin-collapsed",K.toString())})};var E=(C)=>{return C.getAttribute("data-dir-path")||null},c=()=>{let C=[],q=document.querySelectorAll(".dir-group.collapsed");for(let J of Array.from(q)){let K=E(J);if(K)C.push(K)}localStorage.setItem("llmd-nav-collapsed",JSON.stringify(C))},d=()=>{try{let C=localStorage.getItem("llmd-nav-collapsed");if(!C)return;let q=JSON.parse(C),J=document.querySelectorAll(".dir-group");for(let K of Array.from(J)){let Q=E(K);if(Q&&q.includes(Q))K.classList.add("collapsed")}}catch(C){console.error("[collapsible] Failed to restore state:",C)}},p=()=>{let C=document.querySelectorAll(".dir-group-header");for(let q of Array.from(C)){let J=q;J.addEventListener("click",(K)=>{K.preventDefault();let Q=J.closest(".dir-group");if(Q)Q.classList.toggle("collapsed"),c()})}d()},g=()=>{let C=document.querySelector(".toc");if(!C)return;let q=C.querySelector("h3");if(!q)return;let J=document.createElement("span");J.className="toc-chevron",J.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>',q.style.cursor="pointer",q.insertBefore(J,q.firstChild),q.addEventListener("click",()=>{C.classList.toggle("collapsed")})},z=()=>{p(),g()};var I=()=>{for(let C of Array.from(document.querySelectorAll("pre code"))){let q=C.parentElement;if(!q)continue;if(q.querySelector(".copy-button"))continue;let J=document.createElement("button");J.className="copy-button",J.textContent="Copy",J.setAttribute("aria-label","Copy code to clipboard"),J.addEventListener("click",async()=>{try{await navigator.clipboard.writeText(C.textContent||""),J.textContent="Copied!",J.classList.add("copied"),setTimeout(()=>{J.textContent="Copy",J.classList.remove("copied")},2000)}catch(K){console.error("Failed to copy:",K),J.textContent="Failed",setTimeout(()=>{J.textContent="Copy"},2000)}}),q.appendChild(J)}};if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",I);else I();var T=(C,q,J)=>{fetch("/api/events",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:C,path:q,resourceType:J})}).catch(()=>{})},H=(C)=>{T("open",C,"dir")},R=(C)=>{T("view",C,"file")};var l=(C)=>{let J=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/_ws`,K=null,Q=null,Y=0,j=!1,$=()=>{K=new WebSocket(J),K.addEventListener("open",()=>{Y=0,console.log("[llmd] Connected to file watcher"),K?.send(JSON.stringify({type:"watch",file:C}))}),K.addEventListener("message",(Z)=>{try{let V=JSON.parse(Z.data);if(V.type==="reload"&&V.file===C)console.log(`[llmd] File changed: ${C}, reloading...`),window.location.reload()}catch(V){console.error("[llmd] Failed to parse message:",V)}}),K.addEventListener("close",()=>{if(j)return;let Z=Math.min(30000,1000*2**Y);Y+=1,Q=window.setTimeout($,Z)}),K.addEventListener("error",()=>{console.error("[llmd] WebSocket error")})};$(),window.addEventListener("beforeunload",()=>{if(j=!0,Q)clearTimeout(Q);K?.close()})},S=()=>{let C=document.body?.dataset.watchFile;if(C)l(C)};var s=(C,q)=>{let J=Math.min(C.length,q.length),K=0;while(K<J&&C.at(-1-K)===q.at(-1-K))K+=1;return K},h=(C,q)=>{let J=Math.min(C.length,q.length),K=0;while(K<J&&C[K]===q[K])K+=1;return K},w=(C,q,J)=>({exact:C.slice(q,J),prefix:C.slice(Math.max(0,q-32),q),suffix:C.slice(J,J+32)}),n=(C,q)=>{let J=[],K=C.indexOf(q);while(K!==-1)J.push(K),K=C.indexOf(q,K+1);return J},P=(C,q)=>{let{exact:J,prefix:K,suffix:Q}=q;if(!J)return null;let Y=n(C,J);if(Y.length===0)return null;if(Y.length===1){let Z=Y[0];return{start:Z,end:Z+J.length}}let j=Y[0],$=-1;for(let Z of Y){let V=C.slice(Math.max(0,Z-K.length),Z),B=C.slice(Z+J.length,Z+J.length+Q.length),_=s(V,K)+h(B,Q);if(_>$)$=_,j=Z}return{start:j,end:j+J.length}};var a=".markdown-body",r=1000,L=()=>document.querySelector(a),W=(C)=>{let q=document.createTreeWalker(C,NodeFilter.SHOW_TEXT),J=[],K="",Q=q.nextNode();while(Q){let Y=Q.textContent??"";J.push({node:Q,start:K.length,end:K.length+Y.length}),K+=Y,Q=q.nextNode()}return{text:K,spans:J}},k=(C)=>W(C).text,A=(C,q,J)=>{let K=document.createRange();return K.selectNodeContents(C),K.setEnd(q,J),K.toString().length},o=(C)=>{let q=C.querySelectorAll("mark.llmd-highlight");for(let J of Array.from(q)){let K=J.parentNode;if(K)K.replaceChild(document.createTextNode(J.textContent??""),J)}C.normalize()},i=(C,q,J,K)=>{let Q=C.node.textContent??"",Y=Q.slice(q,J),j=C.node.parentNode;if(!(j&&Y))return;let $=Q.slice(0,q),Z=Q.slice(J),V=document.createElement("mark");V.className="llmd-highlight",V.dataset.highlightId=K,V.style.cursor="pointer",V.textContent=Y;let B=document.createDocumentFragment();if($)B.appendChild(document.createTextNode($));if(B.appendChild(V),Z)B.appendChild(document.createTextNode(Z));j.replaceChild(B,C.node)},t=(C,q,J,K)=>{let Q=C.filter((Y)=>Y.start<J&&Y.end>q);for(let Y=Q.length-1;Y>=0;Y-=1){let j=Q[Y],$=Math.max(0,q-j.start),Z=Math.min((j.node.textContent??"").length,J-j.start);i(j,$,Z,K)}},e=(C)=>{let q=[...C].sort((Q,Y)=>Q.start-Y.start),J=[],K=-1;for(let Q of q)if(Q.start>=K)J.push(Q),K=Q.end;return J},v=(C,q)=>{o(C);let J=W(C).text,K=new Set,Q=new Set,Y=[];for(let $ of q){let Z=P(J,$);if(Z)Y.push({id:$.id,start:Z.start,end:Z.end}),K.add($.id);else Q.add($.id)}let j=e(Y).sort(($,Z)=>Z.start-$.start);for(let $ of j){let{spans:Z}=W(C);t(Z,$.start,$.end,$.id)}return{paintedIds:K,staleIds:Q}},M=(C,q="smooth")=>{let J=document.querySelectorAll(`mark.llmd-highlight[data-highlight-id="${C}"]`),K=J[0];if(!K)return!1;K.scrollIntoView({behavior:q,block:"center"});for(let Q of Array.from(J))Q.classList.add("highlight-flash"),setTimeout(()=>Q.classList.remove("highlight-flash"),r);return!0};var b=(C)=>{return new Date(C).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"})},x=(C,q)=>C.length>q?`${C.slice(0,q)}...`:C,CC=(C)=>{let q=document.createElement("li");q.className="highlight-summary-item",q.dataset.highlightId=C.id,q.style.cssText="margin: 8px 0; padding: 8px; background: var(--bg); border-radius: 4px; border-left: 3px solid var(--accent); cursor: pointer; transition: background 0.2s;",q.addEventListener("mouseover",()=>{q.style.background="var(--hover)"}),q.addEventListener("mouseout",()=>{q.style.background="var(--bg)"}),q.addEventListener("click",()=>M(C.id));let J=document.createElement("div");if(C.isStale)J.style.cssText="text-decoration: line-through; opacity: 0.5;";if(J.textContent=x(C.exact,80),q.appendChild(J),C.notes){let Q=document.createElement("div");Q.style.cssText="margin-top: 4px; padding: 6px; background: var(--sidebar-bg); border-radius: 3px; font-size: 11px; opacity: 0.8;",Q.textContent=`Note: ${x(C.notes,60)}`,q.appendChild(Q)}let K=document.createElement("div");return K.style.cssText="opacity: 0.5; font-size: 12px; margin-top: 4px;",K.textContent=C.isStale?`${b(C.createdAt)} (stale)`:b(C.createdAt),q.appendChild(K),q},f=(C)=>{let q=L();if(!q)return;if(q.parentElement?.querySelector(".highlights-summary")?.remove(),C.length===0)return;let J=document.createElement("div");J.className="highlights-summary";let K=document.createElement("div");K.style.cssText="background: var(--code-bg); border: 1px solid var(--border); border-radius: 8px; padding: 16px 20px; margin: 24px 0;";let Q=document.createElement("h3");Q.style.cssText="font-size: 0.875rem; margin: 0 0 12px 0; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; opacity: 0.8;",Q.textContent=`Highlights (${C.length})`,K.appendChild(Q);let Y=document.createElement("ul");Y.style.cssText="list-style: none; padding: 0; margin: 0; font-size: 14px;";for(let Z of C)Y.appendChild(CC(Z));K.appendChild(Y);let j=document.createElement("div");j.style.cssText="margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border);";let $=document.createElement("a");$.href="/highlights",$.style.cssText="color: var(--accent); text-decoration: none; font-size: 13px; font-weight: 500;",$.textContent="View all highlights",j.appendChild($),K.appendChild(j),J.appendChild(K),q.parentElement?.insertBefore(J,q)};var D=[],X=null,U=null,G=new Map,m=()=>window.location.pathname.replace("/view/",""),u=()=>{if(!L())return;qC(),document.addEventListener("mouseup",QC),KC()},qC=async()=>{let C=L();if(!C)return;try{let q=await fetch(`/api/highlights/resource?path=${encodeURIComponent(m())}`);if(!q.ok)return;D=(await q.json()).highlights||[];let{staleIds:K}=v(C,D);JC(C),f(D.map((Q)=>({id:Q.id,exact:Q.exact,notes:Q.notes,createdAt:Q.createdAt,isStale:K.has(Q.id)})))}catch(q){console.error("[highlights] Failed to fetch highlights:",q)}},JC=(C)=>{let q=C.querySelectorAll("mark.llmd-highlight");for(let J of Array.from(q)){let K=J.getAttribute("data-highlight-id"),Q=D.find((Y)=>Y.id===K);if(!Q)continue;J.addEventListener("click",(Y)=>{Y.stopPropagation(),jC(Q,Y)})}},KC=()=>{let C=window.location.hash;if(!C.startsWith("#highlight-"))return;let q=C.slice(11);if(q)M(q,"smooth")},QC=(C)=>{let q=C.target;if(X?.contains(q))return;let J=L(),K=window.getSelection();if(!(J&&K)||K.isCollapsed){O();return}let Q=K.getRangeAt(0);if(!(J.contains(Q.startContainer)&&J.contains(Q.endContainer)&&K.toString().trim())){O();return}let j=A(J,Q.startContainer,Q.startOffset),$=A(J,Q.endContainer,Q.endOffset);U={start:Math.min(j,$),end:Math.max(j,$)},YC(C)},YC=(C)=>{if(!X)X=ZC(),document.body.appendChild(X);X.style.left=`${C.pageX}px`,X.style.top=`${C.pageY-50}px`,X.style.display="block"},O=()=>{if(X)X.style.display="none";U=null},ZC=()=>{let C=document.createElement("div");return C.className="highlight-popup",C.innerHTML=`
|
|
2
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
|
|
3
|
+
<span style="font-size: 13px; font-weight: 500; color: var(--fg);">Add Highlight</span>
|
|
4
|
+
<button class="highlight-close-btn" type="button" style="background: none; border: none; color: var(--fg); cursor: pointer; padding: 0; font-size: 18px; line-height: 1; opacity: 0.7;">×</button>
|
|
5
|
+
</div>
|
|
6
|
+
<textarea
|
|
7
|
+
class="highlight-notes-input"
|
|
8
|
+
placeholder="Add a note (optional)"
|
|
9
|
+
rows="2"
|
|
10
|
+
style="width: 100%; padding: 8px; border: 1px solid var(--border); border-radius: 4px; background: var(--bg); color: var(--fg); font-size: 13px; resize: vertical; margin-bottom: 8px; font-family: inherit;"
|
|
11
|
+
></textarea>
|
|
12
|
+
<button class="highlight-create-btn" type="button">Create Highlight</button>
|
|
13
|
+
`,C.querySelector(".highlight-create-btn")?.addEventListener("click",(q)=>{q.stopPropagation(),$C()}),C.querySelector(".highlight-close-btn")?.addEventListener("click",(q)=>{q.stopPropagation(),O()}),C},$C=async()=>{let C=L();if(!(C&&U))return;let q=k(C),J=w(q,U.start,U.end),Q=X?.querySelector(".highlight-notes-input")?.value.trim()||void 0;try{let Y=await fetch("/api/highlights",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({resourcePath:m(),...J,notes:Q})});if(!Y.ok){let j=await Y.json().catch(()=>({}));console.error("[highlights] Server error:",j.error??"Failed to create highlight");return}window.location.reload()}catch(Y){console.error("[highlights] Failed to create highlight:",Y)}},F=(C)=>{let q=G.get(C);if(!q)return;q.el.remove(),document.removeEventListener("click",q.onOutsideClick),G.delete(C)},jC=(C,q)=>{if(G.has(C.id)){F(C.id);return}let J=document.createElement("div");J.className="highlight-notes-popup",J.style.cssText=`
|
|
2
14
|
position: absolute;
|
|
3
15
|
background: var(--bg);
|
|
4
16
|
border: 1px solid var(--border);
|
|
@@ -9,45 +21,4 @@ var G=()=>{let C=document.querySelector(".admin-section"),q=document.querySelect
|
|
|
9
21
|
z-index: 10000;
|
|
10
22
|
font-size: 13px;
|
|
11
23
|
line-height: 1.5;
|
|
12
|
-
`;let K=document.createElement("div");K.style.cssText="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;";let Q=document.createElement("span");Q.textContent="Highlight Notes",Q.style.cssText="font-weight: 600; color: var(--fg);";let
|
|
13
|
-
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
|
|
14
|
-
<span style="font-size: 13px; font-weight: 500; color: var(--fg);">Add Highlight</span>
|
|
15
|
-
<button class="highlight-close-btn" type="button" style="background: none; border: none; color: var(--fg); cursor: pointer; padding: 0; font-size: 18px; line-height: 1; opacity: 0.7;">×</button>
|
|
16
|
-
</div>
|
|
17
|
-
<textarea
|
|
18
|
-
class="highlight-notes-input"
|
|
19
|
-
placeholder="Add a note (optional)"
|
|
20
|
-
rows="2"
|
|
21
|
-
style="width: 100%; padding: 8px; border: 1px solid var(--border); border-radius: 4px; background: var(--bg); color: var(--fg); font-size: 13px; resize: vertical; margin-bottom: 8px; font-family: inherit;"
|
|
22
|
-
></textarea>
|
|
23
|
-
<button class="highlight-create-btn" type="button">
|
|
24
|
-
Create Highlight
|
|
25
|
-
</button>
|
|
26
|
-
`;let q=C.querySelector(".highlight-create-btn");if(q)q.addEventListener("click",async(J)=>{J.stopPropagation(),await l()});let j=C.querySelector(".highlight-close-btn");if(j)j.addEventListener("click",(J)=>{J.stopPropagation(),B()});return C},d=(C,q)=>{let j=document.querySelector(".content");if(!j)return 0;let J=document.createRange();J.selectNodeContents(j),J.setEnd(q.startContainer,q.startOffset);let K=J.toString(),Q=0,Z=0;while(!0){let _=K.indexOf(C,Z);if(_===-1)break;Q+=1,Z=_+1}return Q},l=async()=>{if(!D)return;try{let{text:C,range:q}=D,j=d(C,q),K=V?.querySelector(".highlight-notes-input")?.value.trim()||void 0,Q=window.location.pathname.replace("/view/",""),Z=await fetch("/api/highlights",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({resourcePath:Q,highlightedText:C,occurrenceIndex:j,notes:K})});if(!Z.ok){let _=await Z.json();console.error("[highlights] Server error:",_.error||"Failed to create highlight");return}window.location.reload()}catch(C){console.error("[highlights] Failed to create highlight:",C)}};var g=(C)=>{return new Date(C).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"})},h=(C)=>{let q=document.querySelector(`[data-highlight-id="${C}"]`);if(q)q.scrollIntoView({behavior:"smooth",block:"center"}),q.classList.add("highlight-flash"),setTimeout(()=>{q.classList.remove("highlight-flash")},1000)},s=(C,q)=>C.length>q?`${C.slice(0,q)}...`:C,T=()=>{let C=document.querySelector(".content");if(!C)return;let q=window.location.pathname;if(!q.startsWith("/view/"))return;let j=q.slice(6);fetch(`/api/highlights/resource?path=${encodeURIComponent(j)}`).then((J)=>J.json()).then((J)=>{let K=J.highlights||[];if(K.length===0)return;let Q=document.createElement("div");Q.className="highlights-summary",Q.innerHTML=`
|
|
27
|
-
<div style="background: var(--code-bg); border: 1px solid var(--border); border-radius: 8px; padding: 16px 20px; margin: 24px 0;">
|
|
28
|
-
<h3 style="font-size: 0.875rem; margin: 0 0 12px 0; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; opacity: 0.8; display: flex; align-items: center; gap: 6px;">
|
|
29
|
-
<span style="font-size: 16px;">✨</span>
|
|
30
|
-
Highlights (${K.length})
|
|
31
|
-
</h3>
|
|
32
|
-
<ul style="list-style: none; padding: 0; margin: 0; font-size: 14px;">
|
|
33
|
-
${K.map(($)=>{let Y=$.isStale?'<span style="color: #f44336; margin-left: 4px;" title="Stale - file has changed">⚠️</span>':"",X=$.isStale?' style="text-decoration: line-through; opacity: 0.5;"':"",L=$.highlightedText.length>80?`${$.highlightedText.slice(0,80)}...`:$.highlightedText,U=$.notes?s($.notes,60):"",F=U?`<div style="margin-top: 4px; padding: 6px; background: var(--sidebar-bg); border-radius: 3px; font-size: 11px; opacity: 0.8;">\uD83D\uDCAD ${U}</div>`:"";return`
|
|
34
|
-
<li style="margin: 8px 0; padding: 8px; background: var(--bg); border-radius: 4px; border-left: 3px solid var(--accent); cursor: pointer; transition: background 0.2s;"
|
|
35
|
-
data-highlight-id="${$.id}"
|
|
36
|
-
class="highlight-summary-item"
|
|
37
|
-
onmouseover="this.style.background='var(--hover)'"
|
|
38
|
-
onmouseout="this.style.background='var(--bg)'">
|
|
39
|
-
<div${X}>${L}</div>
|
|
40
|
-
${F}
|
|
41
|
-
<div style="opacity: 0.5; font-size: 12px; margin-top: 4px;">
|
|
42
|
-
${g($.createdAt)}${Y}
|
|
43
|
-
</div>
|
|
44
|
-
</li>
|
|
45
|
-
`}).join("")}
|
|
46
|
-
</ul>
|
|
47
|
-
<div style="margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border);">
|
|
48
|
-
<a href="/highlights" style="color: var(--accent); text-decoration: none; font-size: 13px; font-weight: 500;">
|
|
49
|
-
View all highlights →
|
|
50
|
-
</a>
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
53
|
-
`;let Z=C.querySelector("h1, h2");if(Z)Z.parentNode?.insertBefore(Q,Z);else C.insertBefore(Q,C.firstChild);let _=Q.querySelectorAll(".highlight-summary-item");for(let $ of Array.from(_)){let Y=$.getAttribute("data-highlight-id");if(Y)$.addEventListener("click",()=>h(Y))}}).catch((J)=>{console.error("Failed to load highlights summary:",J)})};var o=()=>{let C=document.querySelector(".sidebar");if(!C)return;let q=document.createElement("div");q.className="sidebar-resize-handle",C.appendChild(q);let j=!1,J=0,K=0,Q=(Y)=>{j=!0,J=Y.clientX,K=C.offsetWidth,document.body.style.cursor="ew-resize",document.body.style.userSelect="none",Y.preventDefault()},Z=(Y)=>{if(!j)return;let X=Y.clientX-J,L=K+X,U=Math.max(200,Math.min(600,L));C.style.width=`${U}px`,localStorage.setItem("llmd-sidebar-width",U.toString())},_=()=>{if(!j)return;j=!1,document.body.style.cursor="",document.body.style.userSelect=""};q.addEventListener("mousedown",Q),document.addEventListener("mousemove",Z),document.addEventListener("mouseup",_);let $=localStorage.getItem("llmd-sidebar-width");if($){let Y=Number.parseInt($,10);if(Y>=200&&Y<=600)C.style.width=`${Y}px`}};if(typeof window<"u")window.addEventListener("DOMContentLoaded",()=>{o()});var b=(C,q,j)=>{fetch("/api/events",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:C,path:q,resourceType:j})}).catch(()=>{})},I=(C)=>{b("open",C,"dir")},w=(C)=>{b("view",C,"file")};var M=async()=>{try{let C=window.location.pathname.replace("/view/",""),q=C.includes("/")?C.substring(0,C.lastIndexOf("/")):"",j=await fetch(`/api/highlights/directory?path=${encodeURIComponent(q||".")}`);if(!j.ok)return;let K=(await j.json()).highlights||[],Q=new Set;for(let _ of K)Q.add(_.resourcePath);let Z=document.querySelectorAll("a[data-file-path]");for(let _ of Array.from(Z)){let $=_.getAttribute("data-file-path");if($&&Q.has($)){let Y=_.querySelector(".file-icon svg");if(Y)Y.setAttribute("fill","var(--accent)"),Y.setAttribute("fill-opacity","0.3")}}}catch(C){console.error("[file-highlights] Failed to load highlight indicators:",C)}};if(typeof window<"u")window.addEventListener("DOMContentLoaded",()=>{M()});window.trackDirectoryOpen=I;window.trackFileView=w;G();E();M();if(document.querySelector(".content"))S(),T();console.log("[llmd] Client initialized");
|
|
24
|
+
`;let K=document.createElement("div");K.style.cssText="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;";let Q=document.createElement("span");Q.textContent="Highlight Notes",Q.style.cssText="font-weight: 600; color: var(--fg);";let Y=document.createElement("button");Y.textContent="×",Y.style.cssText="background: none; border: none; color: var(--fg); cursor: pointer; padding: 0; font-size: 18px; line-height: 1; opacity: 0.7;",Y.addEventListener("click",(Z)=>{Z.stopPropagation(),F(C.id)}),K.appendChild(Q),K.appendChild(Y);let j=document.createElement("div");j.style.cssText="color: var(--fg); white-space: pre-wrap; word-wrap: break-word;",j.textContent=C.notes||"(No notes)",J.appendChild(K),J.appendChild(j),J.addEventListener("click",(Z)=>Z.stopPropagation()),J.style.left=`${q.pageX}px`,J.style.top=`${q.pageY+10}px`,document.body.appendChild(J);let $=(Z)=>{if(!J.contains(Z.target))F(C.id)};G.set(C.id,{el:J,onOutsideClick:$}),setTimeout(()=>document.addEventListener("click",$),0)};var VC=()=>{let C=document.querySelector(".sidebar");if(!C)return;let q=document.createElement("div");q.className="sidebar-resize-handle",C.appendChild(q);let J=!1,K=0,Q=0,Y=(V)=>{J=!0,K=V.clientX,Q=C.offsetWidth,document.body.style.cursor="ew-resize",document.body.style.userSelect="none",V.preventDefault()},j=(V)=>{if(!J)return;let B=V.clientX-K,_=Q+B,N=Math.max(200,Math.min(600,_));C.style.width=`${N}px`,localStorage.setItem("llmd-sidebar-width",N.toString())},$=()=>{if(!J)return;J=!1,document.body.style.cursor="",document.body.style.userSelect=""};q.addEventListener("mousedown",Y),document.addEventListener("mousemove",j),document.addEventListener("mouseup",$);let Z=localStorage.getItem("llmd-sidebar-width");if(Z){let V=Number.parseInt(Z,10);if(V>=200&&V<=600)C.style.width=`${V}px`}};if(typeof window<"u")window.addEventListener("DOMContentLoaded",()=>{VC()});window.trackDirectoryOpen=H;window.trackFileView=R;y();z();S();if(document.querySelector(".markdown-body"))u();console.log("[llmd] Client initialized");
|