backpack-viewer 0.7.15 → 0.7.16

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.
@@ -1,4 +1,4 @@
1
- var Jn=Object.defineProperty;var Kn=(t,e,s)=>e in t?Jn(t,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[e]=s;var At=(t,e,s)=>Kn(t,typeof e!="symbol"?e+"":e,s);(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const m of document.querySelectorAll('link[rel="modulepreload"]'))l(m);new MutationObserver(m=>{for(const r of m)if(r.type==="childList")for(const d of r.addedNodes)d.tagName==="LINK"&&d.rel==="modulepreload"&&l(d)}).observe(document,{childList:!0,subtree:!0});function s(m){const r={};return m.integrity&&(r.integrity=m.integrity),m.referrerPolicy&&(r.referrerPolicy=m.referrerPolicy),m.crossOrigin==="use-credentials"?r.credentials="include":m.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function l(m){if(m.ep)return;m.ep=!0;const r=s(m);fetch(m.href,r)}})();const Zn="modulepreload",Qn=function(t){return"/"+t},hn={},eo=function(e,s,l){let m=Promise.resolve();if(s&&s.length>0){let d=function(g){return Promise.all(g.map(i=>Promise.resolve(i).then(c=>({status:"fulfilled",value:c}),c=>({status:"rejected",reason:c}))))};document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),n=(o==null?void 0:o.nonce)||(o==null?void 0:o.getAttribute("nonce"));m=d(s.map(g=>{if(g=Qn(g),g in hn)return;hn[g]=!0;const i=g.endsWith(".css"),c=i?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${g}"]${c}`))return;const I=document.createElement("link");if(I.rel=i?"stylesheet":Zn,i||(I.as="script"),I.crossOrigin="",I.href=g,n&&I.setAttribute("nonce",n),document.head.appendChild(I),i)return new Promise((M,x)=>{I.addEventListener("load",M),I.addEventListener("error",()=>x(new Error(`Unable to preload CSS for ${g}`)))})}))}function r(d){const o=new Event("vite:preloadError",{cancelable:!0});if(o.payload=d,window.dispatchEvent(o),!o.defaultPrevented)throw d}return m.then(d=>{for(const o of d||[])o.status==="rejected"&&r(o.reason);return e().catch(r)})};async function vt(){const t=await fetch("/api/ontologies");return t.ok?t.json():[]}async function Pt(t){const e=await fetch(`/api/ontologies/${encodeURIComponent(t)}`);if(!e.ok)throw new Error(`Failed to load ontology: ${t}`);return e.json()}async function to(){const t=await fetch("/api/remotes");return t.ok?t.json():[]}async function no(t){const e=await fetch(`/api/remotes/${encodeURIComponent(t)}`);if(!e.ok)throw new Error(`Failed to load remote graph: ${t}`);return e.json()}async function zt(t,e){if(!(await fetch(`/api/ontologies/${encodeURIComponent(t)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})).ok)throw new Error(`Failed to save ontology: ${t}`)}async function oo(t,e){if(!(await fetch(`/api/ontologies/${encodeURIComponent(t)}/rename`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:e})})).ok)throw new Error(`Failed to rename ontology: ${t}`)}async function so(t){const e=await fetch(`/api/graphs/${encodeURIComponent(t)}/branches`);return e.ok?e.json():[]}async function fn(t,e,s){const l=await fetch(`/api/graphs/${encodeURIComponent(t)}/branches`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:e,from:s})});if(!l.ok){const m=await l.json().catch(()=>({}));throw new Error(m.error||"Failed to create branch")}}async function gn(t,e){const s=await fetch(`/api/graphs/${encodeURIComponent(t)}/branches/switch`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:e})});if(!s.ok){const l=await s.json().catch(()=>({}));throw new Error(l.error||"Failed to switch branch")}}async function ao(t,e){const s=await fetch(`/api/graphs/${encodeURIComponent(t)}/branches/${encodeURIComponent(e)}`,{method:"DELETE"});if(!s.ok){const l=await s.json().catch(()=>({}));throw new Error(l.error||"Failed to delete branch")}}async function co(t){const e=await fetch(`/api/graphs/${encodeURIComponent(t)}/snapshots`);return e.ok?e.json():[]}async function io(t,e){const s=await fetch(`/api/graphs/${encodeURIComponent(t)}/snapshots`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({label:e})});if(!s.ok){const l=await s.json().catch(()=>({}));throw new Error(l.error||"Failed to create snapshot")}}async function lo(t,e){const s=await fetch(`/api/graphs/${encodeURIComponent(t)}/rollback`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({version:e})});if(!s.ok){const l=await s.json().catch(()=>({}));throw new Error(l.error||"Failed to rollback")}}async function ro(t){const e=await fetch(`/api/graphs/${encodeURIComponent(t)}/snippets`);return e.ok?e.json():[]}async function yn(t,e,s,l,m){const r=await fetch(`/api/graphs/${encodeURIComponent(t)}/snippets`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({label:e,description:m,nodeIds:s,edgeIds:l})});if(!r.ok)throw new Error("Failed to save snippet");return(await r.json()).id}async function po(t,e){const s=await fetch(`/api/graphs/${encodeURIComponent(t)}/snippets/${encodeURIComponent(e)}`);if(!s.ok)throw new Error("Snippet not found");return s.json()}async function uo(t,e){if(!(await fetch(`/api/graphs/${encodeURIComponent(t)}/snippets/${encodeURIComponent(e)}`,{method:"DELETE"})).ok)throw new Error("Failed to delete snippet")}const Cn="bp-dialog-overlay";function nn(){var e;(e=document.querySelector(`.${Cn}`))==null||e.remove();const t=document.createElement("div");return t.className=Cn,document.body.appendChild(t),t}function on(t,e){const s=document.createElement("div");s.className="bp-dialog";const l=document.createElement("h4");return l.className="bp-dialog-title",l.textContent=e,s.appendChild(l),t.appendChild(s),t.addEventListener("click",m=>{m.target===t&&t.remove()}),s}function sn(t,e){const s=document.createElement("div");s.className="bp-dialog-buttons";for(const l of e){const m=document.createElement("button");m.className="bp-dialog-btn",l.accent&&m.classList.add("bp-dialog-btn-accent"),l.danger&&m.classList.add("bp-dialog-btn-danger"),m.textContent=l.label,m.addEventListener("click",l.onClick),s.appendChild(m)}t.appendChild(s)}function jn(t,e){return new Promise(s=>{var d;const l=nn(),m=on(l,t),r=document.createElement("p");r.className="bp-dialog-message",r.textContent=e,m.appendChild(r),sn(m,[{label:"Cancel",onClick:()=>{l.remove(),s(!1)}},{label:"Confirm",accent:!0,onClick:()=>{l.remove(),s(!0)}}]),(d=m.querySelector(".bp-dialog-btn-accent"))==null||d.focus()})}function Dt(t,e,s){return new Promise(l=>{const m=nn(),r=on(m,t),d=document.createElement("input");d.type="text",d.className="bp-dialog-input",d.placeholder=e??"",d.value="",r.appendChild(d);const o=()=>{const n=d.value.trim();m.remove(),l(n||null)};d.addEventListener("keydown",n=>{n.key==="Enter"&&o(),n.key==="Escape"&&(m.remove(),l(null))}),sn(r,[{label:"Cancel",onClick:()=>{m.remove(),l(null)}},{label:"OK",accent:!0,onClick:o}]),d.focus(),d.select()})}function mo(){return new Promise(t=>{const e=nn(),s=on(e,"Add Backpack"),l=document.createElement("p");l.className="bp-dialog-message",l.textContent="Enter the absolute path to a directory that should become a backpack. It will be shown in the sidebar using the last segment of the path as its display name.",s.appendChild(l);const m=document.createElement("label");m.className="bp-dialog-label",m.textContent="Path",s.appendChild(m);const r=document.createElement("div");r.className="bp-dialog-path-row",s.appendChild(r);const d=document.createElement("input");d.type="text",d.className="bp-dialog-input bp-dialog-path-input",d.placeholder="/Users/you/OneDrive/work",r.appendChild(d);const o=document.createElement("button");o.type="button",o.className="bp-dialog-btn bp-dialog-browse-btn",o.textContent="Browse...",r.appendChild(o),typeof window.showDirectoryPicker=="function"||(o.disabled=!0,o.title="Browser doesn't support native folder picker — paste the path manually"),o.addEventListener("click",async x=>{x.preventDefault();try{const F=await window.showDirectoryPicker({mode:"read"});g.textContent=`Picked "${F.name}" — paste the absolute path to it below.`,d.focus()}catch{}});const g=document.createElement("div");g.className="bp-dialog-picker-hint",s.appendChild(g);const i=document.createElement("div");i.className="bp-dialog-activate-row";const c=document.createElement("input");c.type="checkbox",c.id="bp-dialog-activate",c.checked=!0;const I=document.createElement("label");I.htmlFor="bp-dialog-activate",I.textContent="Switch to this backpack after registering",i.appendChild(c),i.appendChild(I),s.appendChild(i),d.addEventListener("dragover",x=>{x.preventDefault(),d.classList.add("bp-dialog-drag-over")}),d.addEventListener("dragleave",()=>{d.classList.remove("bp-dialog-drag-over")}),d.addEventListener("drop",x=>{var V,_,X;x.preventDefault(),d.classList.remove("bp-dialog-drag-over");const F=(V=x.dataTransfer)==null?void 0:V.items;if(!F||F.length===0)return;const W=(X=(_=F[0]).webkitGetAsEntry)==null?void 0:X.call(_);W!=null&&W.isDirectory&&(g.textContent=`Dropped "${W.name}" — paste the absolute path to it below.`)});const M=()=>{const x=d.value.trim();x&&(e.remove(),t({path:x,activate:c.checked}))};d.addEventListener("keydown",x=>{x.key==="Enter"&&M(),x.key==="Escape"&&(e.remove(),t(null))}),sn(s,[{label:"Cancel",onClick:()=>{e.remove(),t(null)}},{label:"Register",accent:!0,onClick:M}]),d.focus()})}function kt(t,e=3e3){const s=document.querySelector(".bp-toast");s&&s.remove();const l=document.createElement("div");l.className="bp-toast",l.textContent=t,document.body.appendChild(l),setTimeout(()=>l.classList.add("bp-toast-visible"),10),setTimeout(()=>{l.classList.remove("bp-toast-visible"),setTimeout(()=>l.remove(),300)},e)}const bn="http://www.w3.org/2000/svg";function at(t,e){const s=document.createElementNS(bn,"svg"),l=t.size??16;s.setAttribute("width",String(l)),s.setAttribute("height",String(l)),s.setAttribute("viewBox",t.viewBox??"0 0 24 24"),s.setAttribute("fill","none"),s.setAttribute("stroke","currentColor"),s.setAttribute("stroke-width",String(t.strokeWidth??2)),t.strokeLinecap&&s.setAttribute("stroke-linecap",t.strokeLinecap),t.strokeLinejoin&&s.setAttribute("stroke-linejoin",t.strokeLinejoin),t.className&&s.setAttribute("class",t.className);for(const m of e){const r=document.createElementNS(bn,m.tag);for(const[d,o]of Object.entries(m.attrs))r.setAttribute(d,String(o));s.appendChild(r)}return s}function ho(t){return Array.from(t.childNodes).map(e=>e.cloneNode(!0))}function fo(t,e){t.replaceChildren(...e)}function vn(t){return t>=1e3?`${(t/1e3).toFixed(1)}k tokens`:`${t} tokens`}function xn(t,e){return t*50+e*25+50}function go(t,e){const s=typeof e=="function"?{onSelect:e}:e,l=document.createElement("h2");l.textContent="Backpack Viewer";const m=document.createElement("input");m.type="text",m.placeholder="Filter...",m.id="filter";const r=document.createElement("ul");r.id="ontology-list";const d=document.createElement("h3");d.className="sidebar-section-heading",d.textContent="REMOTE GRAPHS",d.hidden=!0;const o=document.createElement("ul");o.id="remote-list",o.className="remote-list",o.hidden=!0;const n=document.createElement("div");n.className="sidebar-footer";const g=document.createElement("a");g.href="mailto:support@backpackontology.com",g.textContent="support@backpackontology.com";const i=document.createElement("span");i.textContent="Feedback & support";const c=document.createElement("span");c.className="sidebar-version",c.textContent="v0.7.15",n.append(g,i,c);const I=document.createElement("button");I.className="sidebar-collapse-btn",I.title="Toggle sidebar (Tab)",I.appendChild(at({size:14},[{tag:"polyline",attrs:{points:"11 17 6 12 11 7"}},{tag:"polyline",attrs:{points:"18 17 13 12 18 7"}}]));let M=!1;function x(){M=!M,t.classList.toggle("sidebar-collapsed",M),ye.classList.toggle("hidden",!M)}I.addEventListener("click",x);const F=document.createElement("div");F.className="sidebar-heading-row",F.appendChild(l),F.appendChild(I),t.appendChild(F);const W=document.createElement("div");W.className="sidebar-stale-banner",W.hidden=!0,t.appendChild(W);const V=document.createElement("button");V.className="backpack-picker-pill",V.type="button",V.setAttribute("aria-haspopup","listbox"),V.setAttribute("aria-expanded","false");const _=document.createElement("span");_.className="backpack-picker-dot";const X=document.createElement("span");X.className="backpack-picker-name",X.textContent="...";const Y=document.createElement("span");Y.className="backpack-picker-caret",Y.textContent="▾",V.appendChild(_),V.appendChild(X),V.appendChild(Y);const Z=document.createElement("div");Z.className="backpack-picker-dropdown",Z.hidden=!0,Z.setAttribute("role","listbox");const q=document.createElement("div");q.className="backpack-picker-container",q.appendChild(V),q.appendChild(Z),t.appendChild(q);let me=!1;function U(){me=!1,Z.hidden=!0,V.setAttribute("aria-expanded","false")}function pe(){me=!0,Z.hidden=!1,V.setAttribute("aria-expanded","true")}V.addEventListener("click",p=>{p.stopPropagation(),me?U():pe()}),document.addEventListener("click",p=>{q.contains(p.target)||U()});let Ee=[],te=null;function G(){Z.replaceChildren();for(const E of Ee){const u=document.createElement("button");u.className="backpack-picker-item",u.type="button",u.setAttribute("role","option"),E.active&&u.classList.add("active");const b=document.createElement("span");b.className="backpack-picker-item-dot",b.style.setProperty("--backpack-color",E.color);const S=document.createElement("span");S.className="backpack-picker-item-name",S.textContent=E.name;const h=document.createElement("span");h.className="backpack-picker-item-path",h.textContent=E.path,u.appendChild(b),u.appendChild(S),u.appendChild(h),u.addEventListener("click",T=>{T.stopPropagation(),U(),!E.active&&s.onBackpackSwitch&&s.onBackpackSwitch(E.name)}),Z.appendChild(u)}const p=document.createElement("div");p.className="backpack-picker-divider",Z.appendChild(p);const C=document.createElement("button");C.className="backpack-picker-item backpack-picker-add",C.type="button",C.textContent="+ Add new backpack…",C.addEventListener("click",async E=>{if(E.stopPropagation(),U(),!s.onBackpackRegister)return;const u=await mo();u&&s.onBackpackRegister(u.path,u.activate)}),Z.appendChild(C)}const ye=document.createElement("button");ye.className="tools-pane-toggle hidden",ye.title="Show sidebar (Tab)",ye.appendChild(at({size:14},[{tag:"polyline",attrs:{points:"13 7 18 12 13 17"}},{tag:"polyline",attrs:{points:"6 7 11 12 6 17"}}])),ye.addEventListener("click",x),t.appendChild(m),t.appendChild(r),t.appendChild(d),t.appendChild(o),t.appendChild(n);let Ce=[],se=[],ge="";return m.addEventListener("input",()=>{const p=m.value.toLowerCase();for(const C of Ce){const E=C.dataset.name??"";C.style.display=E.includes(p)?"":"none"}for(const C of se){const E=C.dataset.name??"";C.style.display=E.includes(p)?"":"none"}}),{setStaleVersionBanner(p,C){W.replaceChildren();const E=document.createElement("div");E.className="sidebar-stale-banner-title",E.textContent=`Viewer ${p} is out of date`;const u=document.createElement("div");u.className="sidebar-stale-banner-subtitle",u.textContent=`Latest is ${C}. Your version is stuck because of an npx cache.`;const b=document.createElement("pre");b.className="sidebar-stale-banner-hint",b.textContent=`npm cache clean --force
1
+ var Jn=Object.defineProperty;var Kn=(t,e,s)=>e in t?Jn(t,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[e]=s;var At=(t,e,s)=>Kn(t,typeof e!="symbol"?e+"":e,s);(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const m of document.querySelectorAll('link[rel="modulepreload"]'))l(m);new MutationObserver(m=>{for(const r of m)if(r.type==="childList")for(const d of r.addedNodes)d.tagName==="LINK"&&d.rel==="modulepreload"&&l(d)}).observe(document,{childList:!0,subtree:!0});function s(m){const r={};return m.integrity&&(r.integrity=m.integrity),m.referrerPolicy&&(r.referrerPolicy=m.referrerPolicy),m.crossOrigin==="use-credentials"?r.credentials="include":m.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function l(m){if(m.ep)return;m.ep=!0;const r=s(m);fetch(m.href,r)}})();const Zn="modulepreload",Qn=function(t){return"/"+t},hn={},eo=function(e,s,l){let m=Promise.resolve();if(s&&s.length>0){let d=function(g){return Promise.all(g.map(i=>Promise.resolve(i).then(c=>({status:"fulfilled",value:c}),c=>({status:"rejected",reason:c}))))};document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),n=(o==null?void 0:o.nonce)||(o==null?void 0:o.getAttribute("nonce"));m=d(s.map(g=>{if(g=Qn(g),g in hn)return;hn[g]=!0;const i=g.endsWith(".css"),c=i?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${g}"]${c}`))return;const I=document.createElement("link");if(I.rel=i?"stylesheet":Zn,i||(I.as="script"),I.crossOrigin="",I.href=g,n&&I.setAttribute("nonce",n),document.head.appendChild(I),i)return new Promise((M,x)=>{I.addEventListener("load",M),I.addEventListener("error",()=>x(new Error(`Unable to preload CSS for ${g}`)))})}))}function r(d){const o=new Event("vite:preloadError",{cancelable:!0});if(o.payload=d,window.dispatchEvent(o),!o.defaultPrevented)throw d}return m.then(d=>{for(const o of d||[])o.status==="rejected"&&r(o.reason);return e().catch(r)})};async function vt(){const t=await fetch("/api/ontologies");return t.ok?t.json():[]}async function Pt(t){const e=await fetch(`/api/ontologies/${encodeURIComponent(t)}`);if(!e.ok)throw new Error(`Failed to load ontology: ${t}`);return e.json()}async function to(){const t=await fetch("/api/remotes");return t.ok?t.json():[]}async function no(t){const e=await fetch(`/api/remotes/${encodeURIComponent(t)}`);if(!e.ok)throw new Error(`Failed to load remote graph: ${t}`);return e.json()}async function zt(t,e){if(!(await fetch(`/api/ontologies/${encodeURIComponent(t)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})).ok)throw new Error(`Failed to save ontology: ${t}`)}async function oo(t,e){if(!(await fetch(`/api/ontologies/${encodeURIComponent(t)}/rename`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:e})})).ok)throw new Error(`Failed to rename ontology: ${t}`)}async function so(t){const e=await fetch(`/api/graphs/${encodeURIComponent(t)}/branches`);return e.ok?e.json():[]}async function fn(t,e,s){const l=await fetch(`/api/graphs/${encodeURIComponent(t)}/branches`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:e,from:s})});if(!l.ok){const m=await l.json().catch(()=>({}));throw new Error(m.error||"Failed to create branch")}}async function gn(t,e){const s=await fetch(`/api/graphs/${encodeURIComponent(t)}/branches/switch`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:e})});if(!s.ok){const l=await s.json().catch(()=>({}));throw new Error(l.error||"Failed to switch branch")}}async function ao(t,e){const s=await fetch(`/api/graphs/${encodeURIComponent(t)}/branches/${encodeURIComponent(e)}`,{method:"DELETE"});if(!s.ok){const l=await s.json().catch(()=>({}));throw new Error(l.error||"Failed to delete branch")}}async function co(t){const e=await fetch(`/api/graphs/${encodeURIComponent(t)}/snapshots`);return e.ok?e.json():[]}async function io(t,e){const s=await fetch(`/api/graphs/${encodeURIComponent(t)}/snapshots`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({label:e})});if(!s.ok){const l=await s.json().catch(()=>({}));throw new Error(l.error||"Failed to create snapshot")}}async function lo(t,e){const s=await fetch(`/api/graphs/${encodeURIComponent(t)}/rollback`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({version:e})});if(!s.ok){const l=await s.json().catch(()=>({}));throw new Error(l.error||"Failed to rollback")}}async function ro(t){const e=await fetch(`/api/graphs/${encodeURIComponent(t)}/snippets`);return e.ok?e.json():[]}async function yn(t,e,s,l,m){const r=await fetch(`/api/graphs/${encodeURIComponent(t)}/snippets`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({label:e,description:m,nodeIds:s,edgeIds:l})});if(!r.ok)throw new Error("Failed to save snippet");return(await r.json()).id}async function po(t,e){const s=await fetch(`/api/graphs/${encodeURIComponent(t)}/snippets/${encodeURIComponent(e)}`);if(!s.ok)throw new Error("Snippet not found");return s.json()}async function uo(t,e){if(!(await fetch(`/api/graphs/${encodeURIComponent(t)}/snippets/${encodeURIComponent(e)}`,{method:"DELETE"})).ok)throw new Error("Failed to delete snippet")}const Cn="bp-dialog-overlay";function nn(){var e;(e=document.querySelector(`.${Cn}`))==null||e.remove();const t=document.createElement("div");return t.className=Cn,document.body.appendChild(t),t}function on(t,e){const s=document.createElement("div");s.className="bp-dialog";const l=document.createElement("h4");return l.className="bp-dialog-title",l.textContent=e,s.appendChild(l),t.appendChild(s),t.addEventListener("click",m=>{m.target===t&&t.remove()}),s}function sn(t,e){const s=document.createElement("div");s.className="bp-dialog-buttons";for(const l of e){const m=document.createElement("button");m.className="bp-dialog-btn",l.accent&&m.classList.add("bp-dialog-btn-accent"),l.danger&&m.classList.add("bp-dialog-btn-danger"),m.textContent=l.label,m.addEventListener("click",l.onClick),s.appendChild(m)}t.appendChild(s)}function jn(t,e){return new Promise(s=>{var d;const l=nn(),m=on(l,t),r=document.createElement("p");r.className="bp-dialog-message",r.textContent=e,m.appendChild(r),sn(m,[{label:"Cancel",onClick:()=>{l.remove(),s(!1)}},{label:"Confirm",accent:!0,onClick:()=>{l.remove(),s(!0)}}]),(d=m.querySelector(".bp-dialog-btn-accent"))==null||d.focus()})}function Dt(t,e,s){return new Promise(l=>{const m=nn(),r=on(m,t),d=document.createElement("input");d.type="text",d.className="bp-dialog-input",d.placeholder=e??"",d.value="",r.appendChild(d);const o=()=>{const n=d.value.trim();m.remove(),l(n||null)};d.addEventListener("keydown",n=>{n.key==="Enter"&&o(),n.key==="Escape"&&(m.remove(),l(null))}),sn(r,[{label:"Cancel",onClick:()=>{m.remove(),l(null)}},{label:"OK",accent:!0,onClick:o}]),d.focus(),d.select()})}function mo(){return new Promise(t=>{const e=nn(),s=on(e,"Add Backpack"),l=document.createElement("p");l.className="bp-dialog-message",l.textContent="Enter the absolute path to a directory that should become a backpack. It will be shown in the sidebar using the last segment of the path as its display name.",s.appendChild(l);const m=document.createElement("label");m.className="bp-dialog-label",m.textContent="Path",s.appendChild(m);const r=document.createElement("div");r.className="bp-dialog-path-row",s.appendChild(r);const d=document.createElement("input");d.type="text",d.className="bp-dialog-input bp-dialog-path-input",d.placeholder="/Users/you/OneDrive/work",r.appendChild(d);const o=document.createElement("button");o.type="button",o.className="bp-dialog-btn bp-dialog-browse-btn",o.textContent="Browse...",r.appendChild(o),typeof window.showDirectoryPicker=="function"||(o.disabled=!0,o.title="Browser doesn't support native folder picker — paste the path manually"),o.addEventListener("click",async x=>{x.preventDefault();try{const F=await window.showDirectoryPicker({mode:"read"});g.textContent=`Picked "${F.name}" — paste the absolute path to it below.`,d.focus()}catch{}});const g=document.createElement("div");g.className="bp-dialog-picker-hint",s.appendChild(g);const i=document.createElement("div");i.className="bp-dialog-activate-row";const c=document.createElement("input");c.type="checkbox",c.id="bp-dialog-activate",c.checked=!0;const I=document.createElement("label");I.htmlFor="bp-dialog-activate",I.textContent="Switch to this backpack after registering",i.appendChild(c),i.appendChild(I),s.appendChild(i),d.addEventListener("dragover",x=>{x.preventDefault(),d.classList.add("bp-dialog-drag-over")}),d.addEventListener("dragleave",()=>{d.classList.remove("bp-dialog-drag-over")}),d.addEventListener("drop",x=>{var V,_,X;x.preventDefault(),d.classList.remove("bp-dialog-drag-over");const F=(V=x.dataTransfer)==null?void 0:V.items;if(!F||F.length===0)return;const W=(X=(_=F[0]).webkitGetAsEntry)==null?void 0:X.call(_);W!=null&&W.isDirectory&&(g.textContent=`Dropped "${W.name}" — paste the absolute path to it below.`)});const M=()=>{const x=d.value.trim();x&&(e.remove(),t({path:x,activate:c.checked}))};d.addEventListener("keydown",x=>{x.key==="Enter"&&M(),x.key==="Escape"&&(e.remove(),t(null))}),sn(s,[{label:"Cancel",onClick:()=>{e.remove(),t(null)}},{label:"Register",accent:!0,onClick:M}]),d.focus()})}function kt(t,e=3e3){const s=document.querySelector(".bp-toast");s&&s.remove();const l=document.createElement("div");l.className="bp-toast",l.textContent=t,document.body.appendChild(l),setTimeout(()=>l.classList.add("bp-toast-visible"),10),setTimeout(()=>{l.classList.remove("bp-toast-visible"),setTimeout(()=>l.remove(),300)},e)}const bn="http://www.w3.org/2000/svg";function at(t,e){const s=document.createElementNS(bn,"svg"),l=t.size??16;s.setAttribute("width",String(l)),s.setAttribute("height",String(l)),s.setAttribute("viewBox",t.viewBox??"0 0 24 24"),s.setAttribute("fill","none"),s.setAttribute("stroke","currentColor"),s.setAttribute("stroke-width",String(t.strokeWidth??2)),t.strokeLinecap&&s.setAttribute("stroke-linecap",t.strokeLinecap),t.strokeLinejoin&&s.setAttribute("stroke-linejoin",t.strokeLinejoin),t.className&&s.setAttribute("class",t.className);for(const m of e){const r=document.createElementNS(bn,m.tag);for(const[d,o]of Object.entries(m.attrs))r.setAttribute(d,String(o));s.appendChild(r)}return s}function ho(t){return Array.from(t.childNodes).map(e=>e.cloneNode(!0))}function fo(t,e){t.replaceChildren(...e)}function vn(t){return t>=1e3?`${(t/1e3).toFixed(1)}k tokens`:`${t} tokens`}function xn(t,e){return t*50+e*25+50}function go(t,e){const s=typeof e=="function"?{onSelect:e}:e,l=document.createElement("h2");l.textContent="Backpack Viewer";const m=document.createElement("input");m.type="text",m.placeholder="Filter...",m.id="filter";const r=document.createElement("ul");r.id="ontology-list";const d=document.createElement("h3");d.className="sidebar-section-heading",d.textContent="REMOTE GRAPHS",d.hidden=!0;const o=document.createElement("ul");o.id="remote-list",o.className="remote-list",o.hidden=!0;const n=document.createElement("div");n.className="sidebar-footer";const g=document.createElement("a");g.href="mailto:support@backpackontology.com",g.textContent="support@backpackontology.com";const i=document.createElement("span");i.textContent="Feedback & support";const c=document.createElement("span");c.className="sidebar-version",c.textContent="v0.7.16",n.append(g,i,c);const I=document.createElement("button");I.className="sidebar-collapse-btn",I.title="Toggle sidebar (Tab)",I.appendChild(at({size:14},[{tag:"polyline",attrs:{points:"11 17 6 12 11 7"}},{tag:"polyline",attrs:{points:"18 17 13 12 18 7"}}]));let M=!1;function x(){M=!M,t.classList.toggle("sidebar-collapsed",M),ye.classList.toggle("hidden",!M)}I.addEventListener("click",x);const F=document.createElement("div");F.className="sidebar-heading-row",F.appendChild(l),F.appendChild(I),t.appendChild(F);const W=document.createElement("div");W.className="sidebar-stale-banner",W.hidden=!0,t.appendChild(W);const V=document.createElement("button");V.className="backpack-picker-pill",V.type="button",V.setAttribute("aria-haspopup","listbox"),V.setAttribute("aria-expanded","false");const _=document.createElement("span");_.className="backpack-picker-dot";const X=document.createElement("span");X.className="backpack-picker-name",X.textContent="...";const Y=document.createElement("span");Y.className="backpack-picker-caret",Y.textContent="▾",V.appendChild(_),V.appendChild(X),V.appendChild(Y);const Z=document.createElement("div");Z.className="backpack-picker-dropdown",Z.hidden=!0,Z.setAttribute("role","listbox");const q=document.createElement("div");q.className="backpack-picker-container",q.appendChild(V),q.appendChild(Z),t.appendChild(q);let me=!1;function U(){me=!1,Z.hidden=!0,V.setAttribute("aria-expanded","false")}function pe(){me=!0,Z.hidden=!1,V.setAttribute("aria-expanded","true")}V.addEventListener("click",p=>{p.stopPropagation(),me?U():pe()}),document.addEventListener("click",p=>{q.contains(p.target)||U()});let Ee=[],te=null;function G(){Z.replaceChildren();for(const E of Ee){const u=document.createElement("button");u.className="backpack-picker-item",u.type="button",u.setAttribute("role","option"),E.active&&u.classList.add("active");const b=document.createElement("span");b.className="backpack-picker-item-dot",b.style.setProperty("--backpack-color",E.color);const S=document.createElement("span");S.className="backpack-picker-item-name",S.textContent=E.name;const h=document.createElement("span");h.className="backpack-picker-item-path",h.textContent=E.path,u.appendChild(b),u.appendChild(S),u.appendChild(h),u.addEventListener("click",T=>{T.stopPropagation(),U(),!E.active&&s.onBackpackSwitch&&s.onBackpackSwitch(E.name)}),Z.appendChild(u)}const p=document.createElement("div");p.className="backpack-picker-divider",Z.appendChild(p);const C=document.createElement("button");C.className="backpack-picker-item backpack-picker-add",C.type="button",C.textContent="+ Add new backpack…",C.addEventListener("click",async E=>{if(E.stopPropagation(),U(),!s.onBackpackRegister)return;const u=await mo();u&&s.onBackpackRegister(u.path,u.activate)}),Z.appendChild(C)}const ye=document.createElement("button");ye.className="tools-pane-toggle hidden",ye.title="Show sidebar (Tab)",ye.appendChild(at({size:14},[{tag:"polyline",attrs:{points:"13 7 18 12 13 17"}},{tag:"polyline",attrs:{points:"6 7 11 12 6 17"}}])),ye.addEventListener("click",x),t.appendChild(m),t.appendChild(r),t.appendChild(d),t.appendChild(o),t.appendChild(n);let Ce=[],se=[],ge="";return m.addEventListener("input",()=>{const p=m.value.toLowerCase();for(const C of Ce){const E=C.dataset.name??"";C.style.display=E.includes(p)?"":"none"}for(const C of se){const E=C.dataset.name??"";C.style.display=E.includes(p)?"":"none"}}),{setStaleVersionBanner(p,C){W.replaceChildren();const E=document.createElement("div");E.className="sidebar-stale-banner-title",E.textContent=`Viewer ${p} is out of date`;const u=document.createElement("div");u.className="sidebar-stale-banner-subtitle",u.textContent=`Latest is ${C}. Your version is stuck because of an npx cache.`;const b=document.createElement("pre");b.className="sidebar-stale-banner-hint",b.textContent=`npm cache clean --force
2
2
  npx backpack-viewer@latest`,W.appendChild(E),W.appendChild(u),W.appendChild(b),W.hidden=!1},setBackpacks(p){Ee=p.slice();const C=p.find(E=>E.active)??null;te=C,C&&(X.textContent=C.name,_.style.setProperty("--backpack-color",C.color),t.style.setProperty("--backpack-color",C.color)),G()},setActiveBackpack(p){te=p,Ee=Ee.map(C=>({...C,active:C.name===p.name})),Ee.some(C=>C.name===p.name)||Ee.push({...p,active:!0}),X.textContent=p.name,_.style.setProperty("--backpack-color",p.color),t.style.setProperty("--backpack-color",p.color),G()},getActiveBackpack(){return te},setSummaries(p){r.replaceChildren();const C=fetch("/api/locks").then(u=>u.json()).catch(()=>({})),E=fetch("/api/sync-status").then(u=>u.json()).then(u=>new Set(u.synced)).catch(()=>new Set);Ce=p.map(u=>{const b=document.createElement("li");b.className="ontology-item",b.dataset.name=u.name;const S=document.createElement("span");S.className="name",S.textContent=u.name;const h=document.createElement("span");h.className="stats";const T=xn(u.nodeCount,u.edgeCount);h.textContent=`${u.nodeCount} nodes, ${u.edgeCount} edges · ~${vn(T)}`;const w=document.createElement("span");w.className="sidebar-branch",w.dataset.graph=u.name;const N=document.createElement("span");N.className="sidebar-lock-badge",N.dataset.graph=u.name,C.then(y=>{if(!N.isConnected)return;const P=y[u.name];P&&typeof P=="object"&&P.author&&(N.textContent=`editing: ${P.author}`,N.title=`Last activity: ${P.lastActivity??""}`,N.classList.add("active"))});const L=document.createElement("span");if(L.className="sidebar-sync-badge",L.dataset.graph=u.name,E.then(y=>{L.isConnected&&y.has(u.name)&&(L.textContent="synced",L.title="This graph has been synced",L.classList.add("active"))}),b.appendChild(S),b.appendChild(h),b.appendChild(N),b.appendChild(L),b.appendChild(w),s.onRename){const y=document.createElement("button");y.className="sidebar-edit-btn",y.textContent="✎",y.title="Rename";const P=s.onRename;y.addEventListener("click",$=>{$.stopPropagation();const K=document.createElement("input");K.type="text",K.className="sidebar-rename-input",K.value=u.name,S.textContent="",S.appendChild(K),y.style.display="none",K.focus(),K.select();const ae=()=>{const ce=K.value.trim();ce&&ce!==u.name?P(u.name,ce):(S.textContent=u.name,y.style.display="")};K.addEventListener("blur",ae),K.addEventListener("keydown",ce=>{ce.key==="Enter"&&K.blur(),ce.key==="Escape"&&(K.value=u.name,K.blur())})}),b.appendChild(y)}return b.addEventListener("click",()=>s.onSelect(u.name)),r.appendChild(b),b}),ge&&this.setActive(ge)},setActive(p){ge=p;for(const C of Ce)C.classList.toggle("active",C.dataset.name===p);for(const C of se)C.classList.toggle("active",C.dataset.name===p)},setRemotes(p){o.replaceChildren(),se=p.map(E=>{const u=document.createElement("li");u.className="ontology-item ontology-item-remote",u.dataset.name=E.name;const b=document.createElement("div");b.className="remote-name-row";const S=document.createElement("span");S.className="name",S.textContent=E.name;const h=document.createElement("span");h.className="remote-badge",h.textContent=E.pinned?"remote · pinned":"remote",h.title=`Source: ${E.source??E.url}`,b.appendChild(S),b.appendChild(h);const T=document.createElement("span");T.className="stats";const w=xn(E.nodeCount,E.edgeCount);T.textContent=`${E.nodeCount} nodes, ${E.edgeCount} edges · ~${vn(w)}`;const N=document.createElement("span");return N.className="remote-source",N.textContent=E.source??new URL(E.url).hostname,N.title=E.url,u.appendChild(b),u.appendChild(T),u.appendChild(N),u.addEventListener("click",()=>s.onSelect(E.name)),o.appendChild(u),u});const C=p.length>0;d.hidden=!C,o.hidden=!C,ge&&this.setActive(ge)},setActiveBranch(p,C,E){const u=r.querySelectorAll(`.sidebar-branch[data-graph="${p}"]`);for(const b of u){b.textContent=`/ ${C}`,b.title="Click to switch branch",b.style.cursor="pointer";const S=b.cloneNode(!0);b.replaceWith(S),S.addEventListener("click",h=>{h.stopPropagation(),be(p,S,E??[])})}},setSnippets(p,C){var b;const E=Ce.find(S=>S.dataset.name===p);if(!E||((b=E.querySelector(".sidebar-snippets"))==null||b.remove(),C.length===0))return;const u=document.createElement("div");u.className="sidebar-snippets";for(const S of C){const h=document.createElement("div");h.className="sidebar-snippet";const T=document.createElement("span");T.className="sidebar-snippet-label",T.textContent=`◆ ${S.label}`,T.title=`${S.nodeCount} nodes — click to load`;const w=document.createElement("button");w.className="sidebar-snippet-delete",w.textContent="×",w.title="Delete snippet",w.addEventListener("click",N=>{var L;N.stopPropagation(),(L=s.onSnippetDelete)==null||L.call(s,p,S.id)}),h.appendChild(T),h.appendChild(w),h.addEventListener("click",N=>{var L;N.stopPropagation(),(L=s.onSnippetLoad)==null||L.call(s,p,S.id)}),u.appendChild(h)}E.appendChild(u)},toggle:x,expandBtn:ye};function be(p,C,E){const u=t.querySelector(".branch-picker");u&&u.remove();const b=document.createElement("div");b.className="branch-picker";for(const h of E){const T=document.createElement("div");T.className="branch-picker-item",h.active&&T.classList.add("branch-picker-active");const w=document.createElement("span");if(w.textContent=h.name,T.appendChild(w),!h.active&&s.onBranchDelete){const N=document.createElement("button");N.className="branch-picker-delete",N.textContent="×",N.title=`Delete ${h.name}`,N.addEventListener("click",L=>{L.stopPropagation(),jn("Delete branch",`Delete branch "${h.name}"?`).then(y=>{y&&(s.onBranchDelete(p,h.name),b.remove())})}),T.appendChild(N)}h.active||T.addEventListener("click",()=>{var N;(N=s.onBranchSwitch)==null||N.call(s,p,h.name),b.remove()}),b.appendChild(T)}if(s.onBranchCreate){const h=document.createElement("div");h.className="branch-picker-item branch-picker-create",h.textContent="+ New branch",h.addEventListener("click",()=>{Dt("New branch","Branch name").then(T=>{T&&(s.onBranchCreate(p,T),b.remove())})}),b.appendChild(h)}C.after(b);const S=h=>{b.contains(h.target)||(b.remove(),document.removeEventListener("click",S))};setTimeout(()=>document.addEventListener("click",S),0)}}function Zt(t,e,s,l){return{x0:t,y0:e,x1:s,y1:l,cx:0,cy:0,mass:0,children:[null,null,null,null],body:null}}function En(t,e,s){const l=(t.x0+t.x1)/2,m=(t.y0+t.y1)/2;return(e<l?0:1)+(s<m?0:2)}function wn(t,e){const s=(t.x0+t.x1)/2,l=(t.y0+t.y1)/2;switch(e){case 0:return[t.x0,t.y0,s,l];case 1:return[s,t.y0,t.x1,l];case 2:return[t.x0,l,s,t.y1];default:return[s,l,t.x1,t.y1]}}function Qt(t,e){if(t.mass===0&&t.body===null){t.body=e,t.cx=e.x,t.cy=e.y,t.mass=1;return}if(t.body!==null){const m=t.body;t.body=null,m.x===e.x&&m.y===e.y&&(e.x+=(Math.random()-.5)*.1,e.y+=(Math.random()-.5)*.1);const r=En(t,m.x,m.y);if(t.children[r]===null){const[d,o,n,g]=wn(t,r);t.children[r]=Zt(d,o,n,g)}Qt(t.children[r],m)}const s=En(t,e.x,e.y);if(t.children[s]===null){const[m,r,d,o]=wn(t,s);t.children[s]=Zt(m,r,d,o)}Qt(t.children[s],e);const l=t.mass+1;t.cx=(t.cx*t.mass+e.x)/l,t.cy=(t.cy*t.mass+e.y)/l,t.mass=l}function yo(t){if(t.length===0)return null;let e=1/0,s=1/0,l=-1/0,m=-1/0;for(const i of t)i.x<e&&(e=i.x),i.y<s&&(s=i.y),i.x>l&&(l=i.x),i.y>m&&(m=i.y);const r=Math.max(l-e,m-s)*.1+50,d=(e+l)/2,o=(s+m)/2,n=Math.max(l-e,m-s)/2+r,g=Zt(d-n,o-n,d+n,o+n);for(const i of t)Qt(g,i);return g}function Co(t,e,s,l,m,r){zn(t,e,s,l,m,r)}function zn(t,e,s,l,m,r){if(t.mass===0)return;const d=t.cx-e.x,o=t.cy-e.y,n=d*d+o*o;if(t.body!==null){if(t.body!==e){let i=Math.sqrt(n);i<r&&(i=r);const c=l*m/(i*i),I=d/i*c,M=o/i*c;e.vx-=I,e.vy-=M}return}const g=t.x1-t.x0;if(g*g/n<s*s){let i=Math.sqrt(n);i<r&&(i=r);const c=l*t.mass*m/(i*i),I=d/i*c,M=o/i*c;e.vx-=I,e.vy-=M;return}for(let i=0;i<4;i++)t.children[i]!==null&&zn(t.children[i],e,s,l,m,r)}const _n={clusterStrength:.08,spacing:1.5},kn=6e3,bo=12e3,vo=.004,Hn=140,Yn=350,Sn=.9,Nn=.01,xt=30,_t=50;let Ze={..._n};function lt(t){t.clusterStrength!==void 0&&(Ze.clusterStrength=t.clusterStrength),t.spacing!==void 0&&(Ze.spacing=t.spacing)}function wt(){return{...Ze}}function xo(t){if(t<=30)return{..._n};const e=Math.log2(t/30);return{clusterStrength:Math.min(.5,.08+.06*e),spacing:Math.min(15,1.5+1.2*e)}}function Eo(t,e){for(const s of Object.values(t))if(typeof s=="string")return s;return e}function Ln(t,e,s){const l=new Set(e);let m=new Set(e);for(let r=0;r<s;r++){const d=new Set;for(const o of t.edges)m.has(o.sourceId)&&!l.has(o.targetId)&&d.add(o.targetId),m.has(o.targetId)&&!l.has(o.sourceId)&&d.add(o.sourceId);for(const o of d)l.add(o);if(m=d,d.size===0)break}return{nodes:t.nodes.filter(r=>l.has(r.id)),edges:t.edges.filter(r=>l.has(r.sourceId)&&l.has(r.targetId)),metadata:t.metadata}}function Ht(t){const e=new Map,s=[...new Set(t.nodes.map(n=>n.type))],l=Math.sqrt(s.length)*Yn*.6*Math.max(1,Ze.spacing),m=new Map,r=new Map;for(const n of t.nodes)r.set(n.type,(r.get(n.type)??0)+1);const d=t.nodes.map(n=>{const g=s.indexOf(n.type),i=2*Math.PI*g/Math.max(s.length,1),c=Math.cos(i)*l,I=Math.sin(i)*l,M=m.get(n.type)??0;m.set(n.type,M+1);const x=r.get(n.type)??1,F=2*Math.PI*M/x,W=Hn*.6,V={id:n.id,x:c+Math.cos(F)*W,y:I+Math.sin(F)*W,vx:0,vy:0,label:Eo(n.properties,n.id),type:n.type};return e.set(n.id,V),V}),o=t.edges.map(n=>({sourceId:n.sourceId,targetId:n.targetId,type:n.type}));return{nodes:d,edges:o,nodeMap:e}}const wo=.7,ko=80;function So(t,e){const{nodes:s,edges:l,nodeMap:m}=t,r=bo*Ze.spacing;if(s.length>=ko){const o=yo(s);if(o)for(const g of s)Co(o,g,wo,r,e,xt);const n=r-kn;if(n>0){const g=new Map;for(const i of s){let c=g.get(i.type);c||(c=[],g.set(i.type,c)),c.push(i)}for(const i of g.values())for(let c=0;c<i.length;c++)for(let I=c+1;I<i.length;I++){const M=i[c],x=i[I];let F=x.x-M.x,W=x.y-M.y,V=Math.sqrt(F*F+W*W);V<xt&&(V=xt);const _=n*e/(V*V),X=F/V*_,Y=W/V*_;M.vx+=X,M.vy+=Y,x.vx-=X,x.vy-=Y}}}else for(let o=0;o<s.length;o++)for(let n=o+1;n<s.length;n++){const g=s[o],i=s[n];let c=i.x-g.x,I=i.y-g.y,M=Math.sqrt(c*c+I*I);M<xt&&(M=xt);const F=(g.type===i.type?kn:r)*e/(M*M),W=c/M*F,V=I/M*F;g.vx-=W,g.vy-=V,i.vx+=W,i.vy+=V}for(const o of l){const n=m.get(o.sourceId),g=m.get(o.targetId);if(!n||!g)continue;const i=g.x-n.x,c=g.y-n.y,I=Math.sqrt(i*i+c*c);if(I===0)continue;const M=n.type===g.type?Hn*Ze.spacing:Yn*Ze.spacing,x=vo*(I-M)*e,F=i/I*x,W=c/I*x;n.vx+=F,n.vy+=W,g.vx-=F,g.vy-=W}for(const o of s)o.vx-=o.x*Nn*e,o.vy-=o.y*Nn*e;const d=new Map;for(const o of s){const n=d.get(o.type)??{x:0,y:0,count:0};n.x+=o.x,n.y+=o.y,n.count++,d.set(o.type,n)}for(const o of d.values())o.x/=o.count,o.y/=o.count;for(const o of s){const n=d.get(o.type);o.vx+=(n.x-o.x)*Ze.clusterStrength*e,o.vy+=(n.y-o.y)*Ze.clusterStrength*e}for(const o of s){if(o.pinned){o.vx=0,o.vy=0;continue}o.vx*=Sn,o.vy*=Sn;const n=Math.sqrt(o.vx*o.vx+o.vy*o.vy);n>_t&&(o.vx=o.vx/n*_t,o.vy=o.vy/n*_t),o.x+=o.vx,o.y+=o.vy}return e*.995}const In=["#d4a27f","#c17856","#b07a5e","#d4956b","#a67c5a","#cc9e7c","#c4866a","#cb8e6c","#b8956e","#a88a70","#d9b08c","#c4a882","#e8b898","#b5927a","#a8886e","#d1a990"],Mn=new Map;function Ae(t){const e=Mn.get(t);if(e)return e;let s=0;for(let m=0;m<t.length;m++)s=(s<<5)-s+t.charCodeAt(m)|0;const l=In[Math.abs(s)%In.length];return Mn.set(t,l),l}class No{constructor(e){At(this,"cells",new Map);At(this,"cellSize");At(this,"invCell");this.cellSize=e,this.invCell=1/e}key(e,s){const l=e+32768|0,m=s+32768|0;return l*73856093^m*19349663}clear(){this.cells.clear()}insert(e){const s=Math.floor(e.x*this.invCell),l=Math.floor(e.y*this.invCell),m=this.key(s,l),r=this.cells.get(m);r?r.push(e):this.cells.set(m,[e])}rebuild(e){this.cells.clear();for(const s of e)this.insert(s)}query(e,s,l){const m=l*l,r=Math.floor((e-l)*this.invCell),d=Math.floor((e+l)*this.invCell),o=Math.floor((s-l)*this.invCell),n=Math.floor((s+l)*this.invCell);let g=null,i=m;for(let c=r;c<=d;c++)for(let I=o;I<=n;I++){const M=this.cells.get(this.key(c,I));if(M)for(const x of M){const F=x.x-e,W=x.y-s,V=F*F+W*W;V<=i&&(i=V,g=x)}}return g}}const pt=new Map,Lo=2e3;function Io(t,e,s){return`${t}|${e}|${s}`}const Mo=new OffscreenCanvas(1,1),Tn=Mo.getContext("2d");function To(t,e,s){Tn.font=e;const l=Tn.measureText(t),m=Math.ceil(l.width)+2,r=Math.ceil(l.actualBoundingBoxAscent+l.actualBoundingBoxDescent)+4,d=new OffscreenCanvas(m,r),o=d.getContext("2d");return o.font=e,o.fillStyle=s,o.textAlign="left",o.textBaseline="top",o.fillText(t,1,1),{canvas:d,width:m,height:r}}function An(t,e,s,l,m,r,d){const o=Io(e,m,r);let n=pt.get(o);if(!n){if(pt.size>=Lo){const c=pt.keys().next().value;c!==void 0&&pt.delete(c)}n=To(e,m,r),pt.set(o,n)}const g=s-n.width/2,i=d==="top"?l:l-n.height;t.drawImage(n.canvas,g,i)}function Ao(){pt.clear()}function we(t){return getComputedStyle(document.documentElement).getPropertyValue(t).trim()}const Ue=20,Yt=.001,Po={hideBadges:.4,hideLabels:.25,hideEdgeLabels:.35,smallNodes:.2,hideArrows:.15,dotNodes:.1,hullsOnly:.05},Ro={zoomFactor:1.3,zoomMin:.05,zoomMax:10,panAnimationMs:300};function Rt(t,e,s,l,m,r=100){const d=(t-s.x)*s.scale,o=(e-s.y)*s.scale;return d>=-r&&d<=l+r&&o>=-r&&o<=m+r}function Bo(t,e,s,l){const m={...Po,...(l==null?void 0:l.lod)??{}},r={...Ro,...(l==null?void 0:l.navigation)??{}},d={pulseSpeed:.02,...(l==null?void 0:l.walk)??{}},o=t.querySelector("canvas"),n=o.getContext("2d"),g=window.devicePixelRatio||1;let i={x:0,y:0,scale:1},c=null,I=1,M=0,x=new Set,F=null,W=!0,V=!0,_=!0,X=!0,Y="idle",Z=[],q=0,me=0,U=null,pe=new Set;const Ee=5;let te=null,G=null,ye=1,Ce=null,se=null,ge=null,be=!1,p=[],C=0,E=0;const u=400,b=new No(Ue*2);let S=0;function h(){ae(),S||(S=requestAnimationFrame(()=>{S=0,Xe()}))}const T=150;let w=null,N=!1;function L(){if(!w)try{w=new Worker(new URL("/assets/layout-worker-4xak23M6.js",import.meta.url),{type:"module"}),w.onmessage=y,w.onerror=()=>{N=!1,w=null,j()}}catch{return N=!1,null}return w}function y(f){const k=f.data;if(k.type==="tick"&&c){const B=k.positions,D=c.nodes;for(let H=0;H<D.length;H++)D[H].x=B[H*4],D[H].y=B[H*4+1],D[H].vx=B[H*4+2],D[H].vy=B[H*4+3];I=k.alpha,b.rebuild(D),Xe()}k.type==="settled"&&(I=0,be&&p.length>0&&!a&&(a=requestAnimationFrame(v)))}let P=null,$=null,K=!0;function ae(){K=!0}let ce=null,ue=null;const ve=r.panAnimationMs;function $e(){o.width=o.clientWidth*g,o.height=o.clientHeight*g,ae(),h()}const Qe=new ResizeObserver($e);Qe.observe(t),$e();function Re(f,k){return[f/i.scale+i.x,k/i.scale+i.y]}function et(f,k){if(!c)return null;const[B,D]=Re(f,k);return b.query(B,D,Ue)}function ct(){if(!U)return;n.save();const f=Math.min(U.x1,U.x2),k=Math.max(U.x1,U.x2),B=Math.min(U.y1,U.y2),D=Math.max(U.y1,U.y2);n.strokeStyle=we("--accent")||"#d4a27f",n.fillStyle=we("--accent")||"#d4a27f",n.globalAlpha=.12,n.fillRect(f,B,k-f,D-B),n.globalAlpha=.8,n.lineWidth=1/Math.max(i.scale,.5),n.setLineDash([6/Math.max(i.scale,.5),4/Math.max(i.scale,.5)]),n.strokeRect(f,B,k-f,D-B),n.setLineDash([]),n.restore()}function Ot(){if(!c)return;C+=d.pulseSpeed;const f=new Set(p);n.save(),n.setTransform(g,0,0,g,0,0),P&&(n.clearRect(0,0,o.clientWidth,o.clientHeight),n.drawImage(P,0,0,o.clientWidth,o.clientHeight)),n.save(),n.translate(-i.x*i.scale,-i.y*i.scale),n.scale(i.scale,i.scale);const k=we("--canvas-walk-edge")||"#1a1a1a",B=[];for(const z of c.edges){if(!f.has(z.sourceId)||!f.has(z.targetId)||z.sourceId===z.targetId)continue;const O=c.nodeMap.get(z.sourceId),J=c.nodeMap.get(z.targetId);!O||!J||B.push(O.x,O.y,J.x,J.y)}if(B.length>0){n.beginPath();for(let z=0;z<B.length;z+=4)n.moveTo(B[z],B[z+1]),n.lineTo(B[z+2],B[z+3]);n.strokeStyle=k,n.lineWidth=3,n.globalAlpha=.5+.5*Math.sin(C),n.stroke(),n.globalAlpha=1}const D=i.scale<m.smallNodes?Ue*.5:Ue,H=we("--accent")||"#d4a27f";for(const z of p){const O=c.nodeMap.get(z);if(!O||!Rt(O.x,O.y,i,o.clientWidth,o.clientHeight))continue;const J=z===p[p.length-1],Q=.5+.5*Math.sin(C);n.strokeStyle=H,n.lineWidth=J?3:2,n.globalAlpha=J?.5+.5*Q:.3+.4*Q,n.beginPath(),n.arc(O.x,O.y,D+(J?6:4),0,Math.PI*2),n.stroke()}n.globalAlpha=1,ct(),n.restore(),X&&c.nodes.length>1&&Wt(),n.restore()}function Xe(){var ln;if(!c){n.clearRect(0,0,o.width,o.height);return}if(!K&&P&&be&&p.length>0&&I<Yt){Ot();return}const f=I<Yt&&be&&p.length>0;be&&p.length>0&&(C+=d.pulseSpeed);const k=be&&!f?new Set(p):null,B=we("--canvas-edge"),D=we("--canvas-edge-highlight"),H=we("--canvas-edge-dim"),z=we("--canvas-edge-label"),O=we("--canvas-edge-label-highlight"),J=we("--canvas-edge-label-dim"),Q=we("--canvas-arrow"),re=we("--canvas-arrow-highlight"),fe=we("--canvas-node-label"),ke=we("--canvas-node-label-dim"),Se=we("--canvas-type-badge"),Te=we("--canvas-type-badge-dim"),Be=we("--canvas-selection-border"),je=we("--canvas-node-border");if(n.save(),n.setTransform(g,0,0,g,0,0),n.clearRect(0,0,o.clientWidth,o.clientHeight),n.save(),n.translate(-i.x*i.scale,-i.y*i.scale),n.scale(i.scale,i.scale),_&&i.scale>=m.smallNodes){const ee=new Map;for(const Pe of c.nodes){if(F!==null&&!F.has(Pe.id))continue;const Oe=ee.get(Pe.type)??[];Oe.push(Pe),ee.set(Pe.type,Oe)}for(const[Pe,Oe]of ee){if(Oe.length<2)continue;const st=Ae(Pe),nt=Ue*2.5;let He=1/0,qe=1/0,Fe=-1/0,Ke=-1/0;for(const We of Oe)We.x<He&&(He=We.x),We.y<qe&&(qe=We.y),We.x>Fe&&(Fe=We.x),We.y>Ke&&(Ke=We.y);n.beginPath();const oe=(Fe-He)/2+nt,Ie=(Ke-qe)/2+nt,Ne=(He+Fe)/2,ze=(qe+Ke)/2;n.ellipse(Ne,ze,oe,Ie,0,0,Math.PI*2),n.fillStyle=st,n.globalAlpha=.05,n.fill(),n.strokeStyle=st,n.globalAlpha=.12,n.lineWidth=1,n.setLineDash([4,4]),n.stroke(),n.setLineDash([]),n.globalAlpha=1}}let Ye=null;if(x.size>0){Ye=new Set;for(const ee of c.edges)x.has(ee.sourceId)&&Ye.add(ee.targetId),x.has(ee.targetId)&&Ye.add(ee.sourceId)}const tt=we("--accent")||"#d4a27f",_e=we("--canvas-walk-edge")||"#1a1a1a",it=i.scale>=m.hideArrows,Mt=V&&i.scale>=m.hideEdgeLabels;if(W){const ee=[],Pe=[],Oe=[],st=[],nt=[],He=[];for(const oe of c.edges){const Ie=c.nodeMap.get(oe.sourceId),Ne=c.nodeMap.get(oe.targetId);if(!Ie||!Ne||!Rt(Ie.x,Ie.y,i,o.clientWidth,o.clientHeight,200)&&!Rt(Ne.x,Ne.y,i,o.clientWidth,o.clientHeight,200))continue;const ze=F===null||F.has(oe.sourceId),We=F===null||F.has(oe.targetId),rn=ze&&We;if(F!==null&&!ze&&!We)continue;const jt=x.size>0&&(x.has(oe.sourceId)||x.has(oe.targetId))||F!==null&&rn,dn=F!==null&&!rn,pn=k!==null&&k.has(oe.sourceId)&&k.has(oe.targetId),un=ge?te==null?void 0:te.edges.find(Tt=>Tt.sourceId===oe.sourceId&&Tt.targetId===oe.targetId||Tt.targetId===oe.sourceId&&Tt.sourceId===oe.targetId):null,mn=!!(ge&&un&&ge.edgeIds.has(un.id));if(oe.sourceId===oe.targetId){St(Ie,oe.type,jt,B,D,z,O);continue}(mn?nt:pn?st:jt?Pe:dn?Oe:ee).push(Ie.x,Ie.y,Ne.x,Ne.y),(it||Mt)&&He.push({sx:Ie.x,sy:Ie.y,tx:Ne.x,ty:Ne.y,type:oe.type,highlighted:jt,edgeDimmed:dn,isPathEdge:mn,isWalkEdge:pn})}const qe=it?1.5:1,Ke=[{lines:ee,color:B,width:qe,alpha:1},{lines:Oe,color:H,width:qe,alpha:1},{lines:Pe,color:D,width:it?2.5:1,alpha:1},{lines:nt,color:tt,width:3,alpha:1},{lines:st,color:_e,width:3,alpha:.5+.5*Math.sin(C)}];for(const oe of Ke)if(oe.lines.length!==0){n.beginPath();for(let Ie=0;Ie<oe.lines.length;Ie+=4)n.moveTo(oe.lines[Ie],oe.lines[Ie+1]),n.lineTo(oe.lines[Ie+2],oe.lines[Ie+3]);n.strokeStyle=oe.color,n.lineWidth=oe.width,n.globalAlpha=oe.alpha,n.stroke()}n.globalAlpha=1;for(const oe of He)if(it&&ut(oe.sx,oe.sy,oe.tx,oe.ty,oe.highlighted||oe.isPathEdge,Q,re),Mt){const Ie=(oe.sx+oe.tx)/2,Ne=(oe.sy+oe.ty)/2;n.fillStyle=oe.highlighted?O:oe.edgeDimmed?J:z,n.font="9px system-ui, sans-serif",n.textAlign="center",n.textBaseline="bottom",n.fillText(oe.type,Ie,Ne-4)}}const Ut=performance.now()-E,Le=Math.min(1,Ut/u),Ve=1-(1-Le)*(1-Le),Je=Le<1,cn=i.scale<m.hullsOnly,Vn=!cn&&i.scale<m.dotNodes;if(!cn)for(const ee of c.nodes){if(!Rt(ee.x,ee.y,i,o.clientWidth,o.clientHeight))continue;const Pe=Ae(ee.type);if(Vn){const Ne=F!==null&&!F.has(ee.id);n.fillStyle=Pe;const ze=Ne?.1:.8;n.globalAlpha=Je?ze*Ve:ze,n.fillRect(ee.x-2,ee.y-2,4,4);continue}const Oe=x.has(ee.id),st=Ye!==null&&Ye.has(ee.id),nt=F!==null&&!F.has(ee.id),He=nt||x.size>0&&!Oe&&!st,qe=i.scale<m.smallNodes?Ue*.5:Ue,Fe=Je?qe*Ve:qe;if(k!=null&&k.has(ee.id)){const Ne=p[p.length-1]===ee.id,ze=.5+.5*Math.sin(C),We=we("--accent")||"#d4a27f";n.save(),n.strokeStyle=We,n.lineWidth=Ne?3:2,n.globalAlpha=Ne?.5+.5*ze:.3+.4*ze,n.beginPath(),n.arc(ee.x,ee.y,Fe+(Ne?6:4),0,Math.PI*2),n.stroke(),n.restore()}Oe&&(n.save(),n.shadowColor=Pe,n.shadowBlur=20,n.beginPath(),n.arc(ee.x,ee.y,Fe+3,0,Math.PI*2),n.fillStyle=Pe,n.globalAlpha=.3,n.fill(),n.restore()),n.beginPath(),n.arc(ee.x,ee.y,Fe,0,Math.PI*2),n.fillStyle=Pe;const Ke=nt?.1:He?.3:1;n.globalAlpha=Je?Ke*Ve:Ke,n.fill(),n.strokeStyle=Oe?Be:je,n.lineWidth=Oe?3:1.5,n.stroke(),n.globalAlpha=1,ee.pinned&&(n.save(),n.strokeStyle=je,n.globalAlpha=.55,n.lineWidth=1,n.setLineDash([3,3]),n.beginPath(),n.arc(ee.x,ee.y,Fe+4,0,Math.PI*2),n.stroke(),n.setLineDash([]),n.restore()),ge&&ge.nodeIds.has(ee.id)&&!Oe&&(n.save(),n.shadowColor=we("--accent")||"#d4a27f",n.shadowBlur=15,n.beginPath(),n.arc(ee.x,ee.y,Fe+2,0,Math.PI*2),n.strokeStyle=we("--accent")||"#d4a27f",n.globalAlpha=.5,n.lineWidth=2,n.stroke(),n.restore());const oe=te==null?void 0:te.nodes.find(Ne=>Ne.id===ee.id);if(((ln=oe==null?void 0:oe.properties)==null?void 0:ln._starred)===!0&&(n.fillStyle="#ffd700",n.font="10px system-ui, sans-serif",n.textAlign="left",n.textBaseline="bottom",n.fillText("★",ee.x+Fe-2,ee.y-Fe+2)),i.scale>=m.hideLabels){const Ne=ee.label.length>24?ee.label.slice(0,22)+"...":ee.label,ze=He?ke:fe;An(n,Ne,ee.x,ee.y+Fe+4,"11px system-ui, sans-serif",ze,"top")}if(i.scale>=m.hideBadges){const Ne=He?Te:Se;An(n,ee.type,ee.x,ee.y-Fe-3,"9px system-ui, sans-serif",Ne,"bottom")}n.globalAlpha=1}if(n.restore(),n.restore(),f){const ee=o.width,Pe=o.height;(!P||P.width!==ee||P.height!==Pe)&&(P=new OffscreenCanvas(ee,Pe),$=P.getContext("2d")),$&&($.clearRect(0,0,ee,Pe),$.drawImage(o,0,0),K=!1),Ot();return}X&&c.nodes.length>1&&Wt(),U&&(n.save(),n.setTransform(g,0,0,g,0,0),n.translate(-i.x*i.scale,-i.y*i.scale),n.scale(i.scale,i.scale),ct(),n.restore())}function Wt(){if(!c)return;const f=140,k=100,B=8,D=o.clientWidth-f-16,H=o.clientHeight-k-16;let z=1/0,O=1/0,J=-1/0,Q=-1/0;for(const Le of c.nodes)Le.x<z&&(z=Le.x),Le.y<O&&(O=Le.y),Le.x>J&&(J=Le.x),Le.y>Q&&(Q=Le.y);const re=J-z||1,fe=Q-O||1,ke=Math.min((f-B*2)/re,(k-B*2)/fe),Se=D+B+(f-B*2-re*ke)/2,Te=H+B+(k-B*2-fe*ke)/2;n.save(),n.setTransform(g,0,0,g,0,0),n.fillStyle=we("--bg-surface")||"#1a1a1a",n.globalAlpha=.85,n.beginPath(),n.roundRect(D,H,f,k,8),n.fill(),n.strokeStyle=we("--border")||"#2a2a2a",n.globalAlpha=1,n.lineWidth=1,n.stroke(),n.globalAlpha=.15,n.strokeStyle=we("--canvas-edge")||"#555",n.lineWidth=.5;for(const Le of c.edges){const Ve=c.nodeMap.get(Le.sourceId),Je=c.nodeMap.get(Le.targetId);!Ve||!Je||Le.sourceId===Le.targetId||(n.beginPath(),n.moveTo(Se+(Ve.x-z)*ke,Te+(Ve.y-O)*ke),n.lineTo(Se+(Je.x-z)*ke,Te+(Je.y-O)*ke),n.stroke())}n.globalAlpha=.8;for(const Le of c.nodes){const Ve=Se+(Le.x-z)*ke,Je=Te+(Le.y-O)*ke;n.beginPath(),n.arc(Ve,Je,2,0,Math.PI*2),n.fillStyle=Ae(Le.type),n.fill()}const Be=i.x,je=i.y,Ye=i.x+o.clientWidth/i.scale,tt=i.y+o.clientHeight/i.scale,_e=Se+(Be-z)*ke,it=Te+(je-O)*ke,Mt=(Ye-Be)*ke,Ut=(tt-je)*ke;n.globalAlpha=.3,n.strokeStyle=we("--accent")||"#d4a27f",n.lineWidth=1.5,n.strokeRect(Math.max(D,Math.min(_e,D+f)),Math.max(H,Math.min(it,H+k)),Math.min(Mt,f),Math.min(Ut,k)),n.globalAlpha=1,n.restore()}function ut(f,k,B,D,H,z,O){const J=Math.atan2(D-k,B-f),Q=B-Math.cos(J)*Ue,re=D-Math.sin(J)*Ue,fe=8;n.beginPath(),n.moveTo(Q,re),n.lineTo(Q-fe*Math.cos(J-.4),re-fe*Math.sin(J-.4)),n.lineTo(Q-fe*Math.cos(J+.4),re-fe*Math.sin(J+.4)),n.closePath(),n.fillStyle=H?O:z,n.fill()}function St(f,k,B,D,H,z,O){const J=f.x+Ue+15,Q=f.y-Ue-15;n.beginPath(),n.arc(J,Q,15,0,Math.PI*2),n.strokeStyle=B?H:D,n.lineWidth=B?2.5:1.5,n.stroke(),V&&(n.fillStyle=B?O:z,n.font="9px system-ui, sans-serif",n.textAlign="center",n.fillText(k,J,Q-18))}function mt(){if(!ce||!ue)return;const f=performance.now()-ue.time,k=Math.min(f/ve,1),B=1-Math.pow(1-k,3);i.x=ue.x+(ce.x-ue.x)*B,i.y=ue.y+(ce.y-ue.y)*B,ae(),Xe(),k<1?requestAnimationFrame(mt):(ce=null,ue=null)}let a=0;function v(){if(!be||p.length===0){a=0;return}Xe(),a=requestAnimationFrame(v)}function R(){if(!c||c.nodes.length===0)return;let f=1/0,k=1/0,B=-1/0,D=-1/0;for(const re of c.nodes)re.x<f&&(f=re.x),re.y<k&&(k=re.y),re.x>B&&(B=re.x),re.y>D&&(D=re.y);const H=Ue*4,z=B-f+H*2,O=D-k+H*2,J=o.clientWidth/Math.max(z,1),Q=o.clientHeight/Math.max(O,1);i.scale=Math.min(J,Q,2),i.x=(f+B)/2-o.clientWidth/(2*i.scale),i.y=(k+D)/2-o.clientHeight/(2*i.scale),h()}function j(){if(!c||I<Yt){M=0,be&&p.length>0&&!a&&(a=requestAnimationFrame(v));return}I=So(c,I),b.rebuild(c.nodes),Xe(),M=requestAnimationFrame(j)}let ne=!1,de=0,le=0,he=0,Me=0;o.addEventListener("mousedown",f=>{Y="pending",ne=!1,de=f.clientX,le=f.clientY,he=f.clientX,Me=f.clientY;const k=o.getBoundingClientRect(),B=f.clientX-k.left,D=f.clientY-k.top,H=et(B,D);if(H&&!be){if(Z=[],x.has(H.id)&&x.size>1)for(const J of x){const Q=c==null?void 0:c.nodeMap.get(J);Q&&Z.push({node:Q,startX:Q.x,startY:Q.y})}else Z.push({node:H,startX:H.x,startY:H.y});const[z,O]=Re(B,D);q=z,me=O}else if(!H&&f.shiftKey){const[z,O]=Re(B,D);U={x1:z,y1:O,x2:z,y2:O}}}),o.addEventListener("mousemove",f=>{if(Y==="idle")return;const k=f.clientX-de,B=f.clientY-le,D=Math.abs(f.clientX-he),H=Math.abs(f.clientY-Me);if(Y==="pending"&&(D>Ee||H>Ee)&&(ne=!0,Z.length>0?(Y="nodeDrag",N&&w&&w.postMessage({type:"stop"})):U?Y="rubberBand":Y="pan"),Y==="nodeDrag"){const z=o.getBoundingClientRect(),O=f.clientX-z.left,J=f.clientY-z.top,[Q,re]=Re(O,J),fe=Q-q,ke=re-me;for(const Se of Z)Se.node.x=Se.startX+fe,Se.node.y=Se.startY+ke,Se.node.vx=0,Se.node.vy=0,Se.node.pinned=!0,pe.add(Se.node.id);b.rebuild((c==null?void 0:c.nodes)??[]),h()}else if(Y==="rubberBand"&&U){const z=o.getBoundingClientRect(),O=f.clientX-z.left,J=f.clientY-z.top,[Q,re]=Re(O,J);U.x2=Q,U.y2=re,h()}else Y==="pan"&&(i.x-=k/i.scale,i.y-=B/i.scale,h());de=f.clientX,le=f.clientY}),o.addEventListener("mouseup",f=>{const k=Y==="nodeDrag",B=Y==="rubberBand";if(Z.map(Q=>Q.node.id),k){if(N&&w&&c){const Q=Z.map(re=>({id:re.node.id,x:re.node.x,y:re.node.y}));w.postMessage({type:"pin",updates:Q}),w.postMessage({type:"resume",alpha:.5})}else I=Math.max(I,.5),M||j();Y="idle",Z=[],h();return}if(B&&U&&c){const Q=Math.min(U.x1,U.x2),re=Math.max(U.x1,U.x2),fe=Math.min(U.y1,U.y2),ke=Math.max(U.y1,U.y2);f.shiftKey||x.clear();for(const Te of c.nodes)Te.x>=Q&&Te.x<=re&&Te.y>=fe&&Te.y<=ke&&x.add(Te.id);const Se=[...x];e==null||e(Se.length>0?Se:null),U=null,Y="idle",h();return}if(Y==="pan"){Y="idle";return}if(Y="idle",U=null,ne)return;const D=o.getBoundingClientRect(),H=f.clientX-D.left,z=f.clientY-D.top,O=et(H,z),J=f.ctrlKey||f.metaKey||f.shiftKey;if(be&&G&&O&&c){const Q=p.length>0?p[p.length-1]:G[0],re=new Set([Q]),fe=[{id:Q,path:[Q]}];let ke=null;for(;fe.length>0;){const{id:je,path:Ye}=fe.shift();if(je===O.id){ke=Ye;break}for(const tt of c.edges){let _e=null;tt.sourceId===je?_e=tt.targetId:tt.targetId===je&&(_e=tt.sourceId),_e&&!re.has(_e)&&(re.add(_e),fe.push({id:_e,path:[...Ye,_e]}))}}if(!ke)return;for(const je of ke.slice(1))p.includes(je)||p.push(je);G=[O.id];const Se=Math.max(1,ye);ye=Se;const Te=Ln(te,[O.id],Se);cancelAnimationFrame(M),w&&w.postMessage({type:"stop"}),c=Ht(Te),b.rebuild(c.nodes),I=1,x=new Set([O.id]),F=null,i={x:0,y:0,scale:1},N=Te.nodes.length>=T;const Be=N?L():null;Be?Be.postMessage({type:"start",data:Te}):(N=!1,j()),setTimeout(()=>{c&&R()},300),s==null||s({seedNodeIds:[O.id],hops:Se,totalNodes:Te.nodes.length}),e==null||e([O.id]);return}if(O){J?x.has(O.id)?x.delete(O.id):x.add(O.id):x.size===1&&x.has(O.id)?x.clear():(x.clear(),x.add(O.id));const Q=[...x];e==null||e(Q.length>0?Q:null)}else x.clear(),e==null||e(null);h()}),o.addEventListener("mouseleave",()=>{if(Y==="nodeDrag")if(N&&w&&Z.length>0){const f=Z.map(k=>({id:k.node.id,x:k.node.x,y:k.node.y}));w.postMessage({type:"pin",updates:f}),w.postMessage({type:"resume",alpha:.5})}else I=Math.max(I,.5),M||j();Y==="rubberBand"&&(U=null,h()),Y="idle",Z=[]}),o.addEventListener("wheel",f=>{f.preventDefault();const k=o.getBoundingClientRect(),B=f.clientX-k.left,D=f.clientY-k.top,[H,z]=Re(B,D),O=f.ctrlKey?1-f.deltaY*.01:f.deltaY>0?.9:1.1;i.scale=Math.max(r.zoomMin,Math.min(r.zoomMax,i.scale*O)),i.x=H-B/i.scale,i.y=z-D/i.scale,h()},{passive:!1});let xe=[],Ge=0,Nt=1,ht=0,Lt=0,ft=!1;o.addEventListener("touchstart",f=>{f.preventDefault(),xe=Array.from(f.touches),xe.length===2?(Ge=an(xe[0],xe[1]),Nt=i.scale):xe.length===1&&(de=xe[0].clientX,le=xe[0].clientY,ht=xe[0].clientX,Lt=xe[0].clientY,ft=!1)},{passive:!1}),o.addEventListener("touchmove",f=>{f.preventDefault();const k=Array.from(f.touches);if(k.length===2&&xe.length===2){const D=an(k[0],k[1])/Ge;i.scale=Math.max(r.zoomMin,Math.min(r.zoomMax,Nt*D)),h()}else if(k.length===1){const B=k[0].clientX-de,D=k[0].clientY-le;(Math.abs(k[0].clientX-ht)>10||Math.abs(k[0].clientY-Lt)>10)&&(ft=!0),i.x-=B/i.scale,i.y-=D/i.scale,de=k[0].clientX,le=k[0].clientY,h()}xe=k},{passive:!1}),o.addEventListener("touchend",f=>{if(f.preventDefault(),ft||f.changedTouches.length!==1)return;const k=f.changedTouches[0],B=o.getBoundingClientRect(),D=k.clientX-B.left,H=k.clientY-B.top,z=et(D,H);if(z){x.size===1&&x.has(z.id)?x.clear():(x.clear(),x.add(z.id));const O=[...x];e==null||e(O.length>0?O:null)}else x.clear(),e==null||e(null);h()},{passive:!1}),o.addEventListener("gesturestart",f=>f.preventDefault()),o.addEventListener("gesturechange",f=>f.preventDefault());function an(f,k){const B=f.clientX-k.clientX,D=f.clientY-k.clientY;return Math.sqrt(B*B+D*D)}const gt=document.createElement("div");gt.className="zoom-controls";const yt=document.createElement("button");yt.className="zoom-btn",yt.textContent="+",yt.title="Zoom in",yt.addEventListener("click",()=>{const f=o.clientWidth/2,k=o.clientHeight/2,[B,D]=Re(f,k);i.scale=Math.min(r.zoomMax,i.scale*r.zoomFactor),i.x=B-f/i.scale,i.y=D-k/i.scale,h()});const Ct=document.createElement("button");Ct.className="zoom-btn",Ct.textContent="−",Ct.title="Zoom out",Ct.addEventListener("click",()=>{const f=o.clientWidth/2,k=o.clientHeight/2,[B,D]=Re(f,k);i.scale=Math.max(r.zoomMin,i.scale/r.zoomFactor),i.x=B-f/i.scale,i.y=D-k/i.scale,h()});const bt=document.createElement("button");bt.className="zoom-btn",bt.textContent="○",bt.title="Reset zoom",bt.addEventListener("click",()=>{if(c){if(i={x:0,y:0,scale:1},c.nodes.length>0){let f=1/0,k=1/0,B=-1/0,D=-1/0;for(const O of c.nodes)O.x<f&&(f=O.x),O.y<k&&(k=O.y),O.x>B&&(B=O.x),O.y>D&&(D=O.y);const H=(f+B)/2,z=(k+D)/2;i.x=H-o.clientWidth/2,i.y=z-o.clientHeight/2}h()}}),gt.appendChild(yt),gt.appendChild(bt),gt.appendChild(Ct),t.appendChild(gt);const De=document.createElement("div");De.className="node-tooltip",De.style.display="none",t.appendChild(De);let It=null,ot=null;return o.addEventListener("mousemove",f=>{if(Y!=="idle"&&Y!=="pending"){De.style.display!=="none"&&(De.style.display="none",It=null);return}const k=o.getBoundingClientRect(),B=f.clientX-k.left,D=f.clientY-k.top,H=et(B,D),z=(H==null?void 0:H.id)??null;z!==It?(It=z,De.style.display="none",ot&&clearTimeout(ot),ot=null,z&&H&&(ot=setTimeout(()=>{if(!c||!te)return;const O=c.edges.filter(J=>J.sourceId===z||J.targetId===z).length;De.textContent=`${H.label} · ${H.type} · ${O} edge${O!==1?"s":""}`,De.style.left=`${f.clientX-k.left+12}px`,De.style.top=`${f.clientY-k.top-8}px`,De.style.display="block"},200))):z&&De.style.display==="block"&&(De.style.left=`${f.clientX-k.left+12}px`,De.style.top=`${f.clientY-k.top-8}px`)}),o.addEventListener("mouseleave",()=>{De.style.display="none",It=null,ot&&clearTimeout(ot),ot=null}),{loadGraph(f){if(cancelAnimationFrame(M),w&&w.postMessage({type:"stop"}),Ao(),te=f,G=null,Ce=null,se=null,E=performance.now(),c=Ht(f),b.rebuild(c.nodes),I=1,x=new Set,F=null,pe.clear(),Y="idle",Z=[],U=null,i={x:0,y:0,scale:1},c.nodes.length>0){let B=1/0,D=1/0,H=-1/0,z=-1/0;for(const fe of c.nodes)fe.x<B&&(B=fe.x),fe.y<D&&(D=fe.y),fe.x>H&&(H=fe.x),fe.y>z&&(z=fe.y);const O=(B+H)/2,J=(D+z)/2,Q=o.clientWidth,re=o.clientHeight;i.x=O-Q/2,i.y=J-re/2}N=f.nodes.length>=T;const k=N?L():null;k?k.postMessage({type:"start",data:f}):(N=!1,j())},setFilteredNodeIds(f){F=f,h()},releaseAllPins(){if(!c)return!1;let f=!1;for(const k of c.nodes)k.pinned&&(f=!0,k.pinned=!1);return pe.clear(),Y="idle",Z=[],U=null,f&&(N&&w?w.postMessage({type:"unpin",ids:"all"}):(I=Math.max(I,.5),M||j()),h()),f},hasPinnedNodes(){if(!c)return!1;for(const f of c.nodes)if(f.pinned)return!0;return!1},clearSelection(){x.size!==0&&(x.clear(),e==null||e(null),h())},getSelectedNodeIds(){return[...x]},panToNode(f){this.panToNodes([f])},panToNodes(f){if(!c||f.length===0)return;const k=f.map(H=>c.nodeMap.get(H)).filter(Boolean);if(k.length===0)return;x=new Set(f),e==null||e(f);const B=o.clientWidth,D=o.clientHeight;if(k.length===1)ue={x:i.x,y:i.y,time:performance.now()},ce={x:k[0].x-B/(2*i.scale),y:k[0].y-D/(2*i.scale)};else{let H=1/0,z=1/0,O=-1/0,J=-1/0;for(const Be of k)Be.x<H&&(H=Be.x),Be.y<z&&(z=Be.y),Be.x>O&&(O=Be.x),Be.y>J&&(J=Be.y);const Q=Ue*4,re=O-H+Q*2,fe=J-z+Q*2,ke=Math.min(B/re,D/fe,i.scale);i.scale=ke;const Se=(H+O)/2,Te=(z+J)/2;ue={x:i.x,y:i.y,time:performance.now()},ce={x:Se-B/(2*i.scale),y:Te-D/(2*i.scale)}}mt()},setEdges(f){W=f,h()},setEdgeLabels(f){V=f,h()},setTypeHulls(f){_=f,h()},setMinimap(f){X=f,h()},centerView(){R()},panBy(f,k){i.x+=f/i.scale,i.y+=k/i.scale,h()},zoomBy(f){const k=o.clientWidth/2,B=o.clientHeight/2,[D,H]=Re(k,B);i.scale=Math.max(r.zoomMin,Math.min(r.zoomMax,i.scale*f)),i.x=D-k/i.scale,i.y=H-B/i.scale,h()},reheat(){N&&w?w.postMessage({type:"params",params:wt()}):(I=.5,cancelAnimationFrame(M),j())},exportImage(f){if(!c)return"";const k=o.width,B=o.height;if(f==="png"){const O=document.createElement("canvas");O.width=k,O.height=B;const J=O.getContext("2d");return J.fillStyle=we("--bg")||"#141414",J.fillRect(0,0,k,B),J.drawImage(o,0,0),Gn(J,k,B),O.toDataURL("image/png")}const D=o.toDataURL("image/png"),H=Math.max(16,Math.round(k/80)),z=`<svg xmlns="http://www.w3.org/2000/svg" width="${k}" height="${B}">
3
3
  <image href="${D}" width="${k}" height="${B}"/>
4
4
  <text x="${k-20}" y="${B-16}" text-anchor="end" font-family="system-ui, sans-serif" font-size="${H}" fill="#ffffff" opacity="0.4">backpackontology.com</text>
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Backpack Viewer</title>
7
- <script type="module" crossorigin src="/assets/index-DpElI3pz.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-o1FBgY0r.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/assets/index-Cab62Pxr.css">
9
9
  </head>
10
10
  <body>
@@ -1,8 +1,8 @@
1
- const R = "https://app.backpackontology.com";
2
- let g = R, L = `${g}/.well-known/oauth-authorization-server`;
3
- const $ = new Uint8Array([66, 80, 65, 75]), I = 1;
1
+ const P = "https://app.backpackontology.com";
2
+ let g = P, L = `${g}/.well-known/oauth-authorization-server`;
3
+ const R = new Uint8Array([66, 80, 65, 75]), I = 1;
4
4
  let m = null;
5
- async function q(t) {
5
+ async function W(t) {
6
6
  const e = await t.settings.get("relay_url");
7
7
  e && (g = e, L = `${g}/.well-known/oauth-authorization-server`), t.registerTaskbarIcon({
8
8
  label: "Share",
@@ -27,11 +27,11 @@ function B(t) {
27
27
  onClose: () => {
28
28
  m = null;
29
29
  }
30
- })), C(t, s);
30
+ })), w(t, s);
31
31
  }
32
- async function C(t, e) {
32
+ async function w(t, e) {
33
33
  const s = await t.settings.get("relay_token");
34
- e.replaceChildren(), s ? V(t, e, s) : O(t, e);
34
+ e.replaceChildren(), s ? F(t, e, s) : O(t, e);
35
35
  }
36
36
  function O(t, e) {
37
37
  const s = document.createElement("div");
@@ -41,7 +41,7 @@ function O(t, e) {
41
41
  const r = document.createElement("p");
42
42
  r.textContent = "Encrypt your graph and get a shareable link. Recipients open it in their browser — no install needed.", s.appendChild(r);
43
43
  const o = document.createElement("button");
44
- o.className = "share-cta-btn", o.textContent = "Sign in to share", o.addEventListener("click", () => G(t, e)), s.appendChild(o);
44
+ o.className = "share-cta-btn", o.textContent = "Sign in to share", o.addEventListener("click", () => M(t, e)), s.appendChild(o);
45
45
  const a = document.createElement("button");
46
46
  a.className = "share-token-link", a.textContent = "Or paste an API token", a.addEventListener("click", () => D(t, e)), s.appendChild(a);
47
47
  const c = document.createElement("p");
@@ -59,12 +59,12 @@ function D(t, e) {
59
59
  const a = document.createElement("button");
60
60
  a.className = "share-btn-primary", a.textContent = "Save", a.addEventListener("click", async () => {
61
61
  const i = r.value.trim();
62
- i && (await t.settings.set("relay_token", i), C(t, e));
62
+ i && (await t.settings.set("relay_token", i), w(t, e));
63
63
  }), o.appendChild(a);
64
64
  const c = document.createElement("button");
65
- c.className = "share-btn-secondary", c.textContent = "Back", c.addEventListener("click", () => C(t, e)), o.appendChild(c), s.appendChild(o), e.replaceChildren(s);
65
+ c.className = "share-btn-secondary", c.textContent = "Back", c.addEventListener("click", () => w(t, e)), o.appendChild(c), s.appendChild(o), e.replaceChildren(s);
66
66
  }
67
- async function F(t) {
67
+ async function j(t) {
68
68
  try {
69
69
  const e = await fetch(`${g}/api/graphs`, {
70
70
  headers: { Authorization: `Bearer ${t}` }
@@ -77,17 +77,52 @@ async function F(t) {
77
77
  return { graphs: [], error: e.message };
78
78
  }
79
79
  }
80
- async function V(t, e, s) {
80
+ async function F(t, e, s) {
81
81
  const n = t.getGraphName(), r = document.createElement("div");
82
82
  r.className = "share-loading", r.textContent = "Checking account…", e.replaceChildren(r);
83
- const o = await F(s);
83
+ const o = await j(s);
84
84
  if (o.error === "unauthorized") {
85
- await t.settings.remove("relay_token"), C(t, e);
85
+ await t.settings.remove("relay_token"), w(t, e);
86
86
  return;
87
87
  }
88
88
  e.replaceChildren();
89
89
  const a = o.graphs.find((c) => c.name === n);
90
- a ? z(t, e, s, a) : Y(t, e, s);
90
+ a && a.source === "cloud" ? G(t, e, s) : a ? z(t, e, s, a) : Y(t, e, s);
91
+ }
92
+ function G(t, e, s) {
93
+ const n = document.createElement("div");
94
+ n.className = "share-form";
95
+ const r = document.createElement("p");
96
+ r.className = "share-description", r.textContent = "Share this graph with a link. No sync needed — this graph lives in the cloud.", n.appendChild(r);
97
+ const o = document.createElement("button");
98
+ o.className = "share-cta-btn", o.textContent = "Get share link", o.addEventListener("click", async () => {
99
+ o.disabled = !0, o.textContent = "Creating link…";
100
+ try {
101
+ await V(t, e, s);
102
+ } catch (a) {
103
+ o.disabled = !1, o.textContent = "Get share link", N(n), C(n, a.message);
104
+ }
105
+ }), n.appendChild(o), x(t, e, n);
106
+ }
107
+ async function V(t, e, s) {
108
+ const n = t.getGraphName();
109
+ if (!n) throw new Error("No graph loaded");
110
+ const r = await A(s, `${g}/api/graphs/${encodeURIComponent(n)}/share`, {
111
+ method: "POST"
112
+ });
113
+ if (!r.ok) {
114
+ if (r.status === 401)
115
+ throw await t.settings.remove("relay_token"), new Error("Session expired. Please sign in again.");
116
+ let a = `Share failed (${r.status})`;
117
+ try {
118
+ const c = await r.json();
119
+ c.error && (a = c.error);
120
+ } catch {
121
+ }
122
+ throw new Error(a);
123
+ }
124
+ const o = await r.json();
125
+ v(e, o.url, !1, o.expires_at);
91
126
  }
92
127
  function z(t, e, s, n) {
93
128
  const r = document.createElement("div");
@@ -103,9 +138,9 @@ function z(t, e, s, n) {
103
138
  c.className = "share-cta-btn", c.textContent = "Update & Share", c.addEventListener("click", async () => {
104
139
  c.disabled = !0, c.textContent = n.encrypted ? "Encrypting…" : "Syncing…";
105
140
  try {
106
- await A(t, e, s, n.encrypted);
141
+ await T(t, e, s, n.encrypted);
107
142
  } catch (d) {
108
- c.disabled = !1, c.textContent = "Update & Share", N(r), E(r, d.message);
143
+ c.disabled = !1, c.textContent = "Update & Share", N(r), C(r, d.message);
109
144
  }
110
145
  }), r.appendChild(c);
111
146
  const i = document.createElement("a");
@@ -120,21 +155,21 @@ function Y(t, e, s) {
120
155
  o.className = "share-cta-btn", o.textContent = "Sync & Share", o.addEventListener("click", async () => {
121
156
  o.disabled = !0, o.textContent = "Encrypting…";
122
157
  try {
123
- await A(t, e, s, !0);
158
+ await T(t, e, s, !0);
124
159
  } catch (c) {
125
160
  o.disabled = !1, o.textContent = "Sync & Share";
126
161
  const i = c.message;
127
162
  if (i.includes("encrypted") && i.includes("limit")) {
128
- j(t, e, s);
163
+ K(t, e, s);
129
164
  return;
130
165
  }
131
- N(n), E(n, i);
166
+ N(n), C(n, i);
132
167
  }
133
168
  }), n.appendChild(o);
134
169
  const a = document.createElement("p");
135
170
  a.className = "share-trust", a.textContent = "Your first encrypted graph is free. Data is encrypted before upload — we can’t read it.", n.appendChild(a), x(t, e, n);
136
171
  }
137
- function j(t, e, s) {
172
+ function K(t, e, s) {
138
173
  const n = document.createElement("div");
139
174
  n.className = "share-quota";
140
175
  const r = document.createElement("h4");
@@ -161,9 +196,9 @@ function j(t, e, s) {
161
196
  }), h.addEventListener("click", async () => {
162
197
  h.disabled = !0, h.textContent = "Syncing…";
163
198
  try {
164
- await A(t, e, s, !1, "public");
199
+ await T(t, e, s, !1, "public");
165
200
  } catch (f) {
166
- h.disabled = !1, h.textContent = "Share as public graph", N(n), E(n, f.message);
201
+ h.disabled = !1, h.textContent = "Share as public graph", N(n), C(n, f.message);
167
202
  }
168
203
  }), n.appendChild(h), x(t, e, n);
169
204
  }
@@ -172,27 +207,27 @@ function x(t, e, s) {
172
207
  n.className = "share-footer";
173
208
  const r = document.createElement("button");
174
209
  r.className = "share-token-link", r.textContent = "Sign out", r.addEventListener("click", async () => {
175
- await t.settings.remove("relay_token"), C(t, e);
210
+ await t.settings.remove("relay_token"), w(t, e);
176
211
  }), n.appendChild(r), s.appendChild(n), e.replaceChildren(s);
177
212
  }
178
213
  function N(t) {
179
214
  for (const e of t.querySelectorAll(".share-error")) e.remove();
180
215
  }
181
- function E(t, e) {
216
+ function C(t, e) {
182
217
  const s = document.createElement("p");
183
218
  s.className = "share-error", s.textContent = e, t.appendChild(s);
184
219
  }
185
- async function G(t, e) {
220
+ async function M(t, e) {
186
221
  try {
187
- const n = await (await fetch(L)).json(), o = await (await fetch(n.registration_endpoint, { method: "POST" })).json(), a = M(), c = await J(a), i = window.location.origin + "/oauth/callback", d = crypto.randomUUID(), l = new URL(n.authorization_endpoint);
222
+ const n = await (await fetch(L)).json(), o = await (await fetch(n.registration_endpoint, { method: "POST" })).json(), a = q(), c = await Q(a), i = window.location.origin + "/oauth/callback", d = crypto.randomUUID(), l = new URL(n.authorization_endpoint);
188
223
  l.searchParams.set("client_id", o.client_id), l.searchParams.set("redirect_uri", i), l.searchParams.set("response_type", "code"), l.searchParams.set("code_challenge", c), l.searchParams.set("code_challenge_method", "S256"), l.searchParams.set("state", d), l.searchParams.has("scope") || l.searchParams.set("scope", "openid email profile offline_access"), sessionStorage.setItem("share_oauth_state", d), sessionStorage.setItem("share_oauth_token_endpoint", n.token_endpoint), sessionStorage.setItem("share_oauth_client_id", o.client_id), sessionStorage.setItem("share_oauth_code_verifier", a), sessionStorage.setItem("share_oauth_redirect_uri", i);
189
224
  const u = window.open(l.toString(), "backpack-share-auth", "width=500,height=700"), p = async (h) => {
190
- var w;
191
- if (((w = h.data) == null ? void 0 : w.type) !== "backpack-oauth-callback") return;
225
+ var b;
226
+ if (((b = h.data) == null ? void 0 : b.type) !== "backpack-oauth-callback") return;
192
227
  window.removeEventListener("message", p);
193
228
  const { code: f, returnedState: _ } = h.data;
194
229
  if (_ === d) {
195
- H();
230
+ J();
196
231
  try {
197
232
  const y = await (await fetch(n.token_endpoint, {
198
233
  method: "POST",
@@ -200,66 +235,66 @@ async function G(t, e) {
200
235
  body: new URLSearchParams({ grant_type: "authorization_code", code: f, redirect_uri: i, client_id: o.client_id, code_verifier: a }).toString()
201
236
  })).json();
202
237
  if (!y.access_token) {
203
- E(e, "Token exchange failed: no access token returned.");
238
+ C(e, "Token exchange failed: no access token returned.");
204
239
  return;
205
240
  }
206
- await t.settings.set("relay_token", y.access_token), C(t, e);
241
+ await t.settings.set("relay_token", y.access_token), w(t, e);
207
242
  } catch (S) {
208
- E(e, `Token exchange failed: ${S.message}`);
243
+ C(e, `Token exchange failed: ${S.message}`);
209
244
  }
210
245
  }
211
246
  };
212
247
  window.addEventListener("message", p), (!u || u.closed) && (window.location.href = l.toString());
213
248
  } catch (s) {
214
- E(e, `Auth failed: ${s.message}`);
249
+ C(e, `Auth failed: ${s.message}`);
215
250
  }
216
251
  }
217
- async function A(t, e, s, n, r = "private") {
252
+ async function T(t, e, s, n, r = "private") {
218
253
  const o = t.getGraph(), a = t.getGraphName();
219
254
  if (!o || !a) throw new Error("No graph loaded");
220
255
  const c = new TextEncoder().encode(JSON.stringify(o));
221
256
  let i, d, l = "";
222
257
  if (n) {
223
- const y = await import("../index-B8_hkT8R.js"), b = await t.settings.get("keys") || {};
224
- let k = b[a];
225
- k || (k = await y.generateX25519Identity(), b[a] = k, await t.settings.set("keys", b));
226
- const P = await y.identityToRecipient(k), v = new y.Encrypter();
227
- v.addRecipient(P), i = await v.encrypt(c), d = "age-v1", l = btoa(k).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
258
+ const y = await import("../index-B8_hkT8R.js"), E = await t.settings.get("keys") || {};
259
+ let k = E[a];
260
+ k || (k = await y.generateX25519Identity(), E[a] = k, await t.settings.set("keys", E));
261
+ const $ = await y.identityToRecipient(k), U = new y.Encrypter();
262
+ U.addRecipient($), i = await U.encrypt(c), d = "age-v1", l = btoa(k).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
228
263
  } else
229
264
  i = c, d = "plaintext";
230
- const u = await K(a, i, d, o), p = `${g}/api/graphs/${encodeURIComponent(a)}/sync${r === "public" ? "?visibility=public" : ""}`, h = await T(s, p, {
265
+ const u = await H(a, i, d, o), p = `${g}/api/graphs/${encodeURIComponent(a)}/sync${r === "public" ? "?visibility=public" : ""}`, h = await A(s, p, {
231
266
  method: "PUT",
232
267
  headers: { "Content-Type": "application/octet-stream" },
233
268
  body: u
234
269
  });
235
270
  if (!h.ok) {
236
271
  if (h.status === 401)
237
- throw await t.settings.remove("relay_token"), C(t, e), new Error("Session expired. Please sign in again.");
272
+ throw await t.settings.remove("relay_token"), w(t, e), new Error("Session expired. Please sign in again.");
238
273
  let y = `Sync failed (${h.status})`;
239
274
  try {
240
- const b = await h.json();
241
- b.error && (y = b.error);
275
+ const E = await h.json();
276
+ E.error && (y = E.error);
242
277
  } catch {
243
278
  }
244
279
  throw new Error(y);
245
280
  }
246
281
  const f = await t.settings.get("synced") || {};
247
282
  f[a] || (f[a] = !0, await t.settings.set("synced", f));
248
- const _ = await T(s, `${g}/api/graphs/${encodeURIComponent(a)}/share`, {
283
+ const _ = await A(s, `${g}/api/graphs/${encodeURIComponent(a)}/share`, {
249
284
  method: "POST"
250
285
  });
251
286
  if (!_.ok) {
252
- U(e, null, n, void 0);
287
+ v(e, null, n, void 0);
253
288
  return;
254
289
  }
255
- const w = await _.json(), S = l ? `${w.url}#k=${l}` : w.url;
256
- U(e, S, n, w.expires_at);
290
+ const b = await _.json(), S = l ? `${b.url}#k=${l}` : b.url;
291
+ v(e, S, n, b.expires_at);
257
292
  }
258
- async function T(t, e, s = {}) {
293
+ async function A(t, e, s = {}) {
259
294
  const n = new Headers(s.headers);
260
295
  return n.set("Authorization", `Bearer ${t}`), fetch(e, { ...s, headers: n });
261
296
  }
262
- async function K(t, e, s, n) {
297
+ async function H(t, e, s, n) {
263
298
  const r = new Uint8Array(e).buffer, o = await crypto.subtle.digest("SHA-256", r), a = "sha256:" + Array.from(new Uint8Array(o)).map((h) => h.toString(16).padStart(2, "0")).join(""), c = /* @__PURE__ */ new Set();
264
299
  for (const h of n.nodes) c.add(h.type);
265
300
  const i = JSON.stringify({
@@ -275,9 +310,9 @@ async function K(t, e, s, n) {
275
310
  new DataView(l).setUint32(0, d.length, !1);
276
311
  const u = new Uint8Array(9 + d.length + e.length);
277
312
  let p = 0;
278
- return u.set($, p), p += 4, u[p] = I, p += 1, u.set(new Uint8Array(l), p), p += 4, u.set(d, p), p += d.length, u.set(e, p), u;
313
+ return u.set(R, p), p += 4, u[p] = I, p += 1, u.set(new Uint8Array(l), p), p += 4, u.set(d, p), p += d.length, u.set(e, p), u;
279
314
  }
280
- function U(t, e, s, n) {
315
+ function v(t, e, s, n) {
281
316
  const r = document.createElement("div");
282
317
  r.className = "share-success";
283
318
  const o = document.createElement("h4");
@@ -312,17 +347,17 @@ function U(t, e, s, n) {
312
347
  }
313
348
  t.replaceChildren(r);
314
349
  }
315
- function H() {
350
+ function J() {
316
351
  sessionStorage.removeItem("share_oauth_state"), sessionStorage.removeItem("share_oauth_token_endpoint"), sessionStorage.removeItem("share_oauth_client_id"), sessionStorage.removeItem("share_oauth_code_verifier"), sessionStorage.removeItem("share_oauth_redirect_uri");
317
352
  }
318
- function M() {
353
+ function q() {
319
354
  const t = new Uint8Array(32);
320
355
  return crypto.getRandomValues(t), btoa(String.fromCharCode(...t)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
321
356
  }
322
- async function J(t) {
357
+ async function Q(t) {
323
358
  const e = new TextEncoder().encode(t), s = new Uint8Array(e).buffer, n = await crypto.subtle.digest("SHA-256", s);
324
359
  return btoa(String.fromCharCode(...new Uint8Array(n))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
325
360
  }
326
361
  export {
327
- q as activate
362
+ W as activate
328
363
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backpack-viewer",
3
- "version": "0.7.15",
3
+ "version": "0.7.16",
4
4
  "description": "Web-based graph visualizer for backpack-ontology — Canvas 2D, force-directed layout, live reload",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Noah Irzinger",