tecton 0.4.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.
@@ -0,0 +1,3 @@
1
+ // Generated by scripts/build.js from src/report/client/. Do not edit.
2
+ (()=>{var xt="http://www.w3.org/2000/svg",$e=window.matchMedia("(prefers-reduced-motion: reduce)").matches,P=(e,s=document)=>s.querySelector(e),oe=(e,s=document)=>[...s.querySelectorAll(e)];function t(e,s,...a){let o=document.createElement(e);return Gt(o,s),_t(o,a),o}function v(e,s,...a){let o=document.createElementNS(xt,e);return Gt(o,s),_t(o,a),o}function Gt(e,s){if(s)for(let a of Object.keys(s)){let o=s[a];if(!(o==null||o===!1))if(a==="class")e.setAttribute("class",o);else if(a==="text")e.textContent=o;else if(a==="html")e.innerHTML=o;else if(a==="on")for(let n of Object.keys(o))e.addEventListener(n,o[n]);else a==="style"&&typeof o=="object"?Object.assign(e.style,o):a==="dataset"?Object.assign(e.dataset,o):e.setAttribute(a,o===!0?"":o)}}function _t(e,s){for(let a of s.flat(1/0))a==null||a===!1||e.appendChild(typeof a=="string"||typeof a=="number"?document.createTextNode(String(a)):a)}var qt='<rect class="pl" x="6" y="14" width="25" height="12" rx="3"/><rect class="pl-shift" x="33" y="9" width="25" height="12" rx="3"/><rect class="pl" x="25" y="28" width="14" height="30" rx="3"/>',ke={logo:'<circle cx="6" cy="6" r="2.5"/><circle cx="18" cy="6" r="2.5"/><circle cx="12" cy="18" r="2.5"/><path d="M8 7.5l3 8M16 7.5l-3 8M8.5 6h7"/>',overview:'<rect width="7" height="9" x="3" y="3" rx="1"/><rect width="7" height="5" x="14" y="3" rx="1"/><rect width="7" height="9" x="14" y="12" rx="1"/><rect width="7" height="5" x="3" y="16" rx="1"/>',map:'<rect x="16" y="16" width="6" height="6" rx="1"/><rect x="2" y="16" width="6" height="6" rx="1"/><rect x="9" y="2" width="6" height="6" rx="1"/><path d="M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3"/><path d="M12 12V8"/>',shield:'<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/>',compare:'<circle cx="18" cy="18" r="3"/><circle cx="6" cy="6" r="3"/><path d="M13 6h3a2 2 0 0 1 2 2v7"/><path d="M11 18H8a2 2 0 0 1-2-2V9"/>',box:'<path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/>',pkg:'<path d="M16.5 9.4 7.55 4.24"/><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><path d="M3.29 7 12 12l8.71-5"/><path d="M12 22V12"/>',folder:'<path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"/>',search:'<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>',sun:'<circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/>',moon:'<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>',monitor:'<rect width="20" height="14" x="2" y="3" rx="2"/><path d="M8 21h8M12 17v4"/>',x:'<path d="M18 6 6 18M6 6l12 12"/>',plus:'<path d="M5 12h14M12 5v14"/>',minus:'<path d="M5 12h14"/>',fit:'<path d="M8 3H5a2 2 0 0 0-2 2v3M21 8V5a2 2 0 0 0-2-2h-3M16 21h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/>',copy:'<rect width="14" height="14" x="8" y="8" rx="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/>',download:'<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/><path d="M12 15V3"/>',alert:'<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4M12 17h.01"/>',check:'<circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/>',xcircle:'<circle cx="12" cy="12" r="10"/><path d="m15 9-6 6M9 9l6 6"/>',right:'<path d="m9 18 6-6-6-6"/>',arrowRight:'<path d="M5 12h14M12 5l7 7-7 7"/>',file:'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/>',branch:'<path d="M6 3v12"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/>',menu:'<path d="M4 6h16M4 12h16M4 18h16"/>',cycle:'<path d="m17 2 4 4-4 4"/><path d="M3 11v-1a4 4 0 0 1 4-4h14"/><path d="m7 22-4-4 4-4"/><path d="M21 13v1a4 4 0 0 1-4 4H3"/>',image:'<rect width="18" height="18" x="3" y="3" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.09-3.09a2 2 0 0 0-2.82 0L6 21"/>',clock:'<circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/>',link:'<path d="M9 17H7A5 5 0 0 1 7 7h2M15 7h2a5 5 0 1 1 0 10h-2M8 12h8"/>',code:'<path d="m16 18 6-6-6-6M8 6l-6 6 6 6"/>',sparkle:'<path d="M9.94 14.06 2 22M12 2l1.8 5.2L19 9l-5.2 1.8L12 16l-1.8-5.2L5 9l5.2-1.8z"/>',layers:'<path d="m12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z"/><path d="m22 17.65-9.17 4.16a2 2 0 0 1-1.66 0L2 17.65"/><path d="m22 12.65-9.17 4.16a2 2 0 0 1-1.66 0L2 12.65"/>',server:'<rect width="20" height="8" x="2" y="2" rx="2"/><rect width="20" height="8" x="2" y="14" rx="2"/><path d="M6 6h.01M6 18h.01"/>',globe:'<circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/>',users:'<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75"/>',database:'<ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v14a9 3 0 0 0 18 0V5"/><path d="M3 12a9 3 0 0 0 18 0"/>',cloud:'<path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"/>',terminal:'<path d="m4 17 6-6-6-6M12 19h8"/>',mail:'<rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/>',phone:'<rect width="14" height="20" x="5" y="2" rx="2"/><path d="M12 18h.01"/>',filePlus:'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4M9 15h6M12 12v6"/>'};ke.queue='<path d="M22 12h-6l-2 3h-4l-2-3H2"/><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/>';ke.pencil='<path d="M21.17 6.81a2.82 2.82 0 0 0-3.99-3.99L3.84 16.17a2 2 0 0 0-.5.83l-1.32 4.35a.5.5 0 0 0 .62.62l4.35-1.32a2 2 0 0 0 .83-.5z"/>';ke.arrowLeft='<path d="M19 12H5M12 19l-7-7 7-7"/>';function $(e,s){let a=document.createElementNS(xt,"svg");return a.setAttribute("class",`i${s?` ${s}`:""}`),a.setAttribute("viewBox","0 0 24 24"),a.setAttribute("aria-hidden","true"),a.innerHTML=ke[e]||"",a}var Y=e=>e.startsWith("npm:")?e.slice(4):e,ee=(e,s,a)=>`${e.toLocaleString()} ${e===1?s:a||`${s}s`}`,ce=e=>String(e).replace(/[&<>"]/g,s=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"})[s]);function Qt(e){let s=new Date(e).getTime();if(!s)return"";let a=Math.round((Date.now()-s)/6e4);if(a<1)return"just now";if(a<60)return`${a} min ago`;let o=Math.round(a/60);return o<24?`${o} h ago`:new Date(e).toLocaleDateString(void 0,{day:"numeric",month:"short",year:"numeric"})}var It={get(e){try{return localStorage.getItem(`tecton:${e}`)}catch{return null}},set(e,s){try{localStorage.setItem(`tecton:${e}`,s)}catch{}}};var x=JSON.parse(document.getElementById("data").textContent),Z=x.summary,be=Z.violations,M=x.hasBase,Oe=new Map(x.nodes.map(e=>[e.id,e])),Ue=new Map(x.edges.map(e=>[e.id,e])),lt=new Map(x.violations.map(e=>[e.id,e])),Ie={cur:new Map,base:new Map},Yt=(e,s,a)=>{e.has(s)||e.set(s,[]),e.get(s).push(a)};x.violations.forEach(e=>e.edges.forEach(s=>{e.status!=="fixed"&&Yt(Ie.cur,s,e),e.status!=="new"&&Yt(Ie.base,s,e)}));var Ce=M?be.newErrors>0:x.violations.some(e=>e.severity==="error"),Se=x.violations.filter(e=>e.status!=="fixed"),Ot=e=>e.status!=="same"||e.countBase!==e.countCur,Ms=e=>e.status==="added"?"added":e.status==="removed"?"removed":"changed",ze=x.nodes.filter(e=>!e.external),Ee=new Map(x.nodes.map(e=>[e.id,{uses:0,usedBy:0,viol:0}]));x.edges.forEach(e=>{e.status!=="removed"&&(Ee.get(e.from).uses++,Ee.get(e.to).usedBy++)});Se.forEach(e=>{(e.kind==="cycle"?e.members:[e.from]).forEach(a=>{Ee.has(a)&&Ee.get(a).viol++})});var xe=(x.rules||[]).map(e=>{let s=x.violations.filter(n=>n.rule===e.key),a={new:0,existing:0,fixed:0};s.forEach(n=>{a[n.status]++});let o;return a.new?o="new":a.existing?o="existing":a.fixed?o="fixed":o="pass",{...e,viols:s,n:a,state:o}}),Ne=[...ze.filter(e=>e.status!=="same").map(e=>({type:"node",id:e.id,kind:e.status,label:e.id,sub:ee(e.status==="added"?e.filesCur:e.filesBase,"file")})),...x.edges.filter(Ot).map(e=>({type:"edge",id:e.id,kind:Ms(e),label:`${Y(e.from)} \u2192 ${Y(e.to)}`,edge:e,viol:(Ie.cur.get(e.id)||[]).some(s=>s.status==="new")}))],Zt=x.files||{files:[],deps:[]},Kt={s:"same",a:"added",r:"removed"},Fe=Zt.files.map(([e,s,a,o],n)=>({i:n,path:e,module:s,status:Kt[a],edited:!!o,out:[],in:[]})),je=new Map(Fe.map(e=>[e.path,e]));Zt.deps.forEach(([e,s,a,o])=>{let n={from:Fe[e],to:Fe[s],status:Kt[a],line:o};Fe[e].out.push(n),Fe[s].in.push(n)});var Jt=e=>Fe.filter(s=>s.module===e),dt=new Set(x.nodes.filter(e=>e.touched).map(e=>e.id)),Ke=M&&dt.size>0,Ve=e=>e.status==="added"?"added":e.status==="removed"?"removed":e.edited?"edited":"same",Xt={added:0,removed:1,changed:2};Ne.sort((e,s)=>(s.viol?1:0)-(e.viol?1:0)||Xt[e.kind]-Xt[s.kind]||e.label.localeCompare(s.label));var Pe=[{id:"overview",title:"Overview",icon:"overview"},{id:"system",title:"Architecture",icon:"layers"},{id:"map",title:"Dependency map",icon:"map"},{id:"rules",title:"Rule checks",icon:"shield"},{id:"changes",title:"Changes",icon:"compare"},{id:"modules",title:"Modules",icon:"box"}],E={page:"overview",view:M?"diff":"cur",selected:null,focusOnly:!1,touchedOnly:!1};function He(e,s,a){let o=t("div",{class:"tabs",role:"group"}),n=t("span",{class:"ind"});o.appendChild(n);let i=e.map(l=>t("button",{"aria-pressed":String(l.value===s),dataset:{value:l.value},disabled:l.disabled,style:l.disabled?{opacity:".45",cursor:"not-allowed"}:null,on:{click:()=>{l.disabled||(d(l.value),a(l.value))}}},l.label,l.count!=null?t("span",{class:"c",text:l.count}):null));i.forEach(l=>o.appendChild(l));function p(){let l=i.find(c=>c.getAttribute("aria-pressed")==="true");!l||!l.offsetWidth||(n.style.left=`${l.offsetLeft}px`,n.style.width=`${l.offsetWidth}px`)}function d(l){i.forEach(c=>c.setAttribute("aria-pressed",String(c.dataset.value===l))),p()}return o._place=p,o._set=d,o}var et=()=>oe(".tabs").forEach(e=>e._place&&e._place());function de(e,s){return t("span",{class:`badge ${e}`,text:s})}function wt(e){return{new:de("critical","New break"),existing:de("serious","Failing"),fixed:de("good","Fixed"),pass:de("good","Passing")}[e]}function $t(e){return M?e.status==="new"?de(e.severity==="error"?"critical":"warn",e.severity==="error"?"New":"New warning"):e.status==="fixed"?de("good","Fixed"):de("neutral","Already there"):de(e.severity==="error"?"critical":"warn",e.severity==="error"?"Error":"Warning")}function he(e){return{added:de("add","Added"),removed:de("rem","Removed"),changed:de("chg","Changed"),edited:de("acc","Edited"),same:de("neutral","Unchanged")}[e]}function tt(e,s){return t("div",{class:"ev"},e.map(a=>t("div",{class:`ev-row ${s||""}`},t("code",{text:`${a.file}:${a.line}`}),t("span",{class:"to",text:`\u2192 ${a.spec}`}))))}function es(e,s){if($e||s===0){e.textContent=s.toLocaleString();return}let a=performance.now(),o=900,n=i=>{let p=Math.min(1,(i-a)/o);e.textContent=Math.round(s*(1-(1-p)**3)).toLocaleString(),p<1&&requestAnimationFrame(n)};requestAnimationFrame(n)}var Je=P("#tip");function Le(e,s){Je.innerHTML=s,Je.classList.add("show");let a=14,o=Je.getBoundingClientRect(),n=e.clientX+a,i=e.clientY+a;n+o.width>window.innerWidth-8&&(n=e.clientX-o.width-a),i+o.height>window.innerHeight-8&&(i=e.clientY-o.height-a),Je.style.left=`${n}px`,Je.style.top=`${i}px`}function me(){Je.classList.remove("show")}function Es(e){return Math.max(120,Math.round(e.length*7.3)+56)}function ts(e,s){let a=e.map(h=>h.id).sort(),o=h=>h.external?11:(h.filesBase!==h.filesCur?`${h.filesBase} \u2192 ${h.filesCur} files`:`${h.filesCur||h.filesBase||0} files`).length,n=new Map(e.map(h=>[h.id,Math.max(Es((h.label||h.id).replace(/^npm:/,"")),h.filesCur===void 0?0:Math.round(36+o(h)*6.4+16))])),i=new Map(a.map(h=>[h,[]]));for(let h of s)i.get(h.from).push(h);for(let h of i.values())h.sort((T,I)=>T.to<I.to?-1:1);let p=new Map,d=new Set,l=h=>{p.set(h,1);for(let T of i.get(h)){let I=p.get(T.to);I===1?d.add(T.id):I||l(T.to)}p.set(h,2)};for(let h of a)p.get(h)||l(h);let c=s.map(h=>d.has(h.id)?{id:h.id,u:h.to,v:h.from}:{id:h.id,u:h.from,v:h.to}),r=new Map(a.map(h=>[h,[]])),u=new Map(a.map(h=>[h,[]]));for(let h of c)r.get(h.v).push(h.u),u.get(h.u).push(h.v);let m=new Map(a.map(h=>[h,r.get(h).length])),g=[],f=a.filter(h=>m.get(h)===0);for(;f.length;){f.sort();let h=f.shift();g.push(h);for(let T of u.get(h))m.set(T,m.get(T)-1),m.get(T)===0&&f.push(T)}let y=new Map;for(let h of g)y.set(h,Math.max(0,...r.get(h).map(T=>y.get(T)+1)));for(let h of[...g].reverse())r.get(h).length===0&&u.get(h).length&&y.set(h,Math.min(...u.get(h).map(T=>y.get(T)))-1);let D=Math.min(0,...y.values());for(let h of a)y.set(h,y.get(h)-D);let F=new Map(y),ne=new Map,_=[];for(let h of c){let T=[h.u];for(let I=y.get(h.u)+1;I<y.get(h.v);I++){let A=`\0${h.id}#${I}`;F.set(A,I),n.set(A,14),T.push(A)}T.push(h.v),ne.set(h.id,T);for(let I=0;I+1<T.length;I++)_.push([T[I],T[I+1]])}let w=new Map([...F.keys()].map(h=>[h,[]])),z=new Map([...F.keys()].map(h=>[h,[]]));for(let[h,T]of _)z.get(h).push(T),w.get(T).push(h);let b=Math.max(0,...F.values())+1,S=Array.from({length:b},()=>[]),j=new Set,V=[...F.keys()].filter(h=>w.get(h).length===0).sort();for(;V.length;){let h=V.shift();if(!j.has(h)){j.add(h),S[F.get(h)].push(h);for(let T of[...z.get(h)].sort())j.has(T)||V.push(T)}}for(let h of[...F.keys()].sort())j.has(h)||S[F.get(h)].push(h);let ae=h=>{let T=0;for(let I=0;I+1<h.length;I++){let A=new Map(h[I+1].map((k,R)=>[k,R])),N=[];h[I].forEach((k,R)=>z.get(k).forEach(q=>N.push([R,A.get(q)])));for(let k=0;k<N.length;k++)for(let R=k+1;R<N.length;R++)(N[k][0]-N[R][0])*(N[k][1]-N[R][1])<0&&T++}return T},W=(h,T,I,A)=>{let N=new Map(h[A].map((R,q)=>[R,q])),k=new Map(h[T].map((R,q)=>{let pe=I.get(R).filter(ye=>N.has(ye));return[R,pe.length?pe.reduce((ye,De)=>ye+N.get(De),0)/pe.length:q]}));h[T]=[...h[T]].sort((R,q)=>k.get(R)-k.get(q)||h[T].indexOf(R)-h[T].indexOf(q))},X=S.map(h=>[...h]),B=ae(X);for(let h=0;h<16&&B>0;h++){if(h%2===0)for(let I=1;I<b;I++)W(S,I,w,I-1);else for(let I=b-2;I>=0;I--)W(S,I,z,I+1);let T=ae(S);T<B&&(B=T,X=S.map(I=>[...I]))}S=X;let H=new Map;for(let h of S){let T=0;for(let A of h)H.set(A,T+n.get(A)/2),T+=n.get(A)+36;let I=(T-36)/2;for(let A of h)H.set(A,H.get(A)-I)}let te=(h,T)=>{let I=(k,R)=>(n.get(k)+n.get(R))/2+(k.startsWith("\0")||R.startsWith("\0")?10:36),A=h.map(k=>T.get(k));for(let k=1;k<h.length;k++)A[k]=Math.max(A[k],A[k-1]+I(h[k-1],h[k]));let N=h.map(k=>T.get(k));for(let k=h.length-2;k>=0;k--)N[k]=Math.min(N[k],N[k+1]-I(h[k],h[k+1]));h.forEach((k,R)=>H.set(k,(A[R]+N[R])/2));for(let k=1;k<h.length;k++){let R=H.get(h[k-1])+I(h[k-1],h[k]);H.get(h[k])<R&&H.set(h[k],R)}};for(let h=0;h<10;h++){let T=h%2===0?S.map((I,A)=>A):S.map((I,A)=>S.length-1-A);for(let I of T){let A=h%2===0?w:z,N=new Map(S[I].map(k=>{let R=[...A.get(k),...h>5?(A===w?z:w).get(k):[]];return[k,R.length?R.reduce((q,pe)=>q+H.get(pe),0)/R.length:H.get(k)]}));te(S[I],N)}}let we=h=>h*132,G=Math.min(...[...H.entries()].map(([h,T])=>T-n.get(h)/2),0),L={};for(let h of a){let T=n.get(h);L[h]={x:H.get(h)-T/2-G,y:we(y.get(h)),w:T,h:46}}let Q=new Set(s.map(h=>`${h.from}\u2192${h.to}`)),le={};for(let h of s){let T=ne.get(h.id),I=T.map((A,N)=>{let k=H.get(A)-G,R=we(F.get(A));return N===0?[k,R+46]:N===T.length-1?[k,R]:[k,R+46/2]});if(d.has(h.id)&&I.reverse(),Q.has(`${h.to}\u2192${h.from}`)){let A=h.from<h.to?-7:7;I.forEach(N=>{N[0]+=A})}le[h.id]=I.map(([A,N])=>[Math.round(A*10)/10,Math.round(N*10)/10]),T=null}let J=Math.max(0,...Object.values(L).map(h=>h.x+h.w)),ue=Math.max(0,...Object.values(L).map(h=>h.y+h.h));return{pos:L,routes:le,width:J,height:ue,crossings:B}}function se(e){location.hash!==`#${e}`?location.hash=e:st(e)}var ss=!1;function st(e){let s=null;if(e.startsWith("module:")){try{s=decodeURIComponent(e.slice(7))}catch{s=null}let o=s&&Oe.get(s);e=o&&!o.external?"module":"modules"}e!=="module"&&!Pe.some(o=>o.id===e)&&(e="overview"),E.page=e;let a=e==="module"?s:Pe.find(o=>o.id===e).title;oe(".page").forEach(o=>o.classList.toggle("active",o.id===`page-${e}`)),oe(".nav a").forEach(o=>o.classList.toggle("active",o.dataset.page===(e==="module"?"modules":e))),P("#crumb-cur").textContent=e==="module"?`Modules / ${s}`:a,document.title=`${a} \xB7 ${x.project} \xB7 Tecton`,P("#content").scrollTop=0,me(),requestAnimationFrame(et),e==="overview"&&!ss&&(ss=!0,oe("[data-count]",P("#page-overview")).forEach(o=>es(o,Number(o.dataset.count)))),e!=="system"&&_e(),e==="system"&&(C.svg?(oe(".sys-tabs").forEach(o=>o._set&&o._set(E.view)),rt()):ct(),requestAnimationFrame(()=>{C.fitted||(C.fitted=Ge(!1))})),e==="module"&&kt(s),e==="map"&&requestAnimationFrame(()=>{O.fitted||(at(!1),O.fitted=!0),as()})}var re=x.system||{apps:[],stores:[],outside:[],links:[],hasUsers:!1,summary:null},ls={expanded:new Set,sel:null},Qe=[{key:"pages",title:"Pages",icon:"file",mono:!0},{key:"api",title:"Routes & API",icon:"code"},{key:"endpoints",title:"HTTP endpoints",icon:"code"},{key:"jobs",title:"Jobs & scripts",icon:"terminal",mono:!0},{key:"schedules",title:"Schedules",icon:"clock",mono:!0}],Nt=e=>e.kind==="Queue"?"queue":"database",ht=e=>({web:"globe",mobile:"phone",desktop:"monitor",server:"server"})[e.role]||"box",ns=e=>ie(e.status||"same");var pt=new Map(re.apps.map(e=>[e.id,e])),os=e=>e==="users"?"Users":(pt.get(e)||{}).name||e,Pt=new Map([...re.stores,...re.outside].map(e=>[e.id,e]));function Cs(){let e=re.links.filter(a=>a.kind==="app"),s=new Map(re.apps.map(a=>[a.id,["web","mobile","desktop"].includes(a.role)?0:1]));for(let a=0;a<4;a++)e.forEach(o=>{s.has(o.to)&&s.has(o.from)&&s.set(o.to,Math.max(s.get(o.to),s.get(o.from)+1))});return[...re.apps].sort((a,o)=>s.get(a.id)-s.get(o.id)||a.name.localeCompare(o.name))}var is=["var(--accent)","var(--chg)","var(--add)","var(--viol)","var(--warn)"];function Rt(e){let s=re.apps.findIndex(a=>a.id===e);return is[(s<0?0:s)%is.length]}var C={vb:{x:0,y:0,w:100,h:100},drag:null,dragMoved:!1,nodes:new Map,wires:[],model:null,fitted:!1},fe=8,ge=e=>Math.round(e/fe)*fe,qe=(e,s)=>e.length*s,Re=(e,s)=>e.length>s?`${e.slice(0,s-1)}\u2026`:e,Ss=e=>e.every(s=>s.status==="added")?"added":e.every(s=>s.status==="removed")?"removed":"same";function Ls(e){let s={pages:["page","pages"],api:["route","routes"],endpoints:["endpoint","endpoints"],jobs:["job","jobs"],schedules:["schedule","schedules"]};return Qe.map(a=>[a.key,(e.groups[a.key]||[]).filter(o=>o.status!=="removed").length]).filter(([,a])=>a).map(([a,o])=>`${o} ${s[a][o===1?0:1]}`).join(" \xB7 ")}function As(e){if(e.kind==="users")return"uses \xB7 HTTPS";if(e.kind==="app")return e.labels[0]||"HTTP";let s=Pt.get(e.to);return e.kind==="data"?e.labels.length?e.labels.join(" \xB7 "):s&&s.kind==="Queue"?"messages":s&&/SQL|Postgre|MySQL|SQLite|ORM|Prisma|Drizzle/i.test(`${s.name} ${s.via.join(" ")}`)?"reads & writes \xB7 SQL":"reads & writes":s&&s.id.startsWith("svc:")?"API \xB7 SDK":s&&s.id.startsWith("env:")?"HTTPS \xB7 env":"HTTPS"}function Bs(){let e=[],s=re.links.filter(n=>n.kind==="users");s.length&&e.push({id:"users",type:"person",name:"Users",kind:"Person",sub:"Browser & API clients",status:Ss(s),w:168,h:120});for(let n of re.apps){let i=Ls(n)||"No entry points found",p=n.tech.filter(l=>l.toLowerCase()!==n.framework.toLowerCase()).slice(0,4).join(" \xB7 "),d=ge(Math.max(248,64+qe(Re(n.name,26),8),32+qe(i,6.6),32+qe(p,6.3)));e.push({id:n.id,type:"app",name:Re(n.name,26),kind:`Container: ${n.framework}`,sub:i,tech:p,status:n.status||"same",w:d,h:p?128:112,ref:n,color:Rt(n.id)})}for(let n of re.stores){let i=n.kind==="Queue",p=ge(Math.max(i?192:176,44+qe(Re(n.name,24),7.6)));e.push({id:n.id,type:i?"queue":"db",name:Re(n.name,24),kind:i?"Queue":n.kind,sub:Re(n.via.join(", "),30),status:n.status||"same",w:p,h:i?72:104,ref:n})}for(let n of re.outside){let i=(n.hosts||[]).map(l=>typeof l=="string"?l:l.host),p=n.id.startsWith("env:")?`set by ${n.via[0]||"an env var"}`:i.length?Re(i.join(", "),30):n.via.length?Re(n.via.join(", "),30):"",d=ge(Math.max(208,56+qe(Re(n.name,26),7.8),32+qe(p,6.3)));e.push({id:n.id,type:"ext",name:Re(n.name,26),kind:`External \xB7 ${n.kind}`,sub:p,status:n.status||"same",w:d,h:80,ref:n,envOnly:n.id.startsWith("env:")})}let a=new Map(e.map(n=>[n.id,n])),o=re.links.filter(n=>a.has(n.from)&&a.has(n.to)).map(n=>({id:n.id,from:n.from,to:n.to,kind:n.kind,status:n.status||"same",label:As(n),link:n,async:n.kind==="data"&&a.get(n.to).type==="queue"}));return{nodes:e,edges:o,byId:a}}function Ts(e){let p=e.nodes.filter(L=>L.type==="app"),d=e.edges.filter(L=>L.kind==="app"),l=new Map(p.map(L=>[L.id,["web","mobile","desktop"].includes(L.ref.role)?0:1]));for(let L=0;L<4;L++)d.forEach(Q=>{l.has(Q.to)&&l.has(Q.from)&&l.set(Q.to,Math.max(l.get(Q.to),l.get(Q.from)+1))});let c=Math.min(...l.values());p.forEach(L=>l.set(L.id,l.get(L.id)-c));let r=4,u=p.slice().sort((L,Q)=>l.get(L.id)-l.get(Q.id)||L.name.localeCompare(Q.name)),m=[];for(let L=0;L<u.length;L+=r)m.push(u.slice(L,L+r));let g=e.nodes.filter(L=>L.type==="db"||L.type==="queue"),f=L=>L[0]&&L[0].type==="app"?144:64,y=L=>L.reduce((Q,le)=>Q+le.w,0)+f(L)*Math.max(0,L.length-1),D=Math.max(...m.map(y),y(g),320),F=e.byId.has("users"),ne=F?216:0,_=ne+48,w=(L,Q,le)=>{let J=le-y(L)/2,ue=Math.max(...L.map(h=>h.h));return L.forEach(h=>{h.x=ge(J),h.y=ge(Q+(ue-h.h)/2),J+=h.w+f(L)}),ue},z=48+D/2;if(m.forEach(L=>{_+=w(L,_,z)+104}),g.length){let L=Q=>{let le=e.edges.filter(J=>J.to===Q.id).map(J=>e.byId.get(J.from)).filter(J=>J&&J.x!=null);return le.length?le.reduce((J,ue)=>J+ue.x+ue.w/2,0)/le.length:z};g.sort((Q,le)=>L(Q)-L(le)||+(Q.type==="queue")-+(le.type==="queue")||Q.name.localeCompare(le.name)),_+=w(g,_,z)+0}else _-=104;let b=[...p,...g],S=ge(Math.min(...b.map(L=>L.x))-48),j=ge(Math.max(...b.map(L=>L.x+L.w))+48),V=ge(ne),ae=ge(_+48+40),W=b.length?{x:S,y:V,w:j-S,h:ae-V}:null;if(F){let L=e.byId.get("users"),Q=e.edges.filter(J=>J.from==="users").map(J=>e.byId.get(J.to)).filter(J=>J.x!=null),le=Q.length?Q.reduce((J,ue)=>J+ue.x+ue.w/2,0)/Q.length:z;L.x=ge(le-L.w/2),L.y=0}let X=e.nodes.filter(L=>L.type==="ext");if(X.length){let L=A=>{let N=e.edges.filter(k=>k.to===A.id).map(k=>e.byId.get(k.from)).filter(k=>k&&k.y!=null);return N.length?N.reduce((k,R)=>k+R.y+R.h/2,0)/N.length:0};X.sort((A,N)=>L(A)-L(N)||A.ref.kind.localeCompare(N.ref.kind)||A.name.localeCompare(N.name));let Q=40,le=W?W.y:0,J=W?W.h:600,ue=Math.max(4,Math.floor((J+Q)/(80+Q)),Math.min(8,Math.ceil(X.length/2))),h=Math.ceil(X.length/ue),T=Math.max(...X.map(A=>A.w)),I=(W?W.x+W.w:0)+176;for(let A=0;A<h;A++){let N=X.slice(A*ue,(A+1)*ue),k=N.reduce((q,pe)=>q+pe.h,0)+Q*(N.length-1),R=le+Math.max(0,(J-k)/2);N.forEach(q=>{q.x=ge(I+(T-q.w)/2),q.y=ge(R),R+=q.h+Q}),I+=T+96}}let B=e.nodes,H=Math.min(...B.map(L=>L.x),W?W.x:1/0),te=Math.min(...B.map(L=>L.y),W?W.y:1/0),we=Math.max(...B.map(L=>L.x+L.w),W?W.x+W.w:-1/0),G=Math.max(...B.map(L=>L.y+L.h),W?W.y+W.h:-1/0);return{boundary:W,bounds:{x:H,y:te,w:we-H,h:G-te}}}function Is(e,s){let o=s.bounds,n=ge(o.x-120),i=ge(o.y-120),p=Math.ceil((o.w+240)/fe)+1,d=Math.ceil((o.h+240)/fe)+1,l=new Uint8Array(p*d),c=(b,S)=>S*p+b;for(let b of e.nodes){let S=Math.floor((b.x-12-n)/fe)+1,j=Math.ceil((b.x+b.w+12-n)/fe)-1,V=Math.floor((b.y-12-i)/fe)+1,ae=Math.ceil((b.y+b.h+12-i)/fe)-1;for(let W=Math.max(0,V);W<=Math.min(d-1,ae);W++)for(let X=Math.max(0,S);X<=Math.min(p-1,j);X++)l[c(X,W)]=1}let r=new Uint8Array(p*d),u=new Int16Array(p*d),m=new Map(e.nodes.map((b,S)=>[b.id,S+1])),g=[[1,0],[0,1],[-1,0],[0,-1]],f={right:0,bottom:1,left:2,top:3},y=[];for(let b of e.edges){let S=e.byId.get(b.from),j=e.byId.get(b.to),V,ae;j.y>=S.y+S.h+24&&!(j.type==="ext"&&S.type!=="person")?(V="bottom",ae="top"):j.y+j.h+24<=S.y&&j.type!=="ext"?(V="top",ae="bottom"):j.x+j.w/2>=S.x+S.w/2?(V="right",ae="left"):(V="left",ae="right"),b.ss=V,b.ts=ae,y.push({e:b,node:S,side:V,other:j,end:"s"},{e:b,node:j,side:ae,other:S,end:"t"})}let D=new Map;y.forEach(b=>{let S=`${b.node.id}|${b.side}|${b.end}`;D.has(S)||D.set(S,[]),D.get(S).push(b)});for(let b of D.values()){let S=b[0].side==="top"||b[0].side==="bottom";b.sort((B,H)=>(S?B.other.x+B.other.w/2-(H.other.x+H.other.w/2):B.other.y+B.other.h/2-(H.other.y+H.other.h/2))||(B.e.id<H.e.id?-1:1));let j=b[0].node,V=S?j.w:j.h,ae=b[0].end==="s",W=ae?0:Math.min(V*.7,Math.max(0,(b.length-1)*24)),X=ae&&b.length?Math.max(-V*.25,Math.min(V*.25,(b.reduce((B,H)=>B+(S?H.other.x+H.other.w/2:H.other.y+H.other.h/2),0)/b.length-((S?j.x:j.y)+V/2))*.3)):0;b.forEach((B,H)=>{let te=ge((S?j.x:j.y)+V/2+X-W/2+(b.length>1&&W?W*H/(b.length-1):0)),we=B.side==="right"?[j.x+j.w,te]:B.side==="left"?[j.x,te]:B.side==="bottom"?[te,j.y+j.h]:[te,j.y],G=g[f[B.side]],L=[we[0]+G[0]*3*fe,we[1]+G[1]*3*fe];B.e[B.end==="s"?"P0":"P1"]=we,B.e[B.end==="s"?"Q0":"Q1"]=L})}let F=e.edges.slice().sort((b,S)=>Math.abs(b.Q0[0]-b.Q1[0])+Math.abs(b.Q0[1]-b.Q1[1])-(Math.abs(S.Q0[0]-S.Q1[0])+Math.abs(S.Q0[1]-S.Q1[1]))||(b.id<S.id?-1:1)),ne=6;for(let b of F){let S=Math.round((b.Q0[0]-n)/fe),j=Math.round((b.Q0[1]-i)/fe),V=Math.round((b.Q1[0]-n)/fe),ae=Math.round((b.Q1[1]-i)/fe),W=m.get(b.from),X=f[b.ss],B=(f[b.ts]+2)%4,H=p*d*4,te=new Float64Array(H).fill(1/0),we=new Int32Array(H).fill(-1),G=[],L=(I,A)=>{G.push([I,A]);let N=G.length-1;for(;N>0;){let k=N-1>>1;if(G[k][0]<=G[N][0])break;[G[k],G[N]]=[G[N],G[k]],N=k}},Q=()=>{let I=G[0],A=G.pop();if(G.length){G[0]=A;let N=0;for(;;){let k=2*N+1,R=k+1,q=N;if(k<G.length&&G[k][0]<G[q][0]&&(q=k),R<G.length&&G[R][0]<G[q][0]&&(q=R),q===N)break;[G[q],G[N]]=[G[N],G[q]],N=q}}return I},le=(I,A)=>Math.abs(I-V)+Math.abs(A-ae),J=c(S,j)<<2|X;te[J]=0,L(le(S,j),J);let ue=-1,h=0;for(;G.length&&h++<4e5;){let[I,A]=Q(),N=A>>2,k=A&3,R=N%p,q=(N-R)/p;if(R===V&&q===ae){ue=A;break}if(!(I>te[A]+le(R,q)+1e-6))for(let pe=0;pe<4;pe++){if(pe===(k+2)%4)continue;let ye=R+g[pe][0],De=q+g[pe][1];if(ye<0||De<0||ye>=p||De>=d)continue;let it=c(ye,De);if(l[it]&&!(ye===V&&De===ae))continue;let ks=pe%2===0?1:2,zt=u[it]===W,Vt=(zt?.7:1)+(pe!==k?ne:0)+(zt?0:r[it]&ks?4:r[it]?1.5:0);ye===V&&De===ae&&pe!==B&&(Vt+=ne);let bt=it<<2|pe,Tt=te[A]+Vt;Tt<te[bt]&&(te[bt]=Tt,we[bt]=A,L(Tt+le(ye,De),bt))}}let T;if(ue<0)T=[b.P0,b.Q0,[b.Q0[0],b.Q1[1]],b.Q1,b.P1];else{let I=[];for(let N=ue;N>=0;N=we[N])I.push(N);I.reverse();let A=null;for(let N of I){let k=N>>2,R=k%p,q=(k-R)/p;if(A){let pe=R!==A[0]?1:2;for(let ye of[c(R,q),c(A[0],A[1])])r[ye]|=pe,u[ye]||(u[ye]=W)}A=[R,q]}T=[b.P0,...I.map(N=>{let k=N>>2,R=k%p;return[n+R*fe,i+(k-R)/p*fe]}),b.P1]}b.pts=T.filter((I,A)=>A===0||A===T.length-1||!(T[A-1][0]===I[0]&&I[0]===T[A+1][0]||T[A-1][1]===I[1]&&I[1]===T[A+1][1]))}let _=e.nodes.map(b=>({x:b.x-4,y:b.y-4,w:b.w+8,h:b.h+8})),w=[],z=b=>[..._,...w].some(S=>b.x<S.x+S.w&&b.x+b.w>S.x&&b.y<S.y+S.h&&b.y+b.h>S.y);for(let b of F){let S=b.label.length*6.3+18,j=20,V=[];for(let B=0;B<b.pts.length-1;B++){let H=b.pts[B],te=b.pts[B+1];V.push({a:H,c:te,len:Math.abs(H[0]-te[0])+Math.abs(H[1]-te[1])})}let W=[...V.slice().reverse().filter(B=>B.len>=(B.a[1]===B.c[1]?S+16:j+24)),...V.slice().sort((B,H)=>H.len-B.len)],X=null;for(let B of W){for(let H of[.5,.3,.7,.18,.82]){let te=B.a[0]+(B.c[0]-B.a[0])*H,we=B.a[1]+(B.c[1]-B.a[1])*H,G={x:te-S/2,y:we-j/2,w:S,h:j};if(!z(G)){X=G;break}}if(X)break}if(!X&&W.length){let B=W[0];X={x:(B.a[0]+B.c[0])/2-S/2,y:(B.a[1]+B.c[1])/2-j/2,w:S,h:j}}X&&(w.push(X),b.lbl=X)}}function Os(e,s=10){if(e.length<2)return"";let a=`M${e[0][0]},${e[0][1]}`;for(let n=1;n<e.length-1;n++){let[i,p]=e[n-1],[d,l]=e[n],[c,r]=e[n+1],u=Math.min(s,Math.hypot(d-i,l-p)/2,Math.hypot(c-d,r-l)/2),m=d-Math.sign(d-i)*u,g=l-Math.sign(l-p)*u,f=d+Math.sign(c-d)*u,y=l+Math.sign(r-l)*u;a+=` L${m},${g} Q${d},${l} ${f},${y}`}let o=e[e.length-1];return`${a} L${o[0]},${o[1]}`}function Ns(e){let s=v("g",{class:`an t-${e.type}`,transform:`translate(${e.x},${e.y})`,dataset:{node:e.id}}),a=(d,l,c,r=.75)=>v("g",{class:"an-ico",transform:`translate(${l},${c}) scale(${r})`,html:ke[d]}),o=(d,l,c,r,u)=>v("text",{class:d,x:l,y:c,"text-anchor":u||"start"},r),{w:n,h:i}=e;e.type==="person"?s.append(v("rect",{class:"an-shape",x:0,y:40,width:n,height:i-40,rx:26}),v("circle",{class:"an-shape an-head",cx:n/2,cy:24,r:23}),o("an-name",n/2,80,e.name,"middle"),o("an-kind",n/2,96,`[${e.kind}]`,"middle"),o("an-sub",n/2,111,e.sub,"middle")):e.type==="app"?(s.style.setProperty("--app",e.color),s.append(v("rect",{class:"an-shape",width:n,height:i,rx:12}),v("rect",{class:"an-band",width:n,height:5,rx:2.5}),v("rect",{class:"an-ibox",x:16,y:18,width:30,height:30,rx:8}),a(ht(e.ref),22,24),o("an-name",56,32,e.name),o("an-kind",56,47,`[${e.kind}]`),v("line",{class:"an-rule",x1:16,x2:n-16,y1:64,y2:64}),o("an-sub",16,86,e.sub)),e.tech&&s.append(o("an-tech",16,110,e.tech))):e.type==="db"?s.append(v("path",{class:"an-shape",d:`M0,11 A${n/2},11 0 0 1 ${n},11 L${n},${i-11} A${n/2},11 0 0 1 0,${i-11} Z`}),v("ellipse",{class:"an-lid",cx:n/2,cy:11,rx:n/2,ry:11}),a("database",n/2-9,30),o("an-name",n/2,66,e.name,"middle"),o("an-kind",n/2,82,`[${e.kind}]`,"middle")):e.type==="queue"?s.append(v("path",{class:"an-shape",d:`M14,0 L${n-14},0 A14,${i/2} 0 0 1 ${n-14},${i} L14,${i} A14,${i/2} 0 0 1 14,0 Z`}),v("ellipse",{class:"an-lid",cx:n-14,cy:i/2,rx:14,ry:i/2}),a("queue",26,i/2-9),o("an-name",54,i/2-2,e.name),o("an-kind",54,i/2+14,`[${e.kind}${e.sub?` \xB7 ${e.sub}`:""}]`)):(s.append(v("rect",{class:`an-shape${e.envOnly?" env":""}`,width:n,height:i,rx:10}),a({Email:"mail","Web / HTTP":"globe"}[e.ref.kind]||"cloud",16,16),o("an-name",44,29,e.name),o("an-kind",16,52,`[${e.kind}]`)),e.sub&&s.append(o("an-sub mono",16,69,e.sub)));let p=(d,l,c)=>v("g",{class:`an-badge ${d}`,transform:`translate(${n-c-10},-9)`},v("rect",{width:c,height:17,rx:5}),v("text",{x:c/2,y:12,"text-anchor":"middle"},l));if(s.append(p("b-add","NEW",36),p("b-rem","GONE",40)),e.type!=="person"){s.setAttribute("tabindex",0),s.setAttribute("role","button"),s.setAttribute("aria-label",`${e.name}, ${e.kind}`);let d=()=>Ae(e.type==="app"?{type:"app",id:e.id}:{type:"svc",id:e.id});s.addEventListener("click",l=>{C.dragMoved||(l.stopPropagation(),d())}),s.addEventListener("keydown",l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),d())})}return s.addEventListener("pointerenter",()=>{C.drag||ut(e.id)}),s.addEventListener("pointerleave",()=>ut(null)),s.addEventListener("focus",()=>ut(e.id)),s.addEventListener("blur",()=>ut(null)),s}function Ps(e){let s=Bs(),a=Ts(s);Is(s,a),C.model=s,C.layout=a;let o=v("defs");o.innerHTML=[["line","--text-3"],["app","--accent"],["data","--text-2"],["add","--add"],["rem","--rem"],["hl","--accent"]].map(([l,c])=>`<marker id="aw-${l}" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="9" markerHeight="9" orient="auto-start-reverse" markerUnits="userSpaceOnUse"><path d="M1,1.5 L9,5 L1,8.5 Q2.5,5 1,1.5 z" style="fill: var(${c})"/></marker>`).join("")+'<filter id="an-shadow" x="-10%" y="-20%" width="120%" height="150%"><feDropShadow dx="0" dy="1.5" stdDeviation="2" flood-color="#101018" flood-opacity=".07"/></filter><pattern id="aw-dots" width="16" height="16" patternUnits="userSpaceOnUse"><circle cx="1" cy="1" r="1" style="fill: var(--dot)"/></pattern>',e.appendChild(o),e.appendChild(v("rect",{class:"arch-bg",x:-2e4,y:-2e4,width:4e4,height:4e4,fill:"url(#aw-dots)"}));let n=v("g",{id:"arch-world"});if(a.boundary){let l=a.boundary;n.append(v("g",{class:"arch-boundary"},v("rect",{x:l.x,y:l.y,width:l.w,height:l.h,rx:18}),v("g",{class:"an-ico",transform:`translate(${l.x+20},${l.y+l.h-33}) scale(0.7)`,html:ke.layers}),v("text",{class:"ab-name",x:l.x+44,y:l.y+l.h-20},x.project),v("text",{class:"ab-kind",x:l.x+56+qe(x.project,8.6),y:l.y+l.h-20},"[Software system \xB7 this repo]")))}let i=v("g"),p=v("g"),d=v("g");n.append(i,p,d),C.wires=[];for(let l of s.edges){let c=Os(l.pts),r=v("path",{class:"wl",d:c}),u=v("g",{class:`aw k-${l.kind}${l.async?" async":""}`,dataset:{wire:l.id}},r,v("path",{class:"whit",d:c}));if(!$e&&(l.kind==="app"||l.status==="added")){let f=v("circle",{class:"wdot",r:2.6}),y=v("animateMotion",{dur:`${Math.max(2,l.pts.reduce((D,F,ne)=>ne?D+Math.abs(F[0]-l.pts[ne-1][0])+Math.abs(F[1]-l.pts[ne-1][1]):0,0)/90).toFixed(2)}s`,repeatCount:"indefinite",path:c});f.appendChild(y),u.appendChild(f)}let m=null;l.lbl&&(m=v("g",{class:`aw-lbl k-${l.kind}`},v("rect",{x:l.lbl.x,y:l.lbl.y,width:l.lbl.w,height:l.lbl.h,rx:10}),v("text",{x:l.lbl.x+l.lbl.w/2,y:l.lbl.y+l.lbl.h/2+.5,"text-anchor":"middle","dominant-baseline":"central"},l.label)),d.appendChild(m));let g=()=>`<div class="tt">${ce(l.from==="users"?"Users":(s.byId.get(l.from)||{}).name||l.from)} <span class="faint">\u2192</span> ${ce((s.byId.get(l.to)||{}).name||l.to)}</div><div class="kv"><span>${ce(l.label)}</span><b>${l.link.count||""}</b></div>${M&&l.status!=="same"?`<div class="kv"><span>Status</span><b>${l.status==="added"?"New":"Removed"}</b></div>`:""}${l.link.evidence&&l.link.evidence[0]?`<div class="kv faint"><span class="mono-s">${ce(l.link.evidence[0].file)}:${l.link.evidence[0].line}</span></div>`:""}`;[u,m].filter(Boolean).forEach(f=>{f.addEventListener("pointermove",y=>{C.drag||Le(y,g())}),f.addEventListener("pointerleave",me)}),i.appendChild(u),C.wires.push({e:l,g:u,path:r,lbl:m})}C.nodes=new Map;for(let l of s.nodes){let c=Ns(l);p.appendChild(c),C.nodes.set(l.id,{n:l,el:c})}e.appendChild(n),e.addEventListener("click",()=>{C.dragMoved||_e()}),C.svg=e,C.world=n}function rt(){if(C.svg){for(let{n:e,el:s}of C.nodes.values()){let a=E.view==="diff"&&M?e.status:"same";s.setAttribute("class",`an t-${e.type} ${a}${ie(e.status)?"":" gone"}`)}for(let{e,g:s,path:a,lbl:o}of C.wires){let n=E.view==="diff"&&M?e.status:"same",i=`${n}${ie(e.status)?"":" gone"}`;s.setAttribute("class",`aw k-${e.kind}${e.async?" async":""} ${i}`),o&&o.setAttribute("class",`aw-lbl k-${e.kind} ${i}`),a.setAttribute("marker-end",`url(#aw-${n==="added"?"add":n==="removed"?"rem":e.kind==="app"?"app":e.kind==="data"?"data":"line"})`)}}}function ut(e){let s=P("#arch-card");if(!s||(rt(),s.classList.toggle("hl-on",!!e),!e))return;let a=new Set([e]);for(let{e:o,g:n,path:i,lbl:p}of C.wires){let d=o.from===e||o.to===e;n.classList.toggle("hl",d),p&&p.classList.toggle("hl",d),d&&(a.add(o.from),a.add(o.to),i.setAttribute("marker-end","url(#aw-hl)"))}for(let{n:o,el:n}of C.nodes.values())n.classList.toggle("hl",a.has(o.id))}function nt(){if(!C.svg)return;C.svg.setAttribute("viewBox",`${C.vb.x} ${C.vb.y} ${C.vb.w} ${C.vb.h}`);let e=P("#arch-stage").getBoundingClientRect(),s=P("#arch-pct");s&&e.width&&(s.textContent=`${Math.round(e.width/C.vb.w*100)}%`)}function Ge(e){let s=P("#arch-stage");if(!s||!C.layout)return!1;let a=s.getBoundingClientRect();if(!a.width||!a.height)return!1;let o=C.layout.bounds,n=40,i=Math.min(1.1,(a.width-n*2)/o.w,(a.height-n*2)/o.h),p=Math.max(i,a.width<640?.5:.2),d=p>i+1e-6,l=a.width/p,c=a.height/p,r=d?{x:o.x-n/p,y:o.y-n/p,w:l,h:c}:{x:o.x+o.w/2-l/2,y:o.y+o.h/2-c/2,w:l,h:c};if(!e||$e)return C.vb=r,nt(),!0;let u={...C.vb},m=performance.now(),g=f=>{let y=Math.min(1,(f-m)/320),D=1-(1-y)**3;for(let F of["x","y","w","h"])C.vb[F]=u[F]+(r[F]-u[F])*D;nt(),y<1&&requestAnimationFrame(g)};return requestAnimationFrame(g),!0}function Mt(e,s,a){let o=P("#arch-stage").getBoundingClientRect(),n=s??o.width/2,i=a??o.height/2,p=Math.min(8e3,Math.max(160,C.vb.w*e)),d=p/C.vb.w;C.vb.x+=n/o.width*C.vb.w*(1-d),C.vb.y+=i/o.height*C.vb.h*(1-d),C.vb.w=p,C.vb.h*=d,nt()}function Rs(e){let s=new Map,a=null;e.addEventListener("wheel",n=>{n.preventDefault();let i=e.getBoundingClientRect();n.ctrlKey||Math.abs(n.deltaY)>Math.abs(n.deltaX)*1.2||n.deltaMode?Mt(Math.exp(n.deltaY*(n.ctrlKey?.01:.0016)),n.clientX-i.left,n.clientY-i.top):(C.vb.x+=n.deltaX*C.vb.w/i.width,C.vb.y+=n.deltaY*C.vb.h/i.height,nt())},{passive:!1}),e.addEventListener("pointerdown",n=>{if(n.button===0){if(s.set(n.pointerId,[n.clientX,n.clientY]),s.size===2){let[i,p]=[...s.values()];a={d:Math.hypot(i[0]-p[0],i[1]-p[1]),w:C.vb.w},C.drag=null;return}C.drag={x:n.clientX,y:n.clientY,vx:C.vb.x,vy:C.vb.y},C.dragMoved=!1}}),e.addEventListener("pointermove",n=>{if(s.has(n.pointerId)&&s.set(n.pointerId,[n.clientX,n.clientY]),a&&s.size===2){let[l,c]=[...s.values()],r=e.getBoundingClientRect(),u=a.w*a.d/Math.max(20,Math.hypot(l[0]-c[0],l[1]-c[1]))/C.vb.w;Mt(u,(l[0]+c[0])/2-r.left,(l[1]+c[1])/2-r.top),C.dragMoved=!0;return}if(!C.drag)return;let i=n.clientX-C.drag.x,p=n.clientY-C.drag.y;if(!C.dragMoved&&Math.abs(i)+Math.abs(p)>4&&(C.dragMoved=!0,e.classList.add("dragging"),me(),ut(null)),!C.dragMoved)return;let d=e.getBoundingClientRect();C.vb.x=C.drag.vx-i*C.vb.w/d.width,C.vb.y=C.drag.vy-p*C.vb.h/d.height,nt()});let o=n=>{s.delete(n.pointerId),s.size<2&&(a=null),C.drag=null,e.classList.remove("dragging"),setTimeout(()=>{C.dragMoved=!1},0)};e.addEventListener("pointerup",o),e.addEventListener("pointercancel",o),e.addEventListener("pointerleave",n=>{C.drag&&o(n)})}function Ds(){let e=C.layout.bounds,s=40;Ft(C.svg,{x:e.x-s,y:e.y-s,w:e.w+s*2,h:e.h+s*2},`${x.project}-system-architecture.svg`,["whit","wdot","arch-bg"]),We("Architecture diagram exported as SVG","download")}function ct(){let e=P("#page-system"),s=C.svg&&C.fitted?{...C.vb}:null;e.innerHTML="",C.svg=null;let a=re.summary,o=He([{value:"diff",label:"Changes",disabled:!M},{value:"base",label:"Before",disabled:!M},{value:"cur",label:"After"}],E.view,m=>{E.view=m,Dt()});o.classList.add("sys-tabs");let n=m=>M&&(m.added||m.removed)?[m.added?t("span",{class:"chip add",text:`+${m.added}`}):null,m.removed?t("span",{class:"chip rem",text:`\u2212${m.removed}`}):null]:null,i=(m,g,f,y)=>t("div",{class:"sys-stat"},$(y),t("b",{class:"num",text:m}),t("span",{text:g}),n(f));if(e.append(t("div",{class:"page-head"},t("div",null,t("h1",{text:"Architecture"}),t("p",{text:"A container diagram drawn from your code: who uses the system, the apps in this repo, the data they keep and the outside systems they call."})),t("div",{class:"right"},o))),a&&e.append(t("div",{class:"sys-stats stagger"},i(a.apps.total,a.apps.total===1?"app":"apps",a.apps,"layers"),i(a.entry.total,"entry points",a.entry,"code"),i(a.stores.total,a.stores.total===1?"data store":"data stores",a.stores,"database"),i(a.outside.total,a.outside.total===1?"outside system":"outside systems",a.outside,"cloud"))),!re.apps.length){e.append(t("div",{class:"card"},t("div",{class:"empty-state"},t("div",{class:"ico-box"},$("layers")),t("h4",{text:"No apps found"}),t("p",{text:"Tecton looks for package.json files to find the apps in a repo."}))));return}let p=v("svg",{id:"arch-svg",role:"img","aria-label":`Container diagram of ${x.project}`}),d=t("div",{id:"arch-stage"},p),l=(m,g,f)=>t("span",{class:"ak"},v("svg",{viewBox:"0 0 26 16","aria-hidden":"true"},f||v("g",{class:`aw ${m}`},v("path",{class:"wl",d:"M2,8 L24,8"}))),g),c=(m,g)=>v("path",{class:`ak-shape ${m}`,d:g}),r=t("div",{class:"arch-legend"},l("","Person",c("","M13,1.5 a3,3 0 1 1 0,6 a3,3 0 1 1 0,-6 M5,15 q0,-6 8,-6 q8,0 8,6 z")),l("","App (container)",c("","M3,3 h20 a2,2 0 0 1 2,2 v8 a2,2 0 0 1 -2,2 h-20 a2,2 0 0 1 -2,-2 v-8 a2,2 0 0 1 2,-2 z")),l("","Database",c("","M6,3 a7,2.5 0 0 1 14,0 v10 a7,2.5 0 0 1 -14,0 z M6,3 a7,2.5 0 0 0 14,0")),l("","Queue",c("","M5,3 h16 a3,5 0 0 1 0,10 h-16 a3,5 0 0 1 0,-10 z M21,3 a3,5 0 0 0 0,10")),l("","Outside system",c("ext","M2,3 h22 v10 h-22 z")),l("","This repo",c("bnd","M2,3 h22 v10 h-22 z")),t("span",{class:"ak-sep"}),l("k-app","calls"),l("k-data","reads / writes"),l("k-data async","async (queue)"),l("k-outside","outside call"),M?[l("added","new"),l("removed","removed")]:null),u=t("div",{class:"zoom glass"},t("button",{"aria-label":"Zoom in","data-tip":"Zoom in",on:{click:()=>Mt(1/1.3)}},$("plus")),t("button",{"aria-label":"Zoom out","data-tip":"Zoom out",on:{click:()=>Mt(1.3)}},$("minus")),t("button",{"aria-label":"Fit to screen","data-tip":"Fit to screen (F)",on:{click:()=>Ge(!0)}},$("fit")),t("button",{"aria-label":"Export SVG","data-tip":"Export as SVG",on:{click:Ds}},$("image")),t("div",{class:"pct",id:"arch-pct",text:"100%"}));e.append(t("div",{class:"card arch-card",id:"arch-card"},d,t("div",{class:"float br"},u),t("div",{class:"float bl"},t("div",{class:"arch-hint glass"},$("sparkle"),"Hover to trace \xB7 click for the exact lines \xB7 drag to pan"))),r),e.appendChild(t("p",{class:"faint sys-note",text:"Detected from package.json files, imports, route files and route definitions, queue names, cron schedules, URLs in the code and .env.example files."})),Ps(p),rt(),Rs(d),requestAnimationFrame(()=>{et(),s?(C.vb=s,nt()):C.fitted=Ge(!1)})}function Ae(e){ls.sel=e;let s=P("#sheet");s.innerHTML="";let a=t("div",{class:"drawer-b"}),o,n,i,p="",d=l=>t("div",{class:"ev"},l.map(c=>t("div",{class:"ev-row"},t("code",{text:`${c.file}:${c.line}`}),c.text?t("span",{class:"to",text:c.text}):null)));if(e.type==="app"){let l=pt.get(e.id);o=l.name,n=`${l.framework} app \xB7 ${l.root?`${l.root}/`:"repo root"}${l.pkgName&&l.pkgName!==l.name?` \xB7 package "${l.pkgName}"`:""}`,i=ht(l),a.append(t("div",{class:"kv-grid"},t("div",null,t("div",{class:"k",text:"Files"}),t("div",{class:"v",text:l.fileCount})),t("div",null,t("div",{class:"k",text:"Entry points"}),t("div",{class:"v",text:Qe.reduce((r,u)=>r+(l.groups[u.key]||[]).filter(m=>m.status!=="removed").length,0)})),t("div",null,t("div",{class:"k",text:"Modules"}),t("div",{class:"v",text:(l.modules||[]).length}))));let c=re.links.filter(r=>(r.from===l.id||r.to===l.id)&&ns(r));c.length&&a.append(t("div",null,t("div",{class:"sec-t",text:"Connections"}),t("div",{class:"pill-list"},c.map(r=>{let u=r.from===l.id?r.to:r.from,m=Pt.get(u);return t("button",{class:"pill-item",on:{click:()=>m?Ae({type:"svc",id:u}):pt.has(u)?Ae({type:"app",id:u}):null}},$(m?re.stores.includes(m)?Nt(m):"cloud":u==="users"?"users":"server","faint"),t("span",{class:"grow",text:`${r.from===l.id?"\u2192 ":"\u2190 "}${m?m.name:os(u)}`}),E.view==="diff"&&r.status!=="same"?he(r.status):null,t("span",{class:"faint",style:{fontSize:"12px"},text:r.labels[0]||""}))})))),l.tech.length&&a.append(t("div",null,t("div",{class:"sec-t",text:"Notable tech"}),t("div",{class:"sys-tech",style:{padding:0}},l.tech.map(r=>t("span",{class:"chip",text:r})))));for(let r of Qe){let u=(l.groups[r.key]||[]).filter(ns);u.length&&a.append(t("div",null,t("div",{class:"sec-t",text:`${r.title} \xB7 ${u.length}`}),t("div",{class:"pill-list"},u.map(m=>t("button",{class:"pill-item",title:`${m.file}:${m.line}`,on:{click:()=>Ae({type:"item",app:l.id,group:r.key,key:m.key})}},m.methods&&m.methods.length?m.methods.map(g=>t("span",{class:`meth m-${g.toLowerCase()}`,text:g})):$(r.icon,"faint"),t("span",{class:"grow mono-s",text:m.label}),m.human?t("span",{class:"faint",style:{fontSize:"12px"},text:m.human}):null,E.view==="diff"&&M&&m.status!=="same"?he(m.status):null)))))}}else if(e.type==="svc"){let l=Pt.get(e.id),c=re.stores.includes(l);o=l.name,n=`${l.kind}${l.via&&l.via.length?` \xB7 via ${l.via.join(", ")}`:""}`,i=c?Nt(l):l.kind==="Email"?"mail":"cloud",l.kind==="Set by env var"&&a.append(t("div",{class:"muted",text:`The address comes from ${l.via.join(", ")} at run time, so only its name is known. Check .env.example or your deploy settings for where it points.`})),l.status&&l.status!=="same"&&M&&a.append(t("div",null,he(l.status))),a.append(t("div",null,t("div",{class:"sec-t",text:"Used by"}),t("div",{class:"pill-list"},l.apps.map(r=>t("button",{class:"pill-item",on:{click:()=>Ae({type:"app",id:r})}},t("i",{class:"dot",style:{background:Rt(r)}}),t("span",{class:"grow",text:os(r)}),t("span",{class:"faint",style:{fontSize:"12px"},text:(pt.get(r)||{}).framework||""})))))),"hosts"in l&&l.hosts.length&&a.append(t("div",null,t("div",{class:"sec-t",text:"Hosts"}),t("div",{class:"file-list"},l.hosts.map(r=>t("div",{class:E.view==="diff"?r.status==="added"?"plus":r.status==="removed"?"minus":"":"",text:r.host}))))),a.append(t("div",null,t("div",{class:"sec-t",text:`Where the code uses it \xB7 ${l.evidence.length}${l.evidence.length>=25?"+":""}`}),d(l.evidence)))}else{let l=pt.get(e.app),c=Qe.find(g=>g.key===e.group),r=l.groups[e.group].find(g=>g.key===e.key);o=`${r.methods&&r.methods.length?`${r.methods.join(" / ")} `:""}${r.label}`,n=`${c.title.replace(/s$/,"")} in ${l.name}`,i=c.icon,r.status&&r.status!=="same"&&M&&a.append(t("div",null,he(r.status))),r.human&&a.append(t("div",{class:"callout info"},$("clock"),t("div",null,t("b",{text:`Runs ${r.human}`}),t("div",{class:"mono-s",text:r.label})))),a.append(t("div",null,t("div",{class:"sec-t",text:"Defined in"}),d([{file:r.file,line:r.line,text:r.cmd||null}])));let u=r.file,m=x.nodes.find(g=>g.files.some(f=>f.path===u));m&&a.append(t("button",{class:"btn",on:{click:()=>{_e(),ve({type:"node",id:m.id})}}},$("map"),`Show module \u201C${m.id}\u201D on the dependency map`))}s.append(t("div",{class:"drawer-h"},t("span",{class:`ico-box ${p}`},$(i)),t("div",{style:{minWidth:0}},t("h3",{text:o}),t("div",{class:"sub",text:n})),t("button",{class:"btn icon ghost","aria-label":"Close",style:{marginLeft:"auto"},on:{click:_e}},$("x"))),a),s.classList.add("open")}function _e(){let e=P("#sheet");e&&e.classList.remove("open"),ls.sel=null,U.file&&Be(null)}function Dt(){let e=P("#view-tabs");e&&e._set(E.view),Ye(),oe(".sys-tabs").forEach(s=>s._set&&s._set(E.view)),C.svg?rt():ct(),E.page==="module"&&kt(U.id)}function ds(){if(!re.apps.length)return null;let e=re.summary,s=t("div",{class:"glance"});re.hasUsers&&s.append(t("div",{class:"g-node users"},$("users"),"Users"),t("span",{class:"g-arrow"},$("arrowRight"))),Cs().forEach((o,n,i)=>{let p=Qe.map(d=>[d,(o.groups[d.key]||[]).filter(l=>l.status!=="removed").length]).filter(([,d])=>d);s.append(t("button",{class:"g-node g-app",style:{"--app":Rt(o.id)},on:{click:()=>{se("system"),setTimeout(()=>Ae({type:"app",id:o.id}),60)}}},t("span",{class:"ico-box app-ico"},$(ht(o))),t("span",null,t("b",{text:o.name}),t("span",{class:"faint",text:`${o.framework}${p.length?` \xB7 ${p.map(([d,l])=>`${l} ${d.title.toLowerCase().replace("routes & api","routes").replace("http endpoints","endpoints").replace("jobs & scripts","jobs").replace("schedules",l===1?"schedule":"schedules")}`).join(" \xB7 ")}`:""}`})))),n<i.length-1&&s.append(t("span",{class:"g-arrow"},$("arrowRight")))});let a=t("div",{class:"g-tail"},re.stores.filter(o=>o.status!=="removed").map(o=>t("span",{class:"chip"},$(Nt(o)),o.name)),t("span",{class:"chip"},$("cloud"),ee(e.outside.total,"outside service")),M&&e.outside.added?t("span",{class:"chip add",text:`+${e.outside.added} new ${e.outside.added===1?"service":"services"}`}):null,M&&e.entry.added?t("span",{class:"chip add",text:`+${e.entry.added} entry points`}):null);return t("div",{class:"card",style:{marginTop:"14px"}},t("div",{class:"card-h"},t("h3",{text:"Architecture"}),t("div",{class:"right"},t("button",{class:"link-btn",on:{click:()=>se("system")}},"Open diagram",$("right")))),t("div",{class:"card-b"},s,a))}var U={id:null,file:null,pending:null,onlyTouched:!1,els:null,rows:new Map,refresh:null},rs=250;function Me(e,s){U.pending=s||null;let a=`module:${encodeURIComponent(e)}`;location.hash!==`#${a}`?location.hash=a:st(a)}function Fs(e){if(!e.length)return"";let s=e[0].split("/").slice(0,-1);for(let a of e){let o=a.split("/"),n=0;for(;n<s.length&&n<o.length-1&&s[n]===o[n];)n++;s=s.slice(0,n)}return s.join("/")}var js=e=>e.from.module!==e.to.module?`${e.from.module}\u2192${e.to.module}`:null,mt=e=>{let s=js(e);return s&&ie(e.status)&&ot().get(s)||null},Et=e=>ie(e.status)&&(!U.onlyTouched||Ve(e)!=="same");function Hs(e,s,a){let o=new Map,n=new Set,i=(r,u,m)=>{let g=`${r}\u2192${u}`;o.has(g)||o.set(g,{id:g,from:r,to:u,deps:[]}),o.get(g).deps.push(m)};for(let r of s){for(let u of r.out)u.to.module===e?i(r.path,u.to.path,u):(n.add(u.to.module),i(r.path,`mod:${u.to.module}`,u));for(let u of r.in)u.from.module!==e&&(n.add(u.from.module),i(`mod:${u.from.module}`,r.path,u))}let p=(r,u)=>r.length*7.3>=u.length*6.4?r:r.padEnd(Math.ceil(u.length*6.4/7.3)," "),d=s.map(r=>{let u=a(r),m=u.includes("/")?u.slice(0,u.lastIndexOf("/")+1):"";return{id:r.path,name:u.split("/").pop(),meta:m,file:r}});[...n].sort().forEach(r=>d.push({id:`mod:${r}`,name:r,meta:"module",mod:r})),d.forEach(r=>{r.label=p(r.name,r.meta)});let l=[...o.values()].map(r=>{let u=r.deps.map(g=>g.status),m=u.every(g=>g==="added")?"added":u.every(g=>g==="removed")?"removed":"same";return{...r,status:m,countBase:r.deps.filter(g=>g.status!=="added").length,countCur:r.deps.filter(g=>g.status!=="removed").length}}),c=ts(d.map(r=>({id:r.id,label:r.label,external:!!r.mod})),l);return{nodes:d,edges:l,lay:c}}function Ws(e){if(e.mod)return`<div class="tt">${ce(e.name)}</div><div class="kv"><span>Another module</span><b></b></div><div class="kv faint"><span>Click to open its files</span></div>`;let s=e.file,a=Ve(s);return`<div class="tt">${ce(e.name)}${M&&a!=="same"?` <span class="badge ${a==="added"?"add":a==="removed"?"rem":"acc"}">${a[0].toUpperCase()}${a.slice(1)}</span>`:""}</div><div class="kv"><span class="mono-s">${ce(s.path)}</span></div><div class="kv"><span>Imports</span><b>${s.out.filter(o=>ie(o.status)).length}</b></div><div class="kv"><span>Imported by</span><b>${s.in.filter(o=>ie(o.status)).length}</b></div>`}function Us(e){let s=e.status==="removed"?e.countBase:e.countCur,a=n=>n.startsWith("mod:")?n.slice(4):n.split("/").pop(),o=[...new Set(e.deps.flatMap(n=>(mt(n)||[]).map(i=>i.rule)))];return`<div class="tt">${ce(a(e.from))} <span class="faint">\u2192</span> ${ce(a(e.to))}</div><div class="kv"><span>Imports</span><b>${e.status==="same"&&e.countBase!==e.countCur?`${e.countBase} \u2192 ${e.countCur}`:s}</b></div>`+(M&&e.status!=="same"?`<div class="kv"><span>Status</span><b>${e.status==="added"?"New":"Removed"}</b></div>`:"")+o.map(n=>`<div class="kv" style="color:var(--viol-text)"><span>\u26A0 ${ce(n)}</span></div>`).join("")}function zs(e,s){e.innerHTML="";let a=28,o=s.lay.width+a*2,n=s.lay.height+a*2,i=v("svg",{class:"fmap-svg",width:o,height:n,viewBox:`${-a} ${-a} ${o} ${n}`,role:"group","aria-label":"Files in this module and what they import"}),p=v("defs");p.innerHTML='<filter id="fm-shadow" x="-20%" y="-30%" width="140%" height="170%"><feDropShadow dx="0" dy="1" stdDeviation="1.5" flood-color="#101018" flood-opacity=".08"/></filter>'+["line","add","rem","viol","accent"].map(r=>`<marker id="fm-arr-${r}" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="10" markerHeight="10" orient="auto-start-reverse" markerUnits="userSpaceOnUse"><path d="M1,1.5 L9,5 L1,8.5 Q2.5,5 1,1.5 z" style="fill: var(--${r})"/></marker>`).join(""),i.appendChild(p);let d=v("g"),l=v("g");i.append(d,l);let c={nodes:new Map,edges:new Map};return s.edges.forEach(r=>{let u=Ct(s.lay.routes[r.id]),m=v("path",{class:"line",d:u}),g=v("g",{class:"edge"},v("path",{class:"glow",d:u}),m,v("path",{class:"hit",d:u}));g.addEventListener("pointermove",f=>Le(f,Us(r))),g.addEventListener("pointerleave",me),d.appendChild(g),c.edges.set(r.id,{e:r,el:g,line:m})}),s.nodes.forEach(r=>{let u=s.lay.pos[r.id],m=v("g",{class:`node${r.mod?" external":""}`,transform:`translate(${u.x},${u.y})`,tabindex:0,role:"button","aria-label":r.mod?`Open module ${r.name}`:`File ${r.file.path}`}),g=(y,D,F)=>v("g",{class:`nbadge ${y}`,transform:`translate(${u.w-F-8},-8)`},v("rect",{width:F,height:15,rx:4}),v("text",{x:F/2,y:10.5,"text-anchor":"middle"},D));m.append(v("rect",{class:"card-r",width:u.w,height:u.h,rx:r.mod?u.h/2:10}),v("g",{class:"n-ico",transform:`translate(12,${(u.h-16)/2}) scale(0.667)`,html:r.mod?ke.box:ke.file}),v("text",{class:"n-name",x:36,y:r.meta?20:u.h/2+4.5},r.name),r.meta?v("text",{class:"n-meta",x:36,y:35},r.meta):null,g("b-add","NEW",34),g("b-rem","GONE",38)),r.file&&r.file.edited&&r.file.status==="same"&&m.appendChild(v("circle",{class:"tdot",cx:u.w-11,cy:u.h/2,r:3.5}));let f=()=>r.mod?Me(r.mod):Be(U.file===r.id?null:r.id);m.addEventListener("click",y=>{y.stopPropagation(),f()}),m.addEventListener("keydown",y=>{(y.key==="Enter"||y.key===" ")&&(y.preventDefault(),f())}),m.addEventListener("pointermove",y=>Le(y,Ws(r))),m.addEventListener("pointerleave",me),l.appendChild(m),c.nodes.set(r.id,{x:r,el:m})}),i.addEventListener("click",()=>Be(null)),e.appendChild(i),c}function cs(){let e=U.els;if(!e)return;let s=U.file,a=d=>{let l=e.nodes.get(d).x;return l.mod?!0:Et(l.file)},o=new Set,n=new Set;for(let{e:d}of e.edges.values())ie(d.status)&&a(d.from)&&a(d.to)&&(o.add(d.id),[d.from,d.to].forEach(l=>{l.startsWith("mod:")&&n.add(l)}));let i=s?new Set([...o].filter(d=>{let l=e.edges.get(d).e;return l.from===s||l.to===s})):null,p=s?new Set([s,...[...i].flatMap(d=>{let l=e.edges.get(d).e;return[l.from,l.to]})]):null;for(let{e:d,el:l,line:c}of e.edges.values()){let r=o.has(d.id),u=E.view==="diff"?d.status:"same",m=r&&!(E.view==="diff"&&d.status==="removed")&&d.deps.some(f=>mt(f)),g=i&&i.has(d.id);l.setAttribute("class",`edge ${u}${m?" viol":""}${g?" sel":""}${r?"":" gone"}${i&&!g?" dim":""}`),c.setAttribute("marker-end",`url(#fm-arr-${g?"accent":m?"viol":u==="added"?"add":u==="removed"?"rem":"line"})`)}for(let{x:d,el:l}of e.nodes.values()){let c=d.mod?n.has(d.id):Et(d.file),r=d.file&&E.view==="diff"&&M?Ve(d.file):"same",u=r==="edited"?"same touched":r;l.setAttribute("class",`node${d.mod?" external":""} ${u}${s===d.id?" sel":""}${c?"":" gone"}${p&&!p.has(d.id)?" dim":""}`)}}function Be(e){if(U.file=e&&je.has(e)?e:null,cs(),U.rows.forEach((s,a)=>s.classList.toggle("sel",a===U.file)),me(),U.file){Vs(je.get(U.file));let s=U.rows.get(U.file),a=U.els&&U.els.nodes.get(U.file);a?a.el.scrollIntoView({block:"nearest",inline:"center",behavior:$e?"auto":"smooth"}):s&&s.scrollIntoView({block:"nearest"})}else{let s=P("#sheet");s&&s.classList.remove("open")}}function Vs(e){let s=P("#sheet");s.innerHTML="";let a=Ve(e),o=e.out.filter(c=>ie(c.status)).sort((c,r)=>+(c.to.module===e.module)-+(r.to.module===e.module)||c.to.path.localeCompare(r.to.path)),n=e.in.filter(c=>ie(c.status)).sort((c,r)=>+(c.from.module===e.module)-+(r.from.module===e.module)||c.from.path.localeCompare(r.from.path)),i=(c,r)=>{let u=r==="out"?c.to:c.from,m=u.module===e.module,g=mt(c);return t("button",{class:"pill-item",title:u.path,on:{click:()=>m?Be(u.path):Me(u.module,u.path)}},$("file","faint"),t("span",{class:"grow mono-s ell",text:m?u.path.split("/").pop():u.path}),m?null:t("span",{class:`chip${g?" viol":""}`,text:u.module}),E.view==="diff"&&M&&c.status!=="same"?he(c.status):null,t("span",{class:"faint mono-s",title:r==="out"?`line ${c.line} of this file`:`line ${c.line} of ${u.path}`,text:`:${c.line}`}))},p=[...new Set(o.flatMap(c=>(mt(c)||[]).map(r=>r.rule)))],d=[...new Set(o.filter(c=>c.to.module!==e.module).map(c=>c.to.module))],l=t("div",{class:"drawer-b"});M&&a!=="same"&&l.append(t("div",null,he(a)," ",t("span",{class:"chip",text:`module ${e.module}`}))),p.forEach(c=>l.append(t("div",{class:"callout"},$("alert"),t("div",null,t("b",{text:`An import here breaks \u201C${c}\u201D`}),t("div",{text:"The rule-breaking imports are marked in orange below."}))))),l.append(t("div",{class:"kv-grid"},t("div",null,t("div",{class:"k",text:"Imports"}),t("div",{class:"v",text:o.length})),t("div",null,t("div",{class:"k",text:"Imported by"}),t("div",{class:"v",text:n.length})),t("div",null,t("div",{class:"k",text:"Other modules"}),t("div",{class:"v",text:d.length})))),o.length&&l.append(t("div",null,t("div",{class:"sec-t",text:`Imports \xB7 ${o.length}`}),t("div",{class:"pill-list"},o.map(c=>i(c,"out"))))),n.length&&l.append(t("div",null,t("div",{class:"sec-t",text:`Imported by \xB7 ${n.length}`}),t("div",{class:"pill-list"},n.map(c=>i(c,"in"))))),!o.length&&!n.length&&l.append(t("div",{class:"muted",text:"This file does not import other files in the analysed code, and nothing imports it."})),s.append(t("div",{class:"drawer-h"},t("span",{class:`ico-box ${a==="added"?"add":a==="removed"?"rem":""}`},$("file")),t("div",{style:{minWidth:0}},t("h3",{text:e.path.split("/").pop()}),t("div",{class:"sub mono-s ell",title:e.path,text:e.path})),t("button",{class:"btn icon ghost","aria-label":"Close",style:{marginLeft:"auto"},on:{click:()=>Be(null)}},$("x"))),l),s.classList.add("open")}function kt(e){let s=P("#page-module");s.innerHTML="";let a=Oe.get(e),o=U.id===e?U.file:null;U.id=e,U.els=null,U.rows=new Map;let n=Jt(e),i=Fs(n.map(_=>_.path)),p=_=>i?_.path.slice(i.length+1):_.path,d=Ee.get(e),l=n.filter(_=>Ve(_)!=="same").length,c=He([{value:"diff",label:"Changes",disabled:!M},{value:"base",label:"Before",disabled:!M},{value:"cur",label:"After"}],E.view,_=>{E.view=_,Dt()}),r=n.filter(_=>ie(_.status)).length;s.append(t("div",{class:"page-head"},t("div",{style:{minWidth:0}},t("button",{class:"link-btn back",on:{click:()=>se("modules")}},$("arrowLeft"),"All modules"),t("h1",{class:"ell",text:e,title:e}),t("p",{text:`${ee(r,"file")}${i?` in ${i}/`:""} \xB7 uses ${ee(d.uses,"module")} \xB7 used by ${ee(d.usedBy,"module")}`})),t("div",{class:"right"},c,t("button",{class:"btn",on:{click:()=>ve({type:"node",id:e})}},$("map"),t("span",{class:"lbl-t",text:"Show on map"})))));let u=[M&&a.status!=="same"?he(a.status):null,M&&l?t("span",{class:"chip acc"},$("pencil"),`${l} ${l===1?"file":"files"} edited in this change`):null,d.viol?t("span",{class:"chip viol"},$("alert"),ee(d.viol,"rule break")):null].filter(Boolean);u.length&&s.append(t("div",{class:"chip-row"},u));let m=M&&l?t("label",{class:"switch"},t("input",{type:"checkbox",checked:U.onlyTouched,on:{change:_=>{U.onlyTouched=_.target.checked,U.refresh()}}}),"Only changed files"):null,g=(_,w)=>t("span",null,v("svg",{viewBox:"0 0 22 8"},v("g",{class:`edge ${_}`},v("path",{class:"line",d:"M1,4 L21,4"}))),w),f=t("div",{class:"fmap",id:"fmap"});s.append(t("div",{class:"card fmap-card"},t("div",{class:"card-h"},t("h3",{text:"How the files connect"}),t("div",{class:"right fmap-legend"},g("same","import"),M?g("added","new"):null,M?g("removed","removed"):null,g("viol","breaks a rule"),M&&l?t("span",null,t("i",{class:"tdot-key"}),"edited"):null)),f)),n.length>rs?f.append(t("div",{class:"empty-state"},t("div",{class:"ico-box"},$("layers")),t("h4",{text:`${ee(n.length,"file")} is too many to draw clearly`}),t("p",{text:`The diagram is drawn for modules with up to ${rs} files. The table below lists every file, or split the module with "depth" or "modules" in tecton.config.json.`}))):n.length?U.els=zs(f,Hs(e,n,p)):f.append(t("div",{class:"empty-state"},t("div",{class:"ico-box"},$("file")),t("h4",{text:"No files"}),t("p",{text:"This module has no files in the analysed code."})));let y=t("tbody"),D=()=>{y.innerHTML="",U.rows=new Map;let _=n.filter(Et).sort((w,z)=>p(w).localeCompare(p(z)));_.length||y.appendChild(t("tr",null,t("td",{colspan:5,class:"faint",text:"No files to show in this view."}))),_.forEach(w=>{let z=w.out.filter(B=>ie(B.status)),b=z.filter(B=>B.to.module===e).length,S=[...new Set(z.filter(B=>B.to.module!==e).map(B=>B.to.module))].sort(),j=w.in.filter(B=>ie(B.status)&&B.from.module!==e).length,V=p(w),ae=V.includes("/")?V.slice(0,V.lastIndexOf("/")+1):"",W=Ve(w),X=t("tr",{class:`click${w.path===U.file?" sel":""}`,tabindex:0,on:{click:()=>Be(U.file===w.path?null:w.path),keydown:B=>{B.key==="Enter"&&Be(w.path)}}},t("td",null,t("div",{class:"cell-mod mono-s"},$("file","faint"),t("span",{class:"ell"},ae?t("span",{class:"faint",text:ae}):null,V.split("/").pop()))),t("td",null,M&&E.view==="diff"&&W!=="same"?he(W):t("span",{class:"faint",text:"\u2014"})),t("td",{class:"r num",text:b}),t("td",null,S.length?t("div",{class:"chip-row tight"},S.slice(0,4).map(B=>{let H=z.some(te=>te.to.module===B&&mt(te));return t("button",{class:`chip mod${H?" viol":""}`,title:H?`Breaks a rule. Open ${B}`:`Open ${B}`,on:{click:te=>{te.stopPropagation(),Me(B)}}},B)}),S.length>4?t("span",{class:"faint",text:`+${S.length-4}`}):null):t("span",{class:"faint",text:"\u2014"})),t("td",{class:"r num",text:j}));U.rows.set(w.path,X),y.appendChild(X)})},F=t("tr",null,t("th",{text:"File"}),t("th",{text:"Change"}),t("th",{class:"r",text:"Imports here"}),t("th",{text:"Uses other modules"}),t("th",{class:"r",text:"Used from outside"}));s.append(t("div",{class:"toolbar",style:{marginTop:"14px"}},t("h3",{class:"toolbar-t",text:"Files"}),m),t("div",{class:"card"},t("div",{class:"tbl-wrap"},t("table",null,t("thead",null,F),y)))),U.refresh=()=>{D(),cs(),U.file&&!Et(je.get(U.file))&&Be(null)},D(),U.file=null;let ne=U.pending||o;U.pending=null,Be(ne&&je.has(ne)&&je.get(ne).module===e?ne:null)}var O={built:!1,animated:!1,vb:{x:0,y:0,w:100,h:100},edgeEls:new Map,nodeEls:new Map};function Ct(e){let s=`M${e[0][0]},${e[0][1]}`;for(let a=1;a<e.length;a++){let o=e[a-1],n=e[a],i=(n[1]-o[1])/2;s+=` C${o[0]},${o[1]+i} ${n[0]},${n[1]-i} ${n[0]},${n[1]}`}return s}function Gs(e){let s=[e[0]];for(let d=1;d<e.length;d++){let l=e[d-1],c=e[d],r=(c[1]-l[1])/2,u=[l[0],l[1]+r],m=[c[0],c[1]-r];for(let g=1;g<=16;g++){let f=g/16,y=1-f;s.push([y*y*y*l[0]+3*y*y*f*u[0]+3*y*f*f*m[0]+f*f*f*c[0],y*y*y*l[1]+3*y*y*f*u[1]+3*y*f*f*m[1]+f*f*f*c[1]])}}let a=0,o=[0];for(let d=1;d<s.length;d++)a+=Math.hypot(s[d][0]-s[d-1][0],s[d][1]-s[d-1][1]),o.push(a);let n=a/2,i=o.findIndex(d=>d>=n);i<1&&(i=1);let p=(n-o[i-1])/(o[i]-o[i-1]||1);return{len:a,mid:[s[i-1][0]+(s[i][0]-s[i-1][0])*p,s[i-1][1]+(s[i][1]-s[i-1][1])*p]}}function ps(){let e=P("#page-map"),s=He([{value:"diff",label:"Changes",disabled:!M},{value:"base",label:"Before",disabled:!M},{value:"cur",label:"After"}],E.view,m=>{E.view=m,Ye()});s.id="view-tabs";let a=t("label",{class:"switch glass",style:{display:M?"":"none"},title:"Show only dependencies that were added, removed or break a rule"},t("input",{type:"checkbox",id:"focus-sw",on:{change:m=>{if(E.focusOnly=m.target.checked,E.focusOnly){E.touchedOnly=!1;let g=P("#touched-sw");g&&(g.checked=!1),E.view!=="diff"&&(E.view="diff",s._set("diff"))}Ye()}}}),"Only changes"),o=Ke?t("label",{class:"switch glass",title:"Show only the modules whose files this change edits, and what they connect to"},t("input",{type:"checkbox",id:"touched-sw",on:{change:m=>{E.touchedOnly=m.target.checked,E.touchedOnly&&(E.focusOnly=!1,P("#focus-sw").checked=!1),Ye()}}}),t("i",{class:"tdot-key","aria-hidden":"true"}),"Only touched"):null,n=(m,g)=>t("span",null,v("svg",{viewBox:"0 0 22 8"},v("g",{class:`edge ${m}`},v("path",{class:"line",d:"M1,4 L21,4"}))),g),i=t("div",{class:"legend-float glass"},n("same","Unchanged"),M?n("added","New"):null,M?n("removed","Removed"):null,n("viol","Breaks a rule")),p=t("div",{class:"pct",id:"zoom-pct",text:"100%"}),d=t("div",{class:"zoom glass"},t("button",{"aria-label":"Zoom in","data-tip":"Zoom in",on:{click:()=>Ht(1/1.3)}},$("plus")),t("button",{"aria-label":"Zoom out","data-tip":"Zoom out",on:{click:()=>Ht(1.3)}},$("minus")),t("button",{"aria-label":"Fit to screen","data-tip":"Fit to screen (F)",on:{click:()=>at(!0)}},$("fit")),t("button",{"aria-label":"Export SVG","data-tip":"Export as SVG",on:{click:Lt}},$("image")),p),l=t("div",{class:"minimap glass",id:"minimap"}),c=v("svg",{id:"map-svg",role:"img","aria-label":"Module dependency map"}),r=t("div",{id:"stage"},c),u=t("aside",{class:"drawer",id:"drawer","aria-label":"Details"});e.append(t("div",{class:"card map-card"},r,t("div",{class:"float tl"},t("div",{class:"glass",style:{padding:"0",borderRadius:"11px"}},s),a,o,i),t("div",{class:"float br"},d),t("div",{class:"float bl"},l),u)),_s(c),Ks(l),Zs(r)}function _s(e){let s=v("defs");s.innerHTML='<filter id="nshadow" x="-20%" y="-30%" width="140%" height="170%"><feDropShadow dx="0" dy="1" stdDeviation="1.5" flood-color="#101018" flood-opacity=".08"/></filter><pattern id="dots" width="18" height="18" patternUnits="userSpaceOnUse"><circle cx="1" cy="1" r="1" style="fill: var(--dot)"/></pattern>',["line","add","rem","viol","accent"].forEach(d=>{let l=v("marker",{id:`arr-${d}`,viewBox:"0 0 10 10",refX:9,refY:5,markerWidth:10,markerHeight:10,orient:"auto-start-reverse",markerUnits:"userSpaceOnUse"});l.appendChild(v("path",{d:"M1,1.5 L9,5 L1,8.5 Q2.5,5 1,1.5 z",style:`fill: var(--${d})`})),s.appendChild(l)}),e.appendChild(s),e.appendChild(v("rect",{x:-2e4,y:-2e4,width:4e4,height:4e4,fill:"url(#dots)"}));let a=v("g",{id:"world"}),o=v("g"),n=v("g"),i=v("g");a.append(o,n,i),e.appendChild(a);let p=Math.max(1,x.height);x.edges.forEach((d,l)=>{let c=Ct(d.points),{len:r,mid:u}=Gs(d.points),m=v("g",{class:"edge",style:`--len:${Math.ceil(r)};--d:${d.points[0][1]/p*.6+.15}s`});m.appendChild(v("path",{class:"glow",d:c}));let g=v("path",{class:"line",d:c,id:`ep${l}`});if(m.appendChild(g),m.appendChild(v("path",{class:"hit",d:c})),(d.status==="added"||Ie.cur.has(d.id))&&!$e){let w=v("circle",{class:"flow",r:2.6}),z=v("animateMotion",{dur:`${Math.max(1.6,r/70).toFixed(2)}s`,repeatCount:"indefinite",rotate:"auto"});z.appendChild(v("mpath",{href:`#ep${l}`})),w.appendChild(z),m.appendChild(w)}o.appendChild(m);let y=v("g",{class:"edge"}),D=v("g",{class:"lbl",transform:`translate(${u[0].toFixed(1)},${u[1].toFixed(1)})`}),F=v("rect",{rx:8,height:16,y:-8}),ne=v("text",{"text-anchor":"middle","dominant-baseline":"central",y:.5});D.append(F,ne),y.appendChild(D),i.appendChild(y);let _=w=>{O.dragMoved||(w.stopPropagation(),Te({type:"edge",id:d.id}))};[m,y].forEach(w=>{w.addEventListener("click",_),w.addEventListener("pointermove",z=>{O.drag||Le(z,Qs(d))}),w.addEventListener("pointerleave",me)}),y.style.cursor="pointer",O.edgeEls.set(d.id,{g:m,line:g,lbl:y,lr:F,lt:ne})}),x.nodes.forEach((d,l)=>{let c=d.pos,r=v("g",{class:`node${d.external?" external":""}`,transform:`translate(${c.x},${c.y})`,tabindex:0,role:"button","aria-label":d.id}),u=v("g",{style:`--d:${c.y/p*.5+l%5*.03}s`});u.appendChild(v("rect",{class:"card-r",width:c.w,height:c.h,rx:d.external?c.h/2:10}));let m=v("g",{class:"n-ico",transform:`translate(12,${(c.h-16)/2}) scale(0.667)`,html:d.external?ke.pkg:ke.box});u.appendChild(m),u.appendChild(v("text",{class:"n-name",x:36,y:20},Y(d.id)));let g=v("text",{class:"n-meta",x:36,y:35});u.appendChild(g);let f=(y,D,F)=>v("g",{class:`nbadge ${y}`,transform:`translate(${c.w-F-8},-8)`},v("rect",{width:F,height:15,rx:4}),v("text",{x:F/2,y:10.5,"text-anchor":"middle"},D));u.appendChild(f("b-add","NEW",34)),u.appendChild(f("b-rem","GONE",38)),d.touched&&u.appendChild(v("circle",{class:"tdot",cx:c.w-11,cy:c.h/2,r:3.5})),r.appendChild(u),r.addEventListener("click",y=>{O.dragMoved||(y.stopPropagation(),Te({type:"node",id:d.id}))}),d.external||r.addEventListener("dblclick",y=>{y.stopPropagation(),Me(d.id)}),r.addEventListener("keydown",y=>{(y.key==="Enter"||y.key===" ")&&(y.preventDefault(),Te({type:"node",id:d.id}))}),r.addEventListener("pointermove",y=>{O.drag||Le(y,qs(d))}),r.addEventListener("pointerleave",me),n.appendChild(r),O.nodeEls.set(d.id,{g:r,inner:u,meta:g})}),e.addEventListener("click",()=>{!O.dragMoved&&E.selected&&Te(null)}),O.world=a,O.svg=e,O.built=!0,Ye()}function ie(e){return E.view==="diff"?!0:E.view==="base"?e!=="added":e!=="removed"}var ot=()=>E.view==="base"?Ie.base:Ie.cur;function Ye(){if(!O.built)return;let e=ot(),s=E.selected,a=null,o=null;if(s)if(a=new Set,o=new Set,s.type==="node")a.add(s.id),x.edges.forEach(i=>{(i.from===s.id||i.to===s.id)&&ie(i.status)&&(o.add(i.id),a.add(i.from),a.add(i.to))});else if(s.type==="edge"){let i=Ue.get(s.id);o.add(i.id),a.add(i.from),a.add(i.to)}else lt.get(s.id).edges.forEach(i=>{let p=Ue.get(i);p&&(o.add(i),a.add(p.from),a.add(p.to))});else E.focusOnly&&E.view==="diff"?(a=new Set,o=new Set,x.edges.forEach(i=>{(Ot(i)||e.has(i.id))&&(o.add(i.id),a.add(i.from),a.add(i.to))}),x.nodes.forEach(i=>{i.status!=="same"&&a.add(i.id)})):E.touchedOnly&&(a=new Set(dt),o=new Set,x.edges.forEach(i=>{ie(i.status)&&(dt.has(i.from)||dt.has(i.to))&&(o.add(i.id),a.add(i.from),a.add(i.to))}));let n=new Set;x.edges.forEach(i=>{let p=O.edgeEls.get(i.id),d=ie(i.status),l=E.view==="diff"?i.status:"same",c=e.has(i.id)&&d&&!(E.view==="diff"&&i.status==="removed");c&&(n.add(i.from),n.add(i.to));let r=s&&s.type==="edge"&&s.id===i.id,u=p.g.classList.contains("draw-in")?" draw-in":"",m=`edge ${l}${c?" viol":""}${r?" sel":""}${d?"":" gone"}${o&&!o.has(i.id)?" dim":""}`;p.g.setAttribute("class",m+u),p.lbl.setAttribute("class",m);let g=r?"accent":c?"viol":l==="added"?"add":l==="removed"?"rem":"line";p.line.setAttribute("marker-end",`url(#arr-${g})`);let f;E.view==="diff"?i.status==="added"?f=`+${i.countCur}`:i.status==="removed"?f=`\u2212${i.countBase}`:f=i.countBase===i.countCur?String(i.countCur):`${i.countBase}\u2192${i.countCur}`:f=String(E.view==="base"?i.countBase:i.countCur),c&&(f=`\u26A0 ${f}`),p.lt.textContent=f;let y=Math.max(20,f.length*6.3+12);p.lr.setAttribute("width",y),p.lr.setAttribute("x",-y/2)}),x.nodes.forEach(i=>{let p=O.nodeEls.get(i.id),d=ie(i.status),l=E.view==="diff"?i.status:"same",c=s&&s.type==="node"&&s.id===i.id;p.g.setAttribute("class",`node${i.external?" external":""} ${l}${n.has(i.id)?" inviol":""}${c?" sel":""}${d?"":" gone"}${a&&!a.has(i.id)?" dim":""}${i.touched&&E.view==="diff"?" touched":""}`);let r=E.view==="base"?i.filesBase:E.view==="cur"?i.filesCur:i.status==="removed"?i.filesBase:i.filesCur;p.meta.textContent=i.external?"npm package":E.view==="diff"&&i.status==="same"&&i.filesBase!==i.filesCur?`${i.filesBase} \u2192 ${i.filesCur} files`:ee(r,"file")}),ea(n),Ys()}function qs(e){let s=Ee.get(e.id);return`<div class="tt">${ce(Y(e.id))}${e.status!=="same"&&M?` <span class="badge ${e.status==="added"?"add":"rem"}">${e.status==="added"?"New":"Removed"}</span>`:""}</div>${e.external?'<div class="kv"><span>npm package</span><b></b></div>':`<div class="kv"><span>Files</span><b>${M&&e.filesBase!==e.filesCur?`${e.filesBase} \u2192 ${e.filesCur}`:e.status==="removed"?e.filesBase:e.filesCur}</b></div>`}<div class="kv"><span>Uses</span><b>${s.uses}</b></div><div class="kv"><span>Used by</span><b>${s.usedBy}</b></div>`+(e.touched&&M?`<div class="kv"><span>Files edited</span><b style="color:var(--accent-text)">${e.touched}</b></div>`:"")+(e.external?"":'<div class="kv faint"><span>Double-click to open its files</span></div>')+(s.viol?`<div class="kv"><span>Rule breaks</span><b style="color:var(--viol-text)">${s.viol}</b></div>`:"")}function Qs(e){let s=ot().get(e.id)||[],a=e.status==="removed"?e.countBase:e.countCur;return`<div class="tt">${ce(Y(e.from))} <span class="faint">\u2192</span> ${ce(Y(e.to))}</div><div class="kv"><span>Imports</span><b>${e.status==="same"&&e.countBase!==e.countCur?`${e.countBase} \u2192 ${e.countCur}`:a}</b></div>`+(M?`<div class="kv"><span>Status</span><b>${e.status==="added"?"New":e.status==="removed"?"Removed":"Unchanged"}</b></div>`:"")+s.map(o=>`<div class="kv" style="color:var(--viol-text)"><span>\u26A0 ${ce(o.rule)}</span></div>`).join("")}function Ys(){let e=P("#drawer");if(!e)return;let s=E.selected;if(!s){e.classList.remove("open");return}e.innerHTML="";let a=t("button",{class:"btn icon ghost","aria-label":"Close details",style:{marginLeft:"auto"},on:{click:()=>Te(null)}},$("x")),o=t("div",{class:"drawer-b"}),n;if(s.type==="node"){let i=Oe.get(s.id),p=Ee.get(i.id);n=t("div",{class:"drawer-h"},t("span",{class:`ico-box ${i.status==="added"&&M?"add":i.status==="removed"?"rem":""}`},$(i.external?"pkg":"box")),t("div",{style:{minWidth:0}},t("h3",{text:Y(i.id)}),t("div",{class:"sub"},i.external?"npm package":`${M?{added:"New module",removed:"Removed module",same:"Module"}[i.status]:"Module"} \xB7 ${ee(i.status==="removed"?i.filesBase:i.filesCur,"file")}`)),a),o.append(t("div",{class:"kv-grid"},t("div",null,t("div",{class:"k",text:"Uses"}),t("div",{class:"v",text:p.uses})),t("div",null,t("div",{class:"k",text:"Used by"}),t("div",{class:"v",text:p.usedBy})),t("div",null,t("div",{class:"k",text:"Rule breaks"}),t("div",{class:"v",style:p.viol?{color:"var(--viol-text)"}:null,text:p.viol})))),i.external||o.append(t("button",{class:"btn",on:{click:()=>Me(i.id)}},$("file"),"Open files and how they connect",i.touched&&M?t("span",{class:"chip acc",text:`${i.touched} edited`}):null));let d=x.edges.filter(c=>c.from===i.id&&ie(c.status)),l=x.edges.filter(c=>c.to===i.id&&ie(c.status));if([["Uses",d,"to"],["Used by",l,"from"]].forEach(([c,r,u])=>{r.length&&o.append(t("div",null,t("div",{class:"sec-t",text:`${c} \xB7 ${r.length}`}),t("div",{class:"pill-list"},r.map(m=>{let g=ot().get(m.id);return t("button",{class:"pill-item",on:{click:()=>Te({type:"edge",id:m.id})}},$(m[u].startsWith("npm:")?"pkg":"box","faint"),t("span",{class:"grow",text:Y(m[u])}),g?de("serious","Rule"):null,E.view==="diff"&&m.status!=="same"?he(m.status):null,t("span",{class:"faint num mono",style:{fontSize:"11.5px"},text:String(m.status==="removed"?m.countBase:m.countCur)}))}))))}),i.files.length){let c=i.files.filter(r=>!(E.view==="base"&&r.status==="added")&&!(E.view==="cur"&&r.status==="removed"));o.append(t("div",null,t("div",{class:"sec-t",text:`Files \xB7 ${c.length}`}),t("div",{class:"file-list"},c.slice(0,300).map(r=>{let u=E.view==="diff"&&r.status==="same"&&(je.get(r.path)||{}).edited,m=E.view==="diff"?r.status==="added"?"plus":r.status==="removed"?"minus":u?"edit":"":"";return t("div",{class:`${m} click`,role:"button",tabindex:0,title:"Open this file",on:{click:()=>Me(i.id,r.path),keydown:g=>{g.key==="Enter"&&Me(i.id,r.path)}},text:`${E.view==="diff"&&r.status==="added"?"+ ":E.view==="diff"&&r.status==="removed"?"\u2212 ":u?"~ ":""}${r.path}`})}))))}}else if(s.type==="edge"){let i=Ue.get(s.id),p=ot().get(i.id)||[];n=t("div",{class:"drawer-h"},t("span",{class:`ico-box ${p.length?"viol":i.status==="added"?"add":i.status==="removed"?"rem":""}`},$(p.length?"alert":"link")),t("div",{style:{minWidth:0}},t("h3",null,Y(i.from),t("span",{class:"arrow",text:" \u2192 "}),Y(i.to)),t("div",{class:"sub",text:`${M?{added:"New dependency",removed:"Removed dependency",same:"Dependency"}[i.status]:"Dependency"} \xB7 ${i.status==="same"&&i.countBase!==i.countCur?`imports ${i.countBase} \u2192 ${i.countCur}`:ee(i.status==="removed"?i.countBase:i.countCur,"import")}`})),a),p.forEach(d=>o.append(t("div",{class:"callout"},$("alert"),t("div",null,t("b",{text:`Breaks \u201C${d.rule}\u201D`}),d.message?t("div",{text:d.message}):null)))),o.append(t("div",{class:"pill-list"},[i.from,i.to].map(d=>t("button",{class:"pill-item",on:{click:()=>Te({type:"node",id:d})}},$(d.startsWith("npm:")?"pkg":"box","faint"),t("span",{class:"grow",text:Y(d)}),t("span",{class:"faint",style:{fontSize:"12px"},text:d===i.from?"imports":"is imported"}))))),i.addedImports&&i.addedImports.length&&o.append(t("div",null,t("div",{class:"sec-t",text:"Added in this change"}),tt(i.addedImports,"plus"))),o.append(t("div",null,t("div",{class:"sec-t",text:i.status==="removed"?"Where it used to happen":"Where it happens"}),tt(i.imports)))}else{let i=lt.get(s.id);n=t("div",{class:"drawer-h"},t("span",{class:"ico-box viol"},$(i.kind==="cycle"?"cycle":"alert")),t("div",{style:{minWidth:0}},t("h3",{text:i.rule}),t("div",{class:"sub",text:i.status==="new"?"New in this change":i.status==="fixed"?"Fixed by this change":M?"Already existed before this change":"Found in the current code"})),a),o.append(t("div",null,$t(i)," ",de(i.severity==="error"?"critical":"warn",i.severity==="error"?"Error":"Warning"))),i.message&&o.append(t("div",{class:"callout"},$("alert"),i.message)),o.append(t("div",{class:"muted",text:i.kind==="cycle"?`These modules depend on each other in a loop: ${i.members.map(Y).join(" \u21C4 ")}`:`${Y(i.from)} is not allowed to use ${Y(i.to)}.`})),o.append(t("div",null,t("div",{class:"sec-t",text:"Where it happens"}),tt(i.imports)))}e.append(n,o),e.classList.add("open")}function Te(e,s){E.selected=e&&E.selected&&E.selected.type===e.type&&E.selected.id===e.id&&!s?null:e;let a=E.selected;if(a&&M){let o=a.type==="node"?Oe.get(a.id):a.type==="edge"?Ue.get(a.id):null,n=a.type==="viol"?lt.get(a.id):null;E.view==="cur"&&(o&&o.status==="removed"||n&&n.status==="fixed")&&(E.view="diff"),E.view==="base"&&(o&&o.status==="added"||n&&n.status==="new")&&(E.view="diff");let i=P("#view-tabs");i&&i._set(E.view)}me(),Ye(),a&&s&&Xs()}function ve(e){se("map"),setTimeout(()=>Te(e,!0),30)}function ft(){let e=O.vb;O.svg.setAttribute("viewBox",`${e.x} ${e.y} ${e.w} ${e.h}`);let s=P("#stage").getBoundingClientRect(),a=P("#zoom-pct");a&&s.width&&(a.textContent=`${Math.round(s.width/e.w*100)}%`),Js()}function St(){return P("#stage").getBoundingClientRect()}function us(e,s,a,o,n,i){let p=St(),d=Math.max(1,p.width),l=Math.max(1,p.height),c=E.selected&&P("#drawer").classList.contains("open")&&d>700?Math.min(400,d):0,r=64,u=a-e+n*2,m=o-s+n*2+r,g=Math.max(u/(d-c),m/l,.55),f={w:d*g,h:l*g};f.x=(e+a)/2-(d-c)*g/2,f.y=(s+o)/2-f.h/2-r/2*g,hs(f,i)}var jt=null;function hs(e,s){if(cancelAnimationFrame(jt),!s||$e){Object.assign(O.vb,e),ft();return}let a={...O.vb},o=performance.now(),n=i=>{let p=Math.min(1,(i-o)/420),d=1-(1-p)**3;["x","y","w","h"].forEach(l=>{O.vb[l]=a[l]+(e[l]-a[l])*d}),ft(),p<1&&(jt=requestAnimationFrame(n))};jt=requestAnimationFrame(n)}function at(e){us(0,-10,x.width,x.height,48,e)}function Xs(){let e=E.selected;if(!e)return;let s=[];if(e.type==="node")s=[e.id],x.edges.forEach(p=>{(p.from===e.id||p.to===e.id)&&ie(p.status)&&s.push(p.from,p.to)});else if(e.type==="edge"){let p=Ue.get(e.id);s=[p.from,p.to]}else lt.get(e.id).edges.forEach(p=>{let d=Ue.get(p);d&&s.push(d.from,d.to)});let a=1/0,o=1/0,n=-1/0,i=-1/0;s.forEach(p=>{let d=Oe.get(p).pos;a=Math.min(a,d.x),o=Math.min(o,d.y),n=Math.max(n,d.x+d.w),i=Math.max(i,d.y+d.h)}),us(a,o,n,i,90,!0)}function Ht(e,s,a){let o=St();s==null&&(s=o.width/2,a=o.height/2);let n=O.vb,i=n.x+s/o.width*n.w,p=n.y+a/o.height*n.h,l=Math.min(Math.max(n.w*e,180),Math.max(x.width,x.height)*6+2400)/n.w;n.x=i-(i-n.x)*l,n.y=p-(p-n.y)*l,n.w*=l,n.h*=l,ft()}function Zs(e){e.addEventListener("wheel",s=>{s.preventDefault();let a=St();s.ctrlKey||Math.abs(s.deltaY)>Math.abs(s.deltaX)*1.2||s.deltaMode?Ht(Math.exp(s.deltaY*(s.ctrlKey?.01:.0016)),s.clientX-a.left,s.clientY-a.top):(O.vb.x+=s.deltaX*O.vb.w/a.width,O.vb.y+=s.deltaY*O.vb.h/a.height,ft())},{passive:!1}),e.addEventListener("pointerdown",s=>{s.button===0&&(O.drag={x:s.clientX,y:s.clientY,vx:O.vb.x,vy:O.vb.y},O.dragMoved=!1)}),window.addEventListener("pointermove",s=>{if(!O.drag)return;let a=s.clientX-O.drag.x,o=s.clientY-O.drag.y;if(!O.dragMoved&&Math.abs(a)+Math.abs(o)>4&&(O.dragMoved=!0,e.classList.add("dragging"),me()),!O.dragMoved)return;let n=St();O.vb.x=O.drag.vx-a*O.vb.w/n.width,O.vb.y=O.drag.vy-o*O.vb.h/n.height,ft()}),window.addEventListener("pointerup",()=>{O.drag=null,e.classList.remove("dragging"),setTimeout(()=>{O.dragMoved=!1},0)})}function Ks(e){let a=v("svg",{viewBox:`-20 -20 ${x.width+40} ${x.height+40}`,preserveAspectRatio:"xMidYMid meet"}),o=v("g");x.edges.forEach(d=>o.appendChild(v("path",{d:Ct(d.points),style:"fill:none;stroke:var(--border-strong);stroke-width:2","vector-effect":"non-scaling-stroke"}))),x.nodes.forEach(d=>{let l=v("rect",{class:"mn",x:d.pos.x,y:d.pos.y,width:d.pos.w,height:d.pos.h,rx:8,dataset:null});l.dataset.id=d.id,o.appendChild(l)});let n=v("rect",{class:"vp",rx:6});a.append(o,n),e.appendChild(a),O.mini={svg:a,vp:n,pad:20};let i=d=>{let l=a.getBoundingClientRect(),c=x.width+40,r=x.height+40,u=Math.max(c/l.width,r/l.height),m=(l.width*u-c)/2,g=(l.height*u-r)/2,f=(d.clientX-l.left)*u-m-20,y=(d.clientY-l.top)*u-g-20;hs({...O.vb,x:f-O.vb.w/2,y:y-O.vb.h/2},d.type==="click")},p=!1;e.addEventListener("pointerdown",d=>{d.stopPropagation(),p=!0,i(d)}),window.addEventListener("pointermove",d=>{p&&i(d)}),window.addEventListener("pointerup",()=>{p=!1})}function Js(){if(!O.mini)return;let e=O.vb,s=O.mini.vp;s.setAttribute("x",e.x),s.setAttribute("y",e.y),s.setAttribute("width",e.w),s.setAttribute("height",e.h)}function ea(e){O.mini&&oe("rect.mn",O.mini.svg).forEach(s=>{let a=Oe.get(s.dataset.id),o=E.view==="diff"?a.status:"same";s.setAttribute("class",`mn ${o}${e.has(a.id)?" inviol":""}`),s.style.opacity=ie(a.status)?"":"0"})}function as(){if(O.animated||$e){O.animated=!0;return}O.animated=!0,O.edgeEls.forEach(e=>e.g.classList.add("draw-in")),O.nodeEls.forEach(e=>e.inner.classList.add("pop-in")),oe(".lbl",O.world).forEach(e=>{e.style.opacity="0",e.style.transition="opacity .4s"}),setTimeout(()=>oe(".lbl",O.world).forEach(e=>{e.style.opacity=""}),900),setTimeout(()=>{O.edgeEls.forEach(e=>e.g.classList.remove("draw-in")),O.nodeEls.forEach(e=>e.inner.classList.remove("pop-in"))},1900)}function Ft(e,s,a,o){let n=e.cloneNode(!0);n.setAttribute("viewBox",`${s.x} ${s.y} ${s.w} ${s.h}`),n.setAttribute("width",Math.round(s.w)),n.setAttribute("height",Math.round(s.h)),n.setAttribute("xmlns",xt);let i=[e,...e.querySelectorAll("*")],p=[n,...n.querySelectorAll("*")],d=["fill","stroke","stroke-width","stroke-dasharray","stroke-linecap","opacity","font-family","font-size","font-weight","letter-spacing","display"],l=["gone",...o];i.forEach((u,m)=>{let g=getComputedStyle(u),f=p[m];if(u.classList&&l.some(y=>u.classList.contains(y))){f.setAttribute("data-drop","1");return}f.setAttribute("style",d.map(y=>`${y}:${g.getPropertyValue(y)}`).join(";")),f.removeAttribute("class")}),n.querySelectorAll("[data-drop]").forEach(u=>u.remove());let c=v("rect",{x:s.x,y:s.y,width:s.w,height:s.h,style:`fill:${getComputedStyle(document.body).backgroundColor}`});n.insertBefore(c,n.firstChild);let r=new Blob([`<?xml version="1.0" encoding="UTF-8"?>
3
+ ${new XMLSerializer().serializeToString(n)}`],{type:"image/svg+xml"});Wt(r,a)}function Lt(){Ft(O.svg,{x:-32,y:-42,w:x.width+64,h:x.height+64+10},`${x.project}-dependency-map.svg`,["hit","flow"]),We("Map exported as SVG","download")}function Wt(e,s){let a=t("a",{href:URL.createObjectURL(e),download:s});document.body.appendChild(a),a.click(),a.remove(),setTimeout(()=>URL.revokeObjectURL(a.href),2e3)}function At(){let e=x.markdown||"",s=()=>We("PR summary copied as Markdown","copy");navigator.clipboard&&window.isSecureContext?navigator.clipboard.writeText(e).then(s,a):a();function a(){let o=t("textarea",{style:{position:"fixed",opacity:"0"}});o.value=e,document.body.appendChild(o),o.select();try{document.execCommand("copy"),s()}catch{We("Could not copy \u2014 use the JSON/Markdown output instead","alert")}o.remove()}}function ms(){let e=P("#page-overview"),s=be.newErrors+be.newWarnings,a=M?Ce?`This change breaks ${ee(be.newErrors,"architecture rule")}`:s?`No new errors, ${ee(be.newWarnings,"new warning")}`:"This change keeps the architecture clean":Ce?`${ee(Se.length,"rule break")} in this codebase`:"All architecture rules pass",o=M?Ce?"New dependencies cross boundaries your team set in tecton.config.json. CI will fail until they are removed or the rules are updated.":`Compared with ${Xe()}, nothing crosses a boundary you have set.${be.fixed?` It also fixes ${ee(be.fixed,"earlier rule break")}.`:""}`:"No git base was found, so this is a snapshot of the current code checked against your rules.",n=t("div",{class:`card hero ${Ce?"fail":"pass"}`},t("div",{class:"hero-icon"},$(Ce?"alert":"check")),t("div",null,t("h2",{text:a}),t("p",{text:o}),t("div",{class:"actions"},t("button",{class:"btn primary",on:{click:()=>se(Se.length?"rules":"map")}},$(Se.length?"shield":"map"),Se.length?"Review rule breaks":"Open the map"),t("button",{class:"btn",on:{click:()=>se("changes")}},$("compare"),"See all changes"))),t("div",{class:"big"},t("div",{class:"v num",dataset:{count:M?s:Se.length},text:"0"}),t("div",{class:"l",text:M?"new rule breaks":"rule breaks"}))),i=M?[Z.modules.added?t("span",{class:"chip add",text:`+${Z.modules.added} new`}):null,Z.modules.removed?t("span",{class:"chip rem",text:`\u2212${Z.modules.removed} gone`}):null]:[],p=M?[Z.deps.added?t("span",{class:"chip add",text:`+${Z.deps.added}`}):null,Z.deps.removed?t("span",{class:"chip rem",text:`\u2212${Z.deps.removed}`}):null,Z.deps.changed?t("span",{class:"chip chg",text:`${Z.deps.changed} changed`}):null]:[],d=[M&&Z.touched&&Z.touched.files?t("span",{class:"chip acc",text:`${Z.touched.files} edited`}):null,M&&Z.files.cur!==Z.files.base?t("span",{class:"chip",text:`${Z.files.cur-Z.files.base>0?"+":"\u2212"}${Math.abs(Z.files.cur-Z.files.base)} vs ${Xe()}`}):null],l=(w,z,b,S,j)=>t("div",{class:"card stat"},t("div",{class:"l"},$(z),w),t("div",{class:"v num",dataset:{count:b},text:"0"}),t("div",{class:"delta"},S.filter(Boolean).length?S:t("span",{class:"faint",text:j}))),c=t("div",{class:"grid stats stagger"},l("Modules","box",Z.modules.total,i,M?"No modules added or removed":"Current snapshot"),l("Dependencies","link",Z.deps.total,p,M?"No links changed":"Links between modules"),l("Rule breaks","shield",Se.length,[be.newErrors?t("span",{class:"chip viol",text:`${be.newErrors} new`}):null,be.existing?t("span",{class:"chip",text:`${be.existing} existing`}):null,be.fixed?t("span",{class:"chip add",text:`${be.fixed} fixed`}):null],`${xe.length} rules checked`),l("Files analysed","file",Z.files.cur,d,"JS / TS source files")),r=x.edges.filter(w=>w.status==="same"&&w.countBase===w.countCur).length,u=[{k:"Added",n:Z.deps.added,c:"var(--add)"},{k:"Removed",n:Z.deps.removed,c:"var(--rem)"},{k:"Import count changed",n:Z.deps.changed,c:"var(--chg)"},{k:"Unchanged",n:r,c:"var(--neutral-bar)"}],m=u.reduce((w,z)=>w+z.n,0)||1,g=t("div",{class:"card"},t("div",{class:"card-h"},t("h3",{text:"Dependency changes"}),t("div",{class:"right"},t("button",{class:"link-btn",on:{click:()=>se("changes")}},"View all",$("right")))),t("div",{class:"card-b",style:{paddingBottom:"6px"}},t("div",{class:"stackbar",role:"img","aria-label":u.map(w=>`${w.k}: ${w.n}`).join(", ")},u.filter(w=>w.n).map((w,z)=>t("span",{style:{width:`${w.n/m*100}%`,background:w.c,animationDelay:`${z*.08}s`},on:{pointermove:b=>Le(b,`<div class="tt">${ce(w.k)}</div><div class="kv"><span>Dependencies</span><b>${w.n}</b></div><div class="kv"><span>Share</span><b>${Math.round(w.n/m*100)}%</b></div>`),pointerleave:me}}))),t("div",{class:"legend-row"},u.map(w=>t("span",null,t("i",{class:"sw",style:{background:w.c}}),w.k,t("b",{class:"num",text:w.n}))))),t("div",{class:"list",style:{marginTop:"10px"}},Ne.length?Ne.slice(0,5).map(ta):t("div",{class:"card-b faint",text:M?"The structure did not change.":"No comparison available."}))),f=t("div",{class:"card"},t("div",{class:"card-h"},t("h3",{text:"Rule checks"}),t("div",{class:"right"},t("button",{class:"link-btn",on:{click:()=>se("rules")}},"Details",$("right")))),t("div",{class:"list",style:{marginTop:"12px"}},xe.length?xe.map(w=>t("button",{class:"row-btn",on:{click:()=>{se("rules"),gt(w.key)}}},t("span",{class:`ico-box ${w.state==="new"?"rem":w.state==="existing"?"viol":"good"}`},$(w.kind==="cycle"?"cycle":w.state==="pass"||w.state==="fixed"?"check":"alert")),t("span",{class:"main-t"},t("div",{class:"t1",text:w.key}),t("div",{class:"t2",text:Ut(w)})),wt(w.state))):t("div",{class:"card-b faint",text:'No rules yet. Run `tecton init` in your project to add some, like "components must not use db". Loops between modules are checked already.'}))),y=t("div",{class:"preview",id:"preview",role:"link",tabindex:0,"aria-label":"Open the architecture map",on:{click:()=>se("map"),keydown:w=>{w.key==="Enter"&&se("map")}}},t("button",{class:"btn open",tabindex:-1},"Open map",$("arrowRight"))),D=t("div",{class:"card"},t("div",{class:"card-h",style:{paddingBottom:"14px"}},t("h3",{text:"Architecture preview"}),t("div",{class:"right"},t("span",{class:"faint",style:{fontSize:"12.5px"},text:`${Z.modules.total} modules \xB7 ${Z.deps.total} links`}))),y),F=ze.slice().sort((w,z)=>Math.max(z.filesCur,z.filesBase)-Math.max(w.filesCur,w.filesBase)).slice(0,8),ne=Math.max(1,...F.map(w=>Math.max(w.filesCur,w.filesBase))),_=t("div",{class:"card"},t("div",{class:"card-h"},t("h3",{text:"Files per module"}),t("div",{class:"right"},t("button",{class:"link-btn",on:{click:()=>se("modules")}},"All modules",$("right")))),t("div",{class:"card-b"},t("div",{class:"bars"},F.map((w,z)=>{let b=w.status==="removed"?w.filesBase:w.filesCur;return t("div",{class:`bar-row ${w.status}`,on:{pointermove:S=>Le(S,`<div class="tt">${ce(w.id)}</div><div class="kv"><span>Files now</span><b>${w.filesCur}</b></div>${M?`<div class="kv"><span>Files before</span><b>${w.filesBase}</b></div>`:""}`),pointerleave:me}},t("span",{class:"n",text:w.id}),t("div",{class:"bar-track"},t("div",{class:"bar-fill",style:{width:`${Math.max(2,b/ne*100)}%`,animationDelay:`${z*.05}s`}})),t("span",{class:"num muted",style:{fontSize:"12.5px"},text:M&&w.filesBase!==w.filesCur?`${w.filesBase} \u2192 ${w.filesCur}`:String(b)}))}))));e.append(t("div",{class:"page-head"},t("div",null,t("h1",{text:"Overview"}),t("p",{text:M?`How ${x.curLabel} reshapes ${x.project} compared with ${Xe()}.`:`A snapshot of ${x.project}.`})),t("div",{class:"right"},t("button",{class:"btn",on:{click:()=>se("map")}},$("map"),"Open map"))),t("div",{class:"stagger"},n),c,ds(),t("div",{class:"grid two stagger",style:{marginTop:"14px"}},g,f),t("div",{class:"grid two stagger",style:{marginTop:"14px"}},D,_))}function ta(e){let s=e.edge,a=e.type==="node"?e.kind==="added"?"filePlus":"box":e.viol?"alert":"link",o=e.viol?"viol":e.kind==="added"?"add":e.kind==="removed"?"rem":"chg",n=e.type==="node"?`${e.kind==="added"?"New module":"Module removed"} \xB7 ${e.sub}`:s.status==="same"?`Imports ${s.countBase} \u2192 ${s.countCur}`:`${ee(s.status==="added"?s.countCur:s.countBase,"import")}${e.viol?" \xB7 breaks a rule":""}`;return t("button",{class:"row-btn",on:{click:()=>ve({type:e.type,id:e.id})}},t("span",{class:`ico-box ${o}`},$(a)),t("span",{class:"main-t"},t("div",{class:"t1",text:e.label}),t("div",{class:"t2",text:n})),he(e.kind),$("right","chev"))}function Ut(e){return Array.isArray(e.from)&&(e={...e,from:e.from.join(", ")}),e.kind==="cycle"?"No module may depend on itself through others":e.to?`${e.from} must not use ${e.to.map(Y).join(", ")}`:e.allow?e.allow.length?`${e.from} may only use ${e.allow.join(", ")}`:`${e.from} may not use other modules`:e.from||""}function fs(){let e=P("#page-rules"),s=xe.filter(n=>n.state==="new"||n.state==="existing").length;if(e.append(t("div",{class:"page-head"},t("div",null,t("h1",{text:"Rule checks"}),t("p",{text:`The boundaries set in tecton.config.json, checked against ${M?x.curLabel:"the current code"}.`})),t("div",{class:"right"},t("span",{class:"badge neutral plain",text:ee(xe.length,"rule")}),s?de("critical",`${s} failing`):null,de("good",`${xe.length-s} passing`)))),!xe.length){e.append(t("div",{class:"card"},t("div",{class:"empty-state"},t("div",{class:"ico-box"},$("shield")),t("h4",{text:"No rules yet"}),t("p",null,"Run ",t("code",{text:"tecton init"})," to create a starter tecton.config.json, then describe which parts of the app may use which."))));return}let a=t("div",{class:"card",id:"rule-list"});xe.forEach(n=>{let i=t("div",{class:"rule-inner"},n.message?t("div",{class:"callout",style:{background:"var(--surface-2)",color:"var(--text-2)"}},$("sparkle"),n.message):null,n.viols.length?n.viols.map(d=>t("div",{class:"viol-card"},t("div",{class:"top"},$t(d),t("span",{text:d.kind==="cycle"?d.members.map(Y).join(" \u21C4 "):`${Y(d.from)} \u2192 ${Y(d.to)}`}),t("span",{class:"faint",style:{fontSize:"12.5px"},text:`\xB7 ${ee(d.count,d.kind==="cycle"?"link":"import")}`}),t("button",{class:"link-btn",style:{marginLeft:"auto"},on:{click:()=>ve({type:"viol",id:d.id})}},$("map"),"Show on map")),tt(d.imports.slice(0,8)),d.imports.length>8?t("div",{class:"faint",style:{fontSize:"12px",marginTop:"6px"},text:`+ ${d.imports.length-8} more`}):null)):t("div",{class:"faint",text:"Nothing breaks this rule."})),p=t("div",{class:"rule",dataset:{key:n.key}},t("button",{class:"rule-h","aria-expanded":"false",on:{click:d=>gs(d.currentTarget.parentNode)}},t("span",{class:`ico-box ${n.state==="new"?"rem":n.state==="existing"?"viol":"good"}`},$(n.kind==="cycle"?"cycle":n.state==="pass"||n.state==="fixed"?"check":"alert")),t("span",null,t("div",{class:"nm",text:n.key}),t("div",{class:"sub",text:n.severity==="error"?"Error \xB7 fails CI":"Warning \xB7 reported only"})),t("span",{class:"scope sub",text:Ut(n)}),t("span",{class:"cnt sub num",text:n.viols.length?ee(n.viols.filter(d=>d.status!=="fixed").length,"break"):"\u2014"}),wt(n.state),$("right","chev")),t("div",{class:"rule-body"},t("div",null,i)));a.appendChild(p)}),e.append(a);let o=xe.find(n=>n.state==="new")||xe.find(n=>n.state==="existing");o&&gt(o.key)}function gs(e,s){let a=s??!e.classList.contains("open");e.classList.toggle("open",a),P(".rule-h",e).setAttribute("aria-expanded",String(a))}function gt(e){let s=oe(".rule").find(a=>a.dataset.key===e);s&&(gs(s,!0),setTimeout(()=>s.scrollIntoView({behavior:$e?"auto":"smooth",block:"nearest"}),60))}var K={items:[],filtered:[],idx:0};function vs(){let e=[];Pe.forEach(s=>e.push({group:"Pages",label:s.title,icon:s.icon,run:()=>se(s.id)})),ze.forEach(s=>e.push({group:"Modules",label:s.id,hint:ee(s.status==="removed"?s.filesBase:s.filesCur,"file"),icon:"box",run:()=>ve({type:"node",id:s.id})})),x.edges.forEach(s=>e.push({group:"Dependencies",label:`${Y(s.from)} \u2192 ${Y(s.to)}`,hint:M&&s.status!=="same"?s.status==="added"?"new":"removed":ee(s.countCur||s.countBase,"import"),icon:"link",run:()=>ve({type:"edge",id:s.id})})),(x.system?x.system.apps:[]).forEach(s=>e.push({group:"Architecture",label:`${s.name} (${s.framework} app)`,icon:ht(s),run:()=>{se("system"),setTimeout(()=>Ae({type:"app",id:s.id}),60)}})),(x.system?[...x.system.stores,...x.system.outside]:[]).forEach(s=>e.push({group:"Architecture",label:s.name,hint:s.kind,icon:x.system.stores.includes(s)?"database":"cloud",run:()=>{se("system"),setTimeout(()=>Ae({type:"svc",id:s.id}),60)}})),Fe.slice(0,5e3).forEach(s=>e.push({group:"Files",label:s.path,hint:s.module,icon:"file",run:()=>Me(s.module,s.path)})),(x.system?x.system.apps:[]).forEach(s=>Qe.forEach(({key:a,icon:o})=>(s.groups[a]||[]).forEach(n=>e.push({group:"Entry points",label:`${n.methods&&n.methods.length?`${n.methods.join("/")} `:""}${n.label}`,hint:n.human?`${n.human} \xB7 ${s.name}`:s.name,icon:o,run:()=>{se("system"),setTimeout(()=>Ae({type:"item",app:s.id,group:a,key:n.key}),60)}})))),xe.forEach(s=>e.push({group:"Rules",label:s.key,hint:{new:"new break",existing:"failing",fixed:"fixed",pass:"passing"}[s.state],icon:"shield",run:()=>{se("rules"),setTimeout(()=>gt(s.key),50)}})),e.push({group:"Actions",label:"Copy PR summary (Markdown)",icon:"copy",run:At}),e.push({group:"Actions",label:"Export map as SVG",icon:"image",run:()=>{se("map"),setTimeout(Lt,80)}}),e.push({group:"Actions",label:"Download report data (JSON)",icon:"download",run:()=>{let{markdown:s,...a}=x;Wt(new Blob([JSON.stringify(a,null,2)],{type:"application/json"}),`${x.project}-tecton.json`),We("JSON downloaded","download")}}),e.push({group:"Actions",label:"Switch to light theme",icon:"sun",run:()=>Ze("light")}),e.push({group:"Actions",label:"Switch to dark theme",icon:"moon",run:()=>Ze("dark")}),e.push({group:"Actions",label:"Use system theme",icon:"monitor",run:()=>Ze("system")}),K.items=e}function sa(e,s){if(!s)return 1;let a=e.toLowerCase(),o=a.indexOf(s);if(o>=0)return 100-o;let n=0;for(let i of s){if(n=a.indexOf(i,n),n<0)return 0;n++}return 10}function yt(){let e=P("#palette-ov");e.innerHTML="";let s=t("input",{placeholder:"Search modules, files, rules, actions\u2026","aria-label":"Command palette search",autocomplete:"off"}),a=t("div",{class:"pal-list",role:"listbox"});e.append(t("div",{class:"palette",role:"dialog","aria-label":"Command palette"},t("div",{class:"pal-in"},$("search"),s,t("span",{class:"kbd",text:"Esc"})),a,t("div",{class:"pal-foot"},t("span",null,t("span",{class:"kbd",text:"\u2191\u2193"}),"navigate"),t("span",null,t("span",{class:"kbd",text:"\u21B5"}),"open"),t("span",null,t("span",{class:"kbd",text:"Esc"}),"close"))));let o=()=>{let p=s.value.trim().toLowerCase();K.filtered=K.items.map(c=>({it:c,sc:sa(`${c.label} ${c.group}`,p)})).filter(c=>c.sc>0).sort((c,r)=>p?r.sc-c.sc:0).map(c=>c.it),p||(K.filtered=K.items.filter(c=>c.group==="Pages"||c.group==="Actions"||c.group==="Rules"||c.group==="Architecture").concat(K.items.filter(c=>c.group==="Modules").slice(0,6)));let d=["Pages","Architecture","Rules","Modules","Files","Entry points","Dependencies","Actions"];if(K.filtered.sort((c,r)=>d.indexOf(c.group)-d.indexOf(r.group)),K.filtered=K.filtered.slice(0,60),K.idx=Math.min(K.idx,Math.max(0,K.filtered.length-1)),a.innerHTML="",!K.filtered.length){a.appendChild(t("div",{class:"pal-empty",text:"No results"}));return}let l=null;K.filtered.forEach((c,r)=>{c.group!==l&&(a.appendChild(t("div",{class:"pal-group",text:c.group})),l=c.group);let u=t("div",{class:`pal-item${r===K.idx?" on":""}`,role:"option","aria-selected":String(r===K.idx),on:{mousemove:()=>{K.idx!==r&&(K.idx=r,n())},click:()=>i(r)}},$(c.icon),t("span",{class:"grow",text:c.label}),c.hint?t("span",{class:"faint",style:{fontSize:"12px"},text:c.hint}):null,t("span",{class:"enter",text:"\u21B5"}));u.dataset.i=r,a.appendChild(u)})},n=()=>{oe(".pal-item",a).forEach(p=>{let d=Number(p.dataset.i)===K.idx;p.classList.toggle("on",d),p.setAttribute("aria-selected",String(d)),d&&p.scrollIntoView({block:"nearest"})})},i=p=>{let d=K.filtered[p];vt(),d&&d.run()};s.addEventListener("input",()=>{K.idx=0,o()}),s.addEventListener("keydown",p=>{p.key==="ArrowDown"&&(p.preventDefault(),K.idx=Math.min(K.filtered.length-1,K.idx+1),n()),p.key==="ArrowUp"&&(p.preventDefault(),K.idx=Math.max(0,K.idx-1),n()),p.key==="Enter"&&(p.preventDefault(),i(K.idx))}),e.onclick=p=>{p.target===e&&vt()},K.idx=0,o(),e.classList.add("open"),setTimeout(()=>s.focus(),10)}function vt(){P("#palette-ov").classList.remove("open")}function Ze(e){e==="light"||e==="dark"?document.documentElement.setAttribute("data-theme",e):document.documentElement.removeAttribute("data-theme"),It.set("theme",e),oe(".theme-seg button").forEach(s=>s.setAttribute("aria-pressed",String(s.dataset.mode===e)))}var ys=()=>It.get("theme")||"system";function We(e,s="check"){let a=t("div",{class:"toast",role:"status"},$(s),e);P("#toasts").appendChild(a),setTimeout(()=>{a.classList.add("out"),setTimeout(()=>a.remove(),260)},2600)}function aa(e){return e==="rules"?Se.length?t("span",{class:`count${Ce?" bad":""}`},Se.length):null:e==="changes"?M?t("span",{class:"count"},Ne.length):null:e==="system"?x.system&&M&&x.system.summary.entry.added+x.system.summary.outside.added+x.system.summary.stores.added+x.system.summary.apps.added?t("span",{class:"count",text:"new"}):null:e==="modules"?t("span",{class:"count"},ze.filter(s=>s.status!=="removed").length):null}function bs(){let e=P("#sidebar"),s=x.project.replace(/[^A-Za-z0-9]/g,"").slice(0,2).toUpperCase()||"AD";e.append(t("div",{class:"logo"},t("div",{class:"logo-mark","aria-hidden":"true"},v("svg",{viewBox:"0 0 64 64",html:qt})),t("b",{text:"tecton"}),t("span",{class:"ver",text:`v${x.version||"0"}`})),t("div",{class:"project"},t("div",{class:"name"},t("span",{class:"avatar",text:s}),t("span",{text:x.project,title:x.project})),t("div",{class:"compare"},$("branch"),t("span",{class:"ref",text:x.curLabel,title:x.curLabel}),M?[t("span",{class:"vs",text:"vs"}),t("span",{class:"ref",text:Xe(),title:x.baseLabel})]:[t("span"),t("span",{class:"faint",text:"snapshot only"})])),t("div",{class:"nav-label",text:"Report"}),t("nav",{class:"nav","aria-label":"Pages"},Pe.map(a=>t("a",{href:`#${a.id}`,dataset:{page:a.id}},$(a.icon),t("span",{text:a.title}),aa(a.id)))),t("div",{class:"side-foot"},t("div",{class:"theme-seg",role:"group","aria-label":"Theme"},[["system","monitor","System theme"],["light","sun","Light theme"],["dark","moon","Dark theme"]].map(([a,o,n])=>t("button",{dataset:{mode:a},"aria-label":n,title:n,on:{click:()=>Ze(a)}},$(o)))),t("div",{class:"gen"},$("clock"),t("span",{text:`Generated ${Qt(x.generatedAt)}`})))),oe(".nav a",e).forEach(a=>a.addEventListener("click",()=>Bt()))}function Xe(){return(x.baseLabel||"").replace(/\s*\(.*$/,"")}function na(){P("#sidebar").classList.add("open"),P("#scrim").classList.add("open")}function Bt(){P("#sidebar").classList.remove("open"),P("#scrim").classList.remove("open")}function xs(){P("#topbar").append(t("button",{class:"btn icon ghost menu-btn","aria-label":"Open menu",on:{click:na}},$("menu")),t("div",{class:"crumbs"},t("span",{class:"muted hide-sm",text:x.project}),t("span",{class:"sep hide-sm",text:"/"}),t("span",{class:"cur",id:"crumb-cur",text:"Overview"})),t("div",{class:"top-actions"},t("button",{class:"search-btn",on:{click:yt},"aria-label":"Search"},$("search"),t("span",{class:"lbl-t",text:"Search modules, rules\u2026"}),t("span",{class:"kbd",text:navigator.platform.includes("Mac")?"\u2318K":"Ctrl K"})),t("span",{class:`status-pill ${Ce?"fail":"pass"}`,title:Ce?"This change would fail the CI check":"This change passes the CI check"},t("span",{class:"pulse"}),t("span",{class:"lbl-t",text:Ce?"Check failing":"Check passing"})),t("button",{class:"btn",on:{click:At}},$("copy"),t("span",{class:"lbl-t",text:"Copy PR summary"}))))}function ws(){let e=P("#page-changes");if(e.append(t("div",{class:"page-head"},t("div",null,t("h1",{text:"Changes"}),t("p",{text:M?`Every module and dependency that differs from ${Xe()}.`:"Nothing to compare against \u2014 run Tecton inside a git repo with a main branch."})))),!M){e.append(t("div",{class:"card"},t("div",{class:"empty-state"},t("div",{class:"ico-box"},$("compare")),t("h4",{text:"No comparison"}),t("p",{text:"Commit your code to git and create a main branch, or pass --base <branch>."}))));return}let s="all",a="",o=r=>Ne.filter(u=>r==="all"||u.kind===r).length,n=He([{value:"all",label:"All",count:o("all")},{value:"added",label:"Added",count:o("added")},{value:"removed",label:"Removed",count:o("removed")},{value:"changed",label:"Changed",count:o("changed")}],s,r=>{s=r,c()}),i=t("input",{type:"search",placeholder:"Filter by module\u2026","aria-label":"Filter changes",on:{input:r=>{a=r.target.value.toLowerCase(),c()}}}),p=t("tbody"),d=t("div",{class:"card"},t("div",{class:"tbl-wrap"},t("table",null,t("thead",null,t("tr",null,t("th",{text:"Change"}),t("th",{text:"What"}),t("th",{class:"r",text:"Imports"}),t("th",{text:"Rules"}),t("th"))),p))),l=t("div",{class:"empty-state",style:{display:"none"}},t("div",{class:"ico-box"},$("search")),t("h4",{text:"No matching changes"}),t("p",{text:"Try a different filter."}));d.appendChild(l);function c(){p.innerHTML="";let r=Ne.filter(u=>(s==="all"||u.kind===s)&&(!a||u.label.toLowerCase().includes(a)));r.forEach((u,m)=>{let g=u.edge,f=g?Ie.cur.get(g.id)||[]:[],y=t("tr",{class:"click enter",style:{animationDelay:`${Math.min(m,12)*.025}s`},on:{click:()=>ve({type:u.type,id:u.id})}},t("td",null,he(u.kind)),t("td",null,t("div",{class:"cell-mod"},t("span",{class:`ico-box ${u.viol?"viol":u.kind==="added"?"add":u.kind==="removed"?"rem":"chg"}`,style:{width:"26px",height:"26px"}},$(u.type==="node"?"box":"link")),u.type==="node"?t("span",null,u.label,t("span",{class:"faint",text:u.kind==="added"?" \xB7 new module":" \xB7 module removed"})):t("span",null,Y(g.from),t("span",{class:"arrow",text:" \u2192 "}),Y(g.to)))),t("td",{class:"r num mono"},u.type==="node"?t("span",{class:"faint",text:u.sub}):g.status==="same"?`${g.countBase} \u2192 ${g.countCur}`:g.status==="added"?`+${g.countCur}`:`\u2212${g.countBase}`),t("td",null,f.length?f.map(D=>t("span",{class:`badge ${D.status==="new"?D.severity==="error"?"critical":"warn":"neutral"}`,text:D.rule,style:{marginRight:"4px"}})):t("span",{class:"faint",text:"\u2014"})),t("td",{class:"r"},$("right","faint")));p.appendChild(y)}),l.style.display=r.length?"none":"block"}c(),e.append(t("div",{class:"toolbar"},n,t("label",{class:"input"},$("search"),i)),d)}function $s(){let e=P("#page-modules");e.append(t("div",{class:"page-head"},t("div",null,t("h1",{text:"Modules"}),t("p",{text:"Each folder Tecton treats as one part of the app, with how much it uses and is used. Open one to see its files."}))));let s={k:"files",dir:-1},a="",o=!1,n=x.nodes.map(f=>({n:f,...Ee.get(f.id),files:f.status==="removed"?f.filesBase:f.filesCur,edited:f.touched||0})),i=Math.max(1,...n.map(f=>f.files)),p=[["name","Module"],["status","Status"],["files","Files"],...Ke?[["edited","Edited"]]:[],["uses","Uses"],["usedBy","Used by"],["viol","Rule breaks"]],d=t("tr");p.forEach(([f,y])=>d.appendChild(t("th",{class:`sortable${f==="uses"||f==="usedBy"||f==="viol"||f==="edited"?" r":""}`,dataset:{k:f},on:{click:()=>{s={k:f,dir:s.k===f?-s.dir:f==="name"?1:-1},u()}}},y,t("span",{class:"sort"}))));let l=t("tbody"),c=t("input",{type:"search",placeholder:"Search modules\u2026","aria-label":"Search modules",on:{input:f=>{a=f.target.value.toLowerCase(),u()}}});function r(f,y){return y==="name"?f.n.id:y==="status"?f.n.status:f[y]}function u(){oe("th",d.parentNode||d).forEach(f=>{let y=P(".sort",f);y&&(y.textContent=f.dataset.k===s.k?s.dir>0?" \u2191":" \u2193":"")}),l.innerHTML="",n.filter(f=>(!a||f.n.id.toLowerCase().includes(a))&&(!o||f.edited)).sort((f,y)=>{let D=r(f,s.k),F=r(y,s.k);return(D>F?1:D<F?-1:0)*s.dir||f.n.id.localeCompare(y.n.id)}).forEach((f,y)=>{let D=f.n,F=()=>D.external?ve({type:"node",id:D.id}):Me(D.id);l.appendChild(t("tr",{class:"click enter",tabindex:0,style:{animationDelay:`${Math.min(y,12)*.02}s`},on:{click:F,keydown:ne=>{ne.key==="Enter"&&F()}}},t("td",null,t("div",{class:"cell-mod"},t("span",{class:`ico-box ${D.status==="added"?"add":D.status==="removed"?"rem":""}`,style:{width:"26px",height:"26px"}},$(D.external?"pkg":"box")),Y(D.id),D.external?t("span",{class:"faint",text:" \xB7 npm"}):null)),t("td",null,M&&D.status!=="same"?he(D.status):t("span",{class:"faint",text:D.external?"Package":"Unchanged"})),t("td",{class:"num"},D.external?t("span",{class:"faint",text:"\u2014"}):[t("span",{class:"mini-bar"},t("i",{style:{width:`${f.files/i*100}%`}})),M&&D.filesBase!==D.filesCur?`${D.filesBase} \u2192 ${D.filesCur}`:String(f.files)]),Ke?t("td",{class:"r num"},f.edited?t("span",{class:"chip acc",text:String(f.edited)}):t("span",{class:"faint",text:"0"})):null,t("td",{class:"r num",text:f.uses}),t("td",{class:"r num",text:f.usedBy}),t("td",{class:"r"},f.viol?de("serious",String(f.viol)):t("span",{class:"faint",text:"0"}))))})}let m=t("table",null,t("thead",null,d),l),g=Ke?t("label",{class:"switch"},t("input",{type:"checkbox",on:{change:f=>{o=f.target.checked,u()}}}),"Only modules this change touches"):null;e.append(t("div",{class:"toolbar"},t("label",{class:"input"},$("search"),c),g),t("div",{class:"card"},t("div",{class:"tbl-wrap"},m))),u()}window.addEventListener("hashchange",()=>st(location.hash.slice(1)));document.addEventListener("keydown",e=>{let s=/^(INPUT|TEXTAREA)$/.test(document.activeElement?.tagName);if((e.metaKey||e.ctrlKey)&&e.key.toLowerCase()==="k"){e.preventDefault(),P("#palette-ov").classList.contains("open")?vt():yt();return}if(e.key==="Escape"){P("#palette-ov").classList.contains("open")?vt():P("#sheet")&&P("#sheet").classList.contains("open")?_e():E.selected?Te(null):Bt();return}s||(e.key==="/"&&(e.preventDefault(),yt()),E.page==="map"&&(e.key==="f"||e.key==="F")&&at(!0),E.page==="system"&&(e.key==="f"||e.key==="F")&&Ge(!0),/^[1-6]$/.test(e.key)&&!e.metaKey&&!e.ctrlKey&&!e.altKey&&se(Pe[Number(e.key)-1].id))});bs();xs();ms();ps();ct();fs();ws();$s();vs();Ze(ys());P("#scrim").addEventListener("click",Bt);(()=>{let e=P("#preview");if(!e||!O.world)return;let s=30,a=v("svg",{viewBox:`${-s} ${-s} ${x.width+s*2} ${x.height+s*2}`,preserveAspectRatio:"xMidYMid meet","aria-hidden":"true"}),o=O.world.cloneNode(!0);o.removeAttribute("id"),oe("[id], [tabindex], [role], [aria-label]",o).forEach(n=>["id","tabindex","role","aria-label"].forEach(i=>n.removeAttribute(i))),a.appendChild(o),e.insertBefore(a,e.firstChild)})();window.addEventListener("resize",()=>{et(),E.page==="map"&&!E.selected&&at(!1),E.page==="system"&&Ge(!1)});st(location.hash.slice(1)||"overview");})();
@@ -0,0 +1,92 @@
1
+ Copyright (c) 2023 Vercel, in collaboration with basement.studio
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ http://scripts.sil.org/OFL
6
+
7
+ -----------------------------------------------------------
8
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
9
+ -----------------------------------------------------------
10
+
11
+ PREAMBLE
12
+ The goals of the Open Font License (OFL) are to stimulate worldwide
13
+ development of collaborative font projects, to support the font creation
14
+ efforts of academic and linguistic communities, and to provide a free and
15
+ open framework in which fonts may be shared and improved in partnership
16
+ with others.
17
+
18
+ The OFL allows the licensed fonts to be used, studied, modified and
19
+ redistributed freely as long as they are not sold by themselves. The
20
+ fonts, including any derivative works, can be bundled, embedded,
21
+ redistributed and/or sold with any software provided that any reserved
22
+ names are not used by derivative works. The fonts and derivatives,
23
+ however, cannot be released under any other type of license. The
24
+ requirement for fonts to remain under this license does not apply
25
+ to any document created using the fonts or their derivatives.
26
+
27
+ DEFINITIONS
28
+ "Font Software" refers to the set of files released by the Copyright
29
+ Holder(s) under this license and clearly marked as such. This may
30
+ include source files, build scripts and documentation.
31
+
32
+ "Reserved Font Name" refers to any names specified as such after the
33
+ copyright statement(s).
34
+
35
+ "Original Version" refers to the collection of Font Software components as
36
+ distributed by the Copyright Holder(s).
37
+
38
+ "Modified Version" refers to any derivative made by adding to, deleting,
39
+ or substituting -- in part or in whole -- any of the components of the
40
+ Original Version, by changing formats or by porting the Font Software to a
41
+ new environment.
42
+
43
+ "Author" refers to any designer, engineer, programmer, technical
44
+ writer or other person who contributed to the Font Software.
45
+
46
+ PERMISSION AND CONDITIONS
47
+ Permission is hereby granted, free of charge, to any person obtaining
48
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
49
+ redistribute, and sell modified and unmodified copies of the Font
50
+ Software, subject to the following conditions:
51
+
52
+ 1) Neither the Font Software nor any of its individual components,
53
+ in Original or Modified Versions, may be sold by itself.
54
+
55
+ 2) Original or Modified Versions of the Font Software may be bundled,
56
+ redistributed and/or sold with any software, provided that each copy
57
+ contains the above copyright notice and this license. These can be
58
+ included either as stand-alone text files, human-readable headers or
59
+ in the appropriate machine-readable metadata fields within text or
60
+ binary files as long as those fields can be easily viewed by the user.
61
+
62
+ 3) No Modified Version of the Font Software may use the Reserved Font
63
+ Name(s) unless explicit written permission is granted by the corresponding
64
+ Copyright Holder. This restriction only applies to the primary font name as
65
+ presented to the users.
66
+
67
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
68
+ Software shall not be used to promote, endorse or advertise any
69
+ Modified Version, except to acknowledge the contribution(s) of the
70
+ Copyright Holder(s) and the Author(s) or with their explicit written
71
+ permission.
72
+
73
+ 5) The Font Software, modified or unmodified, in part or in whole,
74
+ must be distributed entirely under this license, and must not be
75
+ distributed under any other license. The requirement for fonts to
76
+ remain under this license does not apply to any document created
77
+ using the Font Software.
78
+
79
+ TERMINATION
80
+ This license becomes null and void if any of the above conditions are
81
+ not met.
82
+
83
+ DISCLAIMER
84
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
85
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
86
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
87
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
88
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
89
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
90
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
91
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
92
+ OTHER DEALINGS IN THE FONT SOFTWARE.