diff --git a/README.md b/README.md index a34a5ed..c3f0747 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ actually read (and which hot ones nobody maintains). device only writes its own append-only journal, so no locking service is needed; the hub can be backed by any object store. - **Change tracking** — `bdrive log` and the web UI's History view show - which account changed which file, when, from which device (name, OS, IP). + which account changed which file, when, from which device (name, OS). Content is stored content-addressed, so every version is retained — view or download any point in a file's history. - **Cloud-provider agnostic** — a hub can store on Amazon S3 (`s3://`), @@ -471,8 +471,8 @@ The web UI lists your orgs' projects in the sidebar (⌘K opens a command palette: fuzzy file search, project switching, share/history/upload actions); selecting one browses that project's files, and the **History** view shows every change — which -account made it, when, from which device (name, OS, and the IP the server -observed), with view/download of any past version (content is +account made it, when, from which device (name and OS — never the connecting +IP), with view/download of any past version (content is content-addressed and retained forever; reverting to a version is the next phase and the API is already shaped for it). Folder rows have a history shortcut for a subtree feed; the topbar button shows the current file's diff --git a/internal/webapp/devices.go b/internal/webapp/devices.go index da7fa07..ebbd892 100644 --- a/internal/webapp/devices.go +++ b/internal/webapp/devices.go @@ -11,8 +11,9 @@ import ( // DeviceInfo is what the server knows about one syncing device: self-reported // name/OS (headers sent by the client), plus what the server itself observed // (public IP of the last push, last activity, the signed-in account). History -// joins ops against this registry, so IPs are real — as the server saw them — -// and ops stay small. +// joins ops against this registry so ops stay small — but it reports only +// id/name/os (historyDevice, history.go): the IP is recorded here, not +// repeated to every project member on every change. type DeviceInfo struct { ID string `json:"id"` Name string `json:"name,omitempty"` diff --git a/internal/webapp/frontend/src/api/types.ts b/internal/webapp/frontend/src/api/types.ts index 34eec21..58929f5 100644 --- a/internal/webapp/frontend/src/api/types.ts +++ b/internal/webapp/frontend/src/api/types.ts @@ -158,7 +158,6 @@ export interface DeviceInfo { id?: string; name?: string; os?: string; - ip?: string; } export interface HistoryEntry { time: string; diff --git a/internal/webapp/frontend/src/components/HistoryRow.tsx b/internal/webapp/frontend/src/components/HistoryRow.tsx index 99f721c..33b65fb 100644 --- a/internal/webapp/frontend/src/components/HistoryRow.tsx +++ b/internal/webapp/frontend/src/components/HistoryRow.tsx @@ -85,7 +85,7 @@ export function HistoryRow({ const [diffOpen, setDiffOpen] = useState(false); const kind = e.kind === "put" ? "edit" : e.kind; // older servers report raw "put" ops const who = whoChanged(e); - const dev = [e.device.name || e.device.id, e.device.os, e.device.ip].filter(Boolean).join(" · "); + const dev = [e.device.name || e.device.id, e.device.os].filter(Boolean).join(" · "); const clickable = kind !== "delete"; // A delete has no content, and a first version has nothing behind it. const diffable = !!diff && kind !== "delete" && !!e.blob; diff --git a/internal/webapp/history.go b/internal/webapp/history.go index e5934cd..6f8b107 100644 --- a/internal/webapp/history.go +++ b/internal/webapp/history.go @@ -19,18 +19,29 @@ import ( // the revert/rollback phase, where restoring is just writing an old blob // back as a new op. +// historyDevice is the slice of the device registry history is allowed to +// report: who/what made the change, not where they connected from. The +// registry keeps observing and persisting the IP (devices.go) — it just +// doesn't ride along here, where every project member reads it. Mirrors +// heatByDevice (reads.go). +type historyDevice struct { + ID string `json:"id"` + Name string `json:"name,omitempty"` + OS string `json:"os,omitempty"` +} + // HistoryEntry is one change as the history API reports it. type HistoryEntry struct { - Time string `json:"time"` - Kind string `json:"kind"` // add | edit | delete - Path string `json:"path"` - Size int64 `json:"size,omitempty"` - Blob string `json:"blob,omitempty"` // sha256; fetch via the blob endpoint - User string `json:"user,omitempty"` - UserName string `json:"user_name,omitempty"` - Author string `json:"author,omitempty"` // offline/git fallback identity - Device DeviceInfo `json:"device"` - Note string `json:"note,omitempty"` + Time string `json:"time"` + Kind string `json:"kind"` // add | edit | delete + Path string `json:"path"` + Size int64 `json:"size,omitempty"` + Blob string `json:"blob,omitempty"` // sha256; fetch via the blob endpoint + User string `json:"user,omitempty"` + UserName string `json:"user_name,omitempty"` + Author string `json:"author,omitempty"` // offline/git fallback identity + Device historyDevice `json:"device"` + Note string `json:"note,omitempty"` } // handleHistory serves ?path= (one file's versions) or @@ -92,9 +103,11 @@ func (s *Server) handleHistory(v *volume, w http.ResponseWriter, r *http.Request case path == "" && prefix != "" && !strings.HasPrefix(op.Path, strings.TrimSuffix(prefix, "/")+"/"): continue } - dev, _ := s.Devices.Get(op.Device) - if dev.ID == "" { - dev = DeviceInfo{ID: op.Device, Name: op.DeviceName} + // Unregistered device (or volume mode, where Devices is nil): fall back + // to the op's own id + self-reported name. + dev := historyDevice{ID: op.Device, Name: op.DeviceName} + if info, ok := s.Devices.Get(op.Device); ok && info.ID != "" { + dev = historyDevice{ID: info.ID, Name: info.Name, OS: info.OS} } matched = append(matched, timed{HistoryEntry{ Time: op.Time.UTC().Format("2006-01-02T15:04:05Z"), Kind: kinds[i], diff --git a/internal/webapp/history_test.go b/internal/webapp/history_test.go index 030ba31..061fbc8 100644 --- a/internal/webapp/history_test.go +++ b/internal/webapp/history_test.go @@ -100,10 +100,23 @@ func TestHistoryAPI(t *testing.T) { if newest.User != "alice@x.io" || newest.UserName != "Alice" { t.Fatalf("user = %+v", newest) } - // device joined from the registry: name, OS, server-observed IP - if newest.Device.Name != "alice-laptop" || newest.Device.OS != "darwin/arm64" || newest.Device.IP != "203.0.113.7" { + // device joined from the registry: name and OS only — the server-observed + // IP stays in the registry and out of every member's history feed (BEA-43). + // The id always rides along, so a nameless device still renders as something. + if newest.Device.ID != "dev1" || newest.Device.Name != "alice-laptop" || newest.Device.OS != "darwin/arm64" { t.Fatalf("device = %+v", newest.Device) } + // asserted on the raw body, not the struct: a typed unmarshal would pass + // even if the server still emitted the key. + if strings.Contains(rec.Body.String(), "203.0.113.7") { + t.Fatalf("history response leaks the device IP: %s", rec.Body) + } + if strings.Contains(rec.Body.String(), "last_seen") { + t.Fatalf("history response carries registry internals: %s", rec.Body) + } + if d, ok := srv.Devices.Get("dev1"); !ok || d.IP != "203.0.113.7" { + t.Fatalf("registry must keep observing the IP: %+v %v", d, ok) + } if newest.Blob == "" || oldest.Blob == "" { t.Fatal("entries must link to their exact content") } @@ -124,9 +137,13 @@ func TestHistoryAPI(t *testing.T) { t.Fatalf("entry before the delete = %+v, want other.md's add", out.Entries[1]) } // a device the registry never saw falls back to the op's own info - if out.Entries[0].Device.Name != "dev2" { + if out.Entries[0].Device.ID != "dev2" || out.Entries[0].Device.Name != "dev2" { t.Fatalf("unknown device fallback = %+v", out.Entries[0].Device) } + // the prefix feed is the same projection — no IP there either + if strings.Contains(rec.Body.String(), "203.0.113.7") { + t.Fatalf("prefix feed leaks the device IP: %s", rec.Body) + } // whole-project feed + n limit rec = do(t, h, "GET", base+"history?n=2", nil) diff --git a/internal/webapp/static/assets/index-CPLO3Qr5.js b/internal/webapp/static/assets/index-344uOWlP.js similarity index 92% rename from internal/webapp/static/assets/index-CPLO3Qr5.js rename to internal/webapp/static/assets/index-344uOWlP.js index 356d99a..a987a9b 100644 --- a/internal/webapp/static/assets/index-CPLO3Qr5.js +++ b/internal/webapp/static/assets/index-344uOWlP.js @@ -117,4 +117,4 @@ to set up BearDrive project `+e.id+" on "+n+'. Ask me which folder to sync (the bdrive login `+n+` bdrive init --project `+e.id;return h.jsxs("div",{className:"guide",children:[h.jsxs("h1",{className:"in-title gd-head",children:[h.jsx("span",{className:"proj-mark","aria-hidden":"true",style:{background:dl(e.name)},children:h.jsx(La,{name:e.icon})}),e.name]}),e.description&&h.jsx("p",{className:"in-desc",children:e.description}),h.jsxs("div",{className:"gd-body",children:[h.jsx("p",{className:"gd-desc",children:"Paste into your coding agent — Claude Code, Cowork, Codex, Gemini CLI, Hermes — in the folder where you want the files:"}),h.jsx(Gm,{code:r}),h.jsx("p",{className:"gd-desc",children:"The agent installs the CLI, signs this machine in, and registers the sync hooks — asking before anything it changes."}),h.jsxs("details",{className:"gd-manual",children:[h.jsx("summary",{children:"What exactly happens"}),h.jsxs("ul",{className:"gd-desc gd-list",children:[h.jsx("li",{children:"Sign-in uses a device code you approve in this browser — the folder itself never holds credentials."}),h.jsx("li",{children:"Sync hooks pull the latest before every agent turn, push edits seconds after they happen, and stamp each change with the session that made it; agent reads feed Insights. They register once per machine in your agent's own config, so every session is covered and nothing is written into the synced folder."}),h.jsx("li",{children:"Codex hooks are off by default: set [features] codex_hooks = true in ~/.codex/config.toml."})]})]}),h.jsxs("details",{className:"gd-manual",children:[h.jsx("summary",{children:"Or run it yourself"}),h.jsx("p",{className:"gd-desc",children:"Same result, in the folder you want the files. One command: init signs this device in, registers the sync hooks and starts syncing."}),h.jsx(Gm,{code:o}),h.jsx("p",{className:"gd-desc",children:h.jsx("a",{href:"https://docs.beardrive.ai/manual/install/",target:"_blank",rel:"noreferrer",children:"Full manual setup guide →"})})]})]})]})}function Gm({code:e}){const[n,r]=w.useState("Copy");return h.jsxs("pre",{className:"gd-code",children:[h.jsx("code",{children:e}),h.jsx("button",{className:"gd-copy",onClick:async()=>{r(await Ha(e)?"Copied":"Copy failed"),setTimeout(()=>r("Copy"),1400)},children:n})]})}function N8(){return h.jsxs("div",{className:"onboard",children:[h.jsx("h1",{children:"Welcome to BearDrive"}),h.jsx("p",{children:"You're signed in, but you're not part of any project yet."}),h.jsxs("div",{className:"ob-card",children:[h.jsx("h3",{children:"Connect a new drive to your project"}),h.jsx("p",{children:"Paste into your coding agent — Claude Code, Cowork, Codex, Gemini CLI, Hermes — in the folder where you want the files. It creates the project and starts syncing:"}),h.jsx(Gm,{code:"Follow "+AC+` to set up a new BearDrive project on `+window.location.origin+". Ask me which folder to sync."}),h.jsx("p",{className:"ob-alt",children:h.jsx("a",{href:"https://docs.beardrive.ai/manual/setup-by-hand/",target:"_blank",rel:"noreferrer",children:"Or start a project manually →"})})]})]})}function nw(e,n,r){if(!e)return null;if(!r)return e[n]||null;const o={human:0,agent:0,share:0};for(const[s,l]of Object.entries(e))s.startsWith(n+"/")&&(o.human+=l.human||0,o.agent+=l.agent||0,o.share+=l.share||0);return o.human||o.agent||o.share?o:null}function Ba(e){return(e.human||0)+(e.agent||0)+(e.share||0)}function Ys(e){const n=Ba(e);if(!n)return"";const r=n+(n===1?" read":" reads");if(!e.agent&&!e.share)return r;const o=[];return e.human&&o.push(e.human+" human"),e.agent&&o.push(e.agent+" agent"),e.share&&o.push(e.share+" shared"),r+" ("+o.join(", ")+")"}function D8(e){const n=Ba(e);return n?n<3?1:n<10?2:n<30?3:4:0}function z8(e){const n=Ba(e);return n?{agent:(e.agent||0)/n,human:(e.human||0)/n,share:(e.share||0)/n}:{agent:0,human:0,share:0}}const k8=7;function L8(e){if(!e.length)return null;let n=e[0],r=e[0];for(const o of e)or&&(r=o);return{min:n,max:r}}const $8=(e,n)=>n-esn(e+"tree"),enabled:n,refetchInterval:15e3}),o=w.useMemo(()=>{const s=[],l=new Map,u=d=>{for(const p of d.children||[])p.dir?(l.set(p.path,p),u(p)):s.push(p)};return r.data&&u(r.data),{flatFiles:s,dirIndex:l}},[r.data]);return{tree:r.data,...o,loaded:!!r.data}}function V8(e,n){return Ht({queryKey:["heat",e],queryFn:()=>sn(e+"heat?days=30"),enabled:n,staleTime:6e4,refetchInterval:6e4}).data?.entries??null}function P8(e,n,r){return Ht({queryKey:["history",e,"prefix",n,20],queryFn:()=>sn(e+"history?prefix="+encodeURIComponent(n)+"&n=20"),enabled:r,staleTime:15e3}).data?.entries??null}function U8(e,n,r){const o=new Array(e);return new Proxy(o,{get(s,l,u){if(typeof l=="string"){const d=l.charCodeAt(0);if(d>=48&&d<=57){const p=+l;if(Number.isInteger(p)&&p>=0&&po[y]!==m))&&(o=d,s=n(...d),r?.onChange&&!(l&&r.skipInitialOnChange)&&r.onChange(s),l=!1),s}return u.updateDeps=d=>{o=d},u}function rw(e,n){if(e===void 0)throw new Error("Unexpected undefined");return e}const H8=(e,n)=>Math.abs(e-n)<1.01,B8=(e,n,r)=>{let o;return function(...s){e.clearTimeout(o),o=e.setTimeout(()=>n.apply(this,s),r)}};let Bs;const tm=()=>{if(Bs!==void 0)return Bs;if(typeof navigator>"u")return Bs=!1;if(/iP(hone|od|ad)/.test(navigator.userAgent))return Bs=!0;const e=navigator.maxTouchPoints;return Bs=navigator.platform==="MacIntel"&&e!==void 0&&e>0},iw=e=>{const{offsetWidth:n,offsetHeight:r}=e;return{width:n,height:r}},q8=e=>e,G8=e=>{const n=Math.max(e.startIndex-e.overscan,0),o=Math.min(e.endIndex+e.overscan,e.count-1)-n+1,s=new Array(o);for(let l=0;l{const r=e.scrollElement;if(!r)return;const o=e.targetWindow;if(!o)return;const s=u=>{const{width:d,height:p}=u;n({width:Math.round(d),height:Math.round(p)})};if(s(iw(r)),!o.ResizeObserver)return()=>{};const l=new o.ResizeObserver(u=>{const d=()=>{const p=u[0];if(p?.borderBoxSize){const m=p.borderBoxSize[0];if(m){s({width:m.inlineSize,height:m.blockSize});return}}s(iw(r))};e.options.useAnimationFrameWithResizeObserver?requestAnimationFrame(d):d()});return l.observe(r,{box:"border-box"}),()=>{l.unobserve(r)}},Ru={passive:!0},K8=typeof window>"u"?!0:"onscrollend"in window,Y8=(e,n,r)=>{const o=e.scrollElement;if(!o)return;const s=e.targetWindow;if(!s)return;const l=e.options.useScrollendEvent&&K8;let u=0;const d=l?null:B8(s,()=>n(u,!1),e.options.isScrollingResetDelay),p=v=>()=>{u=r(o),d?.(),n(u,v)},m=p(!0),y=p(!1);return o.addEventListener("scroll",m,Ru),l&&o.addEventListener("scrollend",y,Ru),()=>{o.removeEventListener("scroll",m),l&&o.removeEventListener("scrollend",y)}},Q8=(e,n)=>Y8(e,n,r=>{const{horizontal:o,isRtl:s}=e.options;return o?r.scrollLeft*(s&&-1||1):r.scrollTop}),X8=(e,n,r)=>{if(r.options.useCachedMeasurements){const o=r.indexFromElement(e),s=r.options.getItemKey(o);return r.itemSizeCache.get(s)??r.options.estimateSize(o)}if(n?.borderBoxSize){const o=n.borderBoxSize[0];if(o)return Math.round(o[r.options.horizontal?"inlineSize":"blockSize"])}if(!n){const o=r.indexFromElement(e),s=r.options.getItemKey(o),l=r.itemSizeCache.get(s);if(l!==void 0)return l}return e[r.options.horizontal?"offsetWidth":"offsetHeight"]},J8=(e,{adjustments:n=0,behavior:r},o)=>{var s,l;(l=(s=o.scrollElement)==null?void 0:s.scrollTo)==null||l.call(s,{[o.options.horizontal?"left":"top"]:e+n,behavior:r})},W8=J8;class eI{constructor(n){this.unsubs=[],this.scrollElement=null,this.targetWindow=null,this.isScrolling=!1,this.scrollState=null,this.measurementsCache=[],this._flatMeasurements=null,this.itemSizeCache=new Map,this.itemSizeCacheVersion=0,this.laneAssignments=new Map,this.pendingMin=null,this.prevLanes=void 0,this.lanesChangedFlag=!1,this.lanesSettling=!1,this.pendingScrollAnchor=null,this.scrollRect=null,this.scrollOffset=null,this.scrollDirection=null,this.scrollAdjustments=0,this._iosDeferredAdjustment=0,this._iosTouching=!1,this._iosJustTouchEnded=!1,this._iosTouchEndTimerId=null,this._intendedScrollOffset=null,this.elementsCache=new Map,this.now=()=>{var r,o,s;return((s=(o=(r=this.targetWindow)==null?void 0:r.performance)==null?void 0:o.now)==null?void 0:s.call(o))??Date.now()},this.observer=(()=>{let r=null;const o=()=>r||(!this.targetWindow||!this.targetWindow.ResizeObserver?null:r=new this.targetWindow.ResizeObserver(s=>{s.forEach(l=>{const u=()=>{const d=l.target,p=this.indexFromElement(d);if(!d.isConnected){this.observer.unobserve(d);for(const[m,y]of this.elementsCache)if(y===d){this.elementsCache.delete(m);break}return}this.shouldMeasureDuringScroll(p)&&this.resizeItem(p,this.options.measureElement(d,l,this))};this.options.useAnimationFrameWithResizeObserver?requestAnimationFrame(u):u()})}));return{disconnect:()=>{var s;(s=o())==null||s.disconnect(),r=null},observe:s=>{var l;return(l=o())==null?void 0:l.observe(s,{box:"border-box"})},unobserve:s=>{var l;return(l=o())==null?void 0:l.unobserve(s)}}})(),this.range=null,this.setOptions=r=>{var o,s;const l={debug:!1,initialOffset:0,overscan:1,paddingStart:0,paddingEnd:0,scrollPaddingStart:0,scrollPaddingEnd:0,horizontal:!1,getItemKey:q8,rangeExtractor:G8,onChange:()=>{},measureElement:X8,initialRect:{width:0,height:0},scrollMargin:0,gap:0,indexAttribute:"data-index",initialMeasurementsCache:[],lanes:1,anchorTo:"start",followOnAppend:!1,scrollEndThreshold:1,isScrollingResetDelay:150,enabled:!0,isRtl:!1,useScrollendEvent:!1,useAnimationFrameWithResizeObserver:!1,laneAssignmentMode:"estimate",useCachedMeasurements:!1};for(const b in r){const x=r[b];x!==void 0&&(l[b]=x)}const u=this.options;let d=null,p=null,m=!1;if(u!==void 0&&u.enabled&&l.enabled&&l.anchorTo==="end"&&this.scrollElement!==null){const b=u.count,x=l.count,C=this.getMeasurements(),_=b>0?((o=C[0])==null?void 0:o.key)??u.getItemKey(0):null,E=b>0?((s=C[b-1])==null?void 0:s.key)??u.getItemKey(b-1):null;if(x!==b||b>0&&x>0&&(l.getItemKey(0)!==_||l.getItemKey(x-1)!==E)){m=!0;const O=b>0?this.getVirtualItemForOffset(this.getScrollOffset())??C[0]:null;O&&(d=[O.key,this.getScrollOffset()-O.start]);const k=l.followOnAppend===!0?"auto":l.followOnAppend||null;k&&x>b&&this.isAtEnd(u.scrollEndThreshold)&&(b===0||l.getItemKey(x-1)!==E)&&(p=k)}}this.options=l,m&&(this.pendingMin=0,this.itemSizeCacheVersion++);let y=!1,v=0;if(d&&this.scrollOffset!==null){const[b,x]=d,C=this.getMeasurements(),{count:_,getItemKey:E}=this.options;let T=0;for(;T<_&&E(T)!==b;)T++;if(T<_){const j=C[T];if(j){const O=j.start+x;O!==this.scrollOffset&&(v=O-this.scrollOffset,this.scrollOffset=O,y=!0)}}}(y||p)&&(this.pendingScrollAnchor=[y?d[0]:null,y?d[1]:0,p,v])},this.notify=r=>{var o,s;(s=(o=this.options).onChange)==null||s.call(o,this,r)},this.maybeNotify=ja(()=>(this.calculateRange(),[this.isScrolling,this.range?this.range.startIndex:null,this.range?this.range.endIndex:null]),r=>{this.notify(r)},{key:!1,debug:()=>this.options.debug,initialDeps:[this.isScrolling,this.range?this.range.startIndex:null,this.range?this.range.endIndex:null]}),this.cleanup=()=>{this.unsubs.filter(Boolean).forEach(r=>r()),this.unsubs=[],this.observer.disconnect(),this.rafId!=null&&this.targetWindow&&(this.targetWindow.cancelAnimationFrame(this.rafId),this.rafId=null),this.scrollState=null,this._iosDeferredAdjustment=0,this._iosTouching=!1,this._iosJustTouchEnded=!1,this.scrollElement=null,this.targetWindow=null},this._didMount=()=>()=>{this.cleanup()},this._willUpdate=()=>{var r;const o=this.options.enabled?this.options.getScrollElement():null;if(this.scrollElement!==o){if(this.cleanup(),!o){this.maybeNotify();return}if(this.scrollElement=o,this.scrollElement&&"ownerDocument"in this.scrollElement?this.targetWindow=this.scrollElement.ownerDocument.defaultView:this.targetWindow=((r=this.scrollElement)==null?void 0:r.window)??null,this.elementsCache.forEach(l=>{this.observer.observe(l)}),this.unsubs.push(this.options.observeElementRect(this,l=>{this.scrollRect=l,this.maybeNotify()})),this.unsubs.push(this.options.observeElementOffset(this,(l,u)=>{if(u&&this._intendedScrollOffset===null&&l===this.scrollOffset)return;this._intendedScrollOffset!==null&&Math.abs(l-this._intendedScrollOffset)<1.5&&(l=this._intendedScrollOffset),this._intendedScrollOffset=null,this.scrollAdjustments=0;const d=this.getScrollOffset();this.scrollDirection=u?d===l?this.scrollDirection:d{this._iosTouching=!0,this._iosJustTouchEnded=!1,this._iosTouchEndTimerId!==null&&this.targetWindow!=null&&(this.targetWindow.clearTimeout(this._iosTouchEndTimerId),this._iosTouchEndTimerId=null)},d=()=>{this._iosTouching=!1,!(!tm()||this.targetWindow==null)&&(this._iosJustTouchEnded=!0,this._iosTouchEndTimerId=this.targetWindow.setTimeout(()=>{this._iosJustTouchEnded=!1,this._iosTouchEndTimerId=null,this._flushIosDeferredIfReady()},150))};l.addEventListener("touchstart",u,Ru),l.addEventListener("touchend",d,Ru),this.unsubs.push(()=>{l.removeEventListener("touchstart",u),l.removeEventListener("touchend",d),this._iosTouchEndTimerId!==null&&this.targetWindow!=null&&(this.targetWindow.clearTimeout(this._iosTouchEndTimerId),this._iosTouchEndTimerId=null)})}this._scrollToOffset(this.getScrollOffset(),{adjustments:void 0,behavior:void 0})}const s=this.pendingScrollAnchor;if(this.pendingScrollAnchor=null,s&&this.scrollElement&&this.options.enabled){const[l,u,d,p]=s;l!==null&&!d&&(tm()&&(this.isScrolling||this._iosTouching||this._iosJustTouchEnded)?p!==0&&(this._iosDeferredAdjustment+=p):this._scrollToOffset(this.getScrollOffset(),{adjustments:void 0,behavior:void 0})),d&&this.scrollToEnd({behavior:d})}},this._flushIosDeferredIfReady=()=>{if(this._iosDeferredAdjustment===0||this.isScrolling||this._iosTouching||this._iosJustTouchEnded)return;const r=this.getScrollOffset(),o=this.getMaxScrollOffset();if(r<0||r>o)return;const s=this._iosDeferredAdjustment;this._iosDeferredAdjustment=0,this._scrollToOffset(r,{adjustments:this.scrollAdjustments+=s,behavior:void 0})},this.rafId=null,this.getSize=()=>this.options.enabled?(this.scrollRect=this.scrollRect??this.options.initialRect,this.scrollRect[this.options.horizontal?"width":"height"]):(this.scrollRect=null,0),this.getScrollOffset=()=>this.options.enabled?(this.scrollOffset=this.scrollOffset??(typeof this.options.initialOffset=="function"?this.options.initialOffset():this.options.initialOffset),this.scrollOffset):(this.scrollOffset=null,0),this.getMeasurementOptions=ja(()=>[this.options.count,this.options.paddingStart,this.options.scrollMargin,this.options.getItemKey,this.options.enabled,this.options.lanes,this.options.laneAssignmentMode,this.options.gap],(r,o,s,l,u,d,p,m)=>(this.prevLanes!==void 0&&this.prevLanes!==d&&(this.lanesChangedFlag=!0),this.prevLanes=d,this.pendingMin=null,{count:r,paddingStart:o,scrollMargin:s,getItemKey:l,enabled:u,lanes:d,laneAssignmentMode:p,gap:m}),{key:!1}),this.getMeasurements=ja(()=>[this.getMeasurementOptions(),this.itemSizeCacheVersion],({count:r,paddingStart:o,scrollMargin:s,getItemKey:l,enabled:u,lanes:d,laneAssignmentMode:p,gap:m},y)=>{const v=this.itemSizeCache;if(!u)return this.measurementsCache=[],this.itemSizeCache.clear(),this.laneAssignments.clear(),[];if(this.laneAssignments.size>r)for(const T of this.laneAssignments.keys())T>=r&&this.laneAssignments.delete(T);this.lanesChangedFlag&&(this.lanesChangedFlag=!1,this.lanesSettling=!0,this.measurementsCache=[],this.itemSizeCache.clear(),this.laneAssignments.clear(),this.pendingMin=null),this.measurementsCache.length===0&&!this.lanesSettling&&(this.measurementsCache=this.options.initialMeasurementsCache,this.measurementsCache.forEach(T=>{this.itemSizeCache.set(T.key,T.size)}));const b=this.lanesSettling?0:this.pendingMin??0;if(this.pendingMin=null,this.lanesSettling&&this.measurementsCache.length===r&&(this.lanesSettling=!1),d===1){const T=r*2;let j=this._flatMeasurements;if(!j||j.length0&&I.set(j.subarray(0,b*2)),j=I,this._flatMeasurements=j}let O;if(b===0)O=o+s;else{const I=b-1;O=j[I*2]+j[I*2+1]+m}for(let I=b;I1){k=O;const ve=C[k],de=ve!==void 0?x[ve]:void 0;I=de?de.end+m:o+s}else if(E===d){let ve=0,de=_[0],Q=C[0];for(let le=1;lethis.options.debug}),this.calculateRange=ja(()=>[this.getMeasurements(),this.getSize(),this.getScrollOffset(),this.options.lanes],(r,o,s,l)=>r.length===0||o===0?(this.range=null,null):(this.range=nI(r,o,s,l,l===1&&this._flatMeasurements!=null?this._flatMeasurements:null),this.range),{key:!1,debug:()=>this.options.debug}),this.getVirtualIndexes=ja(()=>{let r=null,o=null;const s=this.calculateRange();return s&&(r=s.startIndex,o=s.endIndex),this.maybeNotify.updateDeps([this.isScrolling,r,o]),[this.options.rangeExtractor,this.options.overscan,this.options.count,r,o]},(r,o,s,l,u)=>l===null||u===null?[]:r({startIndex:l,endIndex:u,overscan:o,count:s}),{key:!1,debug:()=>this.options.debug}),this.indexFromElement=r=>{const o=this.options.indexAttribute,s=r.getAttribute(o);return s?parseInt(s,10):(console.warn(`Missing attribute name '${o}={index}' on measured element.`),-1)},this.shouldMeasureDuringScroll=r=>{var o;if(!this.scrollState||this.scrollState.behavior!=="smooth")return!0;const s=this.scrollState.index??((o=this.getVirtualItemForOffset(this.scrollState.lastTargetOffset))==null?void 0:o.index);if(s!==void 0&&this.range){const l=Math.max(this.options.overscan,Math.ceil((this.range.endIndex-this.range.startIndex)/2)),u=Math.max(0,s-l),d=Math.min(this.options.count-1,s+l);return r>=u&&r<=d}return!0},this.measureElement=r=>{if(!r){this.elementsCache.forEach((u,d)=>{u.isConnected||(this.observer.unobserve(u),this.elementsCache.delete(d))});return}const o=this.indexFromElement(r),s=this.options.getItemKey(o),l=this.elementsCache.get(s);l!==r&&(l&&this.observer.unobserve(l),this.observer.observe(r),this.elementsCache.set(s,r)),(!this.isScrolling||this.scrollState)&&this.shouldMeasureDuringScroll(o)&&this.resizeItem(o,this.options.measureElement(r,void 0,this))},this.resizeItem=(r,o)=>{var s,l;if(r<0||r>=this.options.count)return;let u,d,p;const m=this._flatMeasurements;if(this.options.lanes===1&&m!==null)p=this.options.getItemKey(r),d=m[r*2],u=m[r*2+1];else{const b=this.measurementsCache[r];if(!b)return;p=b.key,d=b.start,u=b.size}const y=this.itemSizeCache.get(p)??u,v=o-y;if(v!==0){const b=this.options.anchorTo==="end"&&((s=this.scrollState)==null?void 0:s.behavior)!=="smooth"&&this.getVirtualDistanceFromEnd()<=this.options.scrollEndThreshold,x=b?this.getTotalSize():0,C=((l=this.scrollState)==null?void 0:l.behavior)!=="smooth"&&(this.shouldAdjustScrollPositionOnItemSizeChange!==void 0?this.shouldAdjustScrollPositionOnItemSizeChange(this.measurementsCache[r]??{index:r,key:p,start:d,size:u,end:d+u,lane:0},v,this):d[this.getVirtualIndexes(),this.getMeasurements()],(r,o)=>{const s=[];for(let l=0,u=r.length;lthis.options.debug}),this.getVirtualItemForOffset=r=>{const o=this.getMeasurements();if(o.length===0)return;const s=this._flatMeasurements,l=this.options.lanes===1&&s!=null,u=NC(0,o.length-1,l?d=>s[d*2]:d=>rw(o[d]).start,r);return rw(o[u])},this.getMaxScrollOffset=()=>{if(!this.scrollElement)return 0;if("scrollHeight"in this.scrollElement)return this.options.horizontal?this.scrollElement.scrollWidth-this.scrollElement.clientWidth:this.scrollElement.scrollHeight-this.scrollElement.clientHeight;{const r=this.scrollElement.document.documentElement;return this.options.horizontal?r.scrollWidth-this.scrollElement.innerWidth:r.scrollHeight-this.scrollElement.innerHeight}},this.getVirtualDistanceFromEnd=()=>Math.max(this.getTotalSize()-this.getSize()-this.getScrollOffset(),0),this.getDistanceFromEnd=()=>Math.max(this.getMaxScrollOffset()-this.getScrollOffset(),0),this.isAtEnd=(r=this.options.scrollEndThreshold)=>this.getDistanceFromEnd()<=r,this.getOffsetForAlignment=(r,o,s=0)=>{if(!this.scrollElement)return 0;const l=this.getSize(),u=this.getScrollOffset();o==="auto"&&(o=r>=u+l?"end":"start"),o==="center"?r+=(s-l)/2:o==="end"&&(r-=l);const d=this.getMaxScrollOffset();return Math.max(Math.min(d,r),0)},this.getOffsetForIndex=(r,o="auto")=>{r=Math.max(0,Math.min(r,this.options.count-1));const s=this.getSize(),l=this.getScrollOffset(),u=this.measurementsCache[r];if(!u)return;if(o==="auto")if(u.end>=l+s-this.options.scrollPaddingEnd)o="end";else if(u.start<=l+this.options.scrollPaddingStart)o="start";else return[l,o];if(o==="end"&&r===this.options.count-1)return[this.getMaxScrollOffset(),o];const d=o==="end"?u.end+this.options.scrollPaddingEnd:u.start-this.options.scrollPaddingStart;return[this.getOffsetForAlignment(d,o,u.size),o]},this.scrollToOffset=(r,{align:o="start",behavior:s="auto"}={})=>{const l=this.getOffsetForAlignment(r,o),u=this.now();this.scrollState={index:null,align:o,behavior:s,startedAt:u,lastTargetOffset:l,stableFrames:0},this._scrollToOffset(l,{adjustments:void 0,behavior:s}),this.scheduleScrollReconcile()},this.scrollToIndex=(r,{align:o="auto",behavior:s="auto"}={})=>{r=Math.max(0,Math.min(r,this.options.count-1));const l=this.getOffsetForIndex(r,o);if(!l)return;const[u,d]=l,p=this.now();this.scrollState={index:r,align:d,behavior:s,startedAt:p,lastTargetOffset:u,stableFrames:0},this._scrollToOffset(u,{adjustments:void 0,behavior:s}),this.scheduleScrollReconcile()},this.scrollBy=(r,{behavior:o="auto"}={})=>{const s=this.getScrollOffset()+r,l=this.now();this.scrollState={index:null,align:"start",behavior:o,startedAt:l,lastTargetOffset:s,stableFrames:0},this._scrollToOffset(s,{adjustments:void 0,behavior:o}),this.scheduleScrollReconcile()},this.scrollToEnd=({behavior:r="auto"}={})=>{if(this.options.count>0){this.scrollToIndex(this.options.count-1,{align:"end",behavior:r});return}this.scrollToOffset(Math.max(this.getTotalSize()-this.getSize(),0),{behavior:r})},this.getTotalSize=()=>{var r;const o=this.getMeasurements();let s;if(o.length===0)s=this.options.paddingStart;else if(this.options.lanes===1){const l=o.length-1,u=this._flatMeasurements;u!=null?s=u[l*2]+u[l*2+1]:s=((r=o[l])==null?void 0:r.end)??0}else{const l=Array(this.options.lanes).fill(null);let u=o.length-1;for(;u>=0&&l.some(d=>d===null);){const d=o[u];l[d.lane]===null&&(l[d.lane]=d.end),u--}s=Math.max(...l.filter(d=>d!==null))}return Math.max(s-this.options.scrollMargin+this.options.paddingEnd,0)},this.takeSnapshot=()=>{const r=[];if(this.itemSizeCache.size===0)return r;const o=this.getMeasurements();for(const s of o)s&&this.itemSizeCache.has(s.key)&&r.push({index:s.index,key:s.key,start:s.start,size:s.size,end:s.end,lane:s.lane});return r},this._scrollToOffset=(r,{adjustments:o,behavior:s})=>{this._intendedScrollOffset=r+(o??0),this.options.scrollToFn(r,{behavior:s,adjustments:o},this)},this.measure=()=>{this.pendingMin=null,this.itemSizeCache.clear(),this.laneAssignments.clear(),this.itemSizeCacheVersion++,this.notify(!1)},this.setOptions(n)}applyScrollAdjustment(n,r){n!==0&&(tm()&&(this.isScrolling||this._iosTouching||this._iosJustTouchEnded)?this._iosDeferredAdjustment+=n:(this._scrollToOffset(this.getScrollOffset(),{adjustments:this.scrollAdjustments+=n,behavior:r}),this.scrollOffset!==null&&(this.scrollOffset+=this.scrollAdjustments,this.scrollAdjustments=0)))}scheduleScrollReconcile(){if(!this.targetWindow){this.scrollState=null;return}this.rafId==null&&(this.rafId=this.targetWindow.requestAnimationFrame(()=>{this.rafId=null,this.reconcileScroll()}))}reconcileScroll(){if(!this.scrollState||!this.scrollElement)return;if(this.now()-this.scrollState.startedAt>5e3){this.scrollState=null;return}const o=this.scrollState.index!=null?this.getOffsetForIndex(this.scrollState.index,this.scrollState.align):void 0,s=o?o[0]:this.scrollState.lastTargetOffset,l=1,u=s!==this.scrollState.lastTargetOffset;if(!u&&H8(s,this.getScrollOffset())){if(this.scrollState.stableFrames++,this.scrollState.stableFrames>=l){this.getScrollOffset()!==s&&this._scrollToOffset(s,{adjustments:void 0,behavior:"auto"}),this.scrollState=null;return}}else if(this.scrollState.stableFrames=0,u){const d=this.getSize()||600,p=Math.abs(s-this.getScrollOffset()),m=this.scrollState.behavior==="smooth"&&p>d;this.scrollState.lastTargetOffset=s,m||(this.scrollState.behavior="auto"),this._scrollToOffset(s,{adjustments:void 0,behavior:m?"smooth":"auto"})}this.scheduleScrollReconcile()}}const NC=(e,n,r,o)=>{for(;e<=n;){const s=(e+n)/2|0,l=r(s);if(lo)n=s-1;else return s}return e>0?e-1:0};function tI(e,n,r){let o=0;for(;o<=n;){const s=(o+n)/2|0,l=e[s*2];if(lr)n=s-1;else return s}return o>0?o-1:0}function nI(e,n,r,o,s){const l=e.length-1;if(e.length<=o)return{startIndex:0,endIndex:l};if(o===1&&s!==null){const m=tI(s,l,r);let y=m;const v=r+n;for(;ye[m].start,r),p=d;if(o===1)for(;p1){const m=Array(o).fill(0);for(;pv=0&&y.some(v=>v>=r);){const v=e[d];y[v.lane]=v.start,d--}d=Math.max(0,d-d%o),p=Math.min(l,p+(o-1-p%o))}return{startIndex:d,endIndex:p}}const nm=typeof document<"u"?w.useLayoutEffect:w.useEffect;function rI({useFlushSync:e=!0,directDomUpdates:n=!1,directDomUpdatesMode:r="transform",...o}){const s=w.useReducer(m=>m+1,0)[1],l=w.useRef({enabled:n,mode:r,container:null,lastSize:null,lastPositions:new WeakMap,prevRange:null});l.current.enabled=n,l.current.mode=r;const u=m=>{const y=l.current;if(!y.enabled||!y.container)return;const v=m.getTotalSize();if(v!==y.lastSize){y.lastSize=v;const T=m.options.horizontal?"width":"height";y.container.style[T]=`${v}px`}const b=!!m.options.horizontal,x=y.mode==="transform",C=b?"left":"top",_=m.options.scrollMargin,E=m.getVirtualItems();for(const T of E){const j=T.start-_,O=m.elementsCache.get(T.key);O&&y.lastPositions.get(O)!==j&&(y.lastPositions.set(O,j),x?O.style.transform=b?`translate3d(${j}px, 0, 0)`:`translate3d(0, ${j}px, 0)`:O.style[C]=`${j}px`)}},d={...o,onChange:(m,y)=>{var v;const b=l.current;let x=!0;if(b.enabled){u(m);const C=m.range,_=b.prevRange;x=!_||_.isScrolling!==m.isScrolling||_.startIndex!==C?.startIndex||_.endIndex!==C?.endIndex,x&&(b.prevRange=C?{startIndex:C.startIndex,endIndex:C.endIndex,isScrolling:m.isScrolling}:null)}x&&(e&&y?Mo.flushSync(s):s()),(v=o.onChange)==null||v.call(o,m,y)}},[p]=w.useState(()=>{const m=new eI(d);return Object.assign(m,{containerRef:y=>{const v=l.current;if(v.container=y,v.lastSize=null,y&&v.enabled){const b=m.getTotalSize();v.lastSize=b;const x=m.options.horizontal?"width":"height";y.style[x]=`${b}px`}}})});return p.setOptions(d),nm(()=>p._didMount(),[]),nm(()=>p._willUpdate()),nm(()=>{u(p)}),p}function iI(e){return rI({observeElementRect:Z8,observeElementOffset:Q8,scrollToFn:W8,...e})}function oI(e,n){const r=[],o=(s,l)=>{for(const u of s)r.push({node:u,depth:l}),u.dir&&n.has(u.path)&&o(u.children||[],l+1)};return o(e?.children||[],0),r}function aI(e){const{root:n,expanded:r,onToggle:o,currentPath:s,listingShowing:l,onOpen:u}=e,d=w.useRef(null),p=w.useMemo(()=>oI(n,r),[n,r]),m=iI({count:p.length,getScrollElement:()=>d.current,estimateSize:()=>window.matchMedia("(max-width: 768px)").matches?44:28,overscan:12,getItemKey:y=>p[y].node.path});return w.useEffect(()=>{if(!s)return;const y=p.findIndex(v=>v.node.path===s);y>=0&&m.scrollToIndex(y,{align:"auto"})},[s,p]),h.jsx("nav",{id:"tree","aria-label":"Files",ref:d,children:h.jsx("div",{style:{height:m.getTotalSize(),position:"relative"},children:m.getVirtualItems().map(y=>{const{node:v,depth:b}=p[y.index],x=v.dir?r.has(v.path):!1,C=()=>{if(v.dir&&s===v.path&&l){o(v.path);return}u(v.path),v.dir||mr()};return h.jsxs("div",{className:"row "+(v.dir?"dir":"file")+(s===v.path?" active":"")+(v.dir&&!x?" collapsed":""),"data-path":v.path,tabIndex:0,role:"button",title:v.name,"aria-expanded":v.dir?x:void 0,style:{position:"absolute",top:0,left:0,right:0,transform:`translateY(${y.start}px)`,paddingLeft:8+b*13},onClick:C,onKeyDown:_=>{(_.key==="Enter"||_.key===" ")&&(_.preventDefault(),C())},children:[Array.from({length:b},(_,E)=>h.jsx("span",{className:"tguide",style:{left:8+E*13+5},"aria-hidden":"true"},E)),h.jsx("span",{className:"chev",onClick:_=>{v.dir&&(_.stopPropagation(),o(v.path))},children:h.jsx(ht,{name:"chevd"})}),h.jsx("span",{className:"ticon",children:h.jsx(ht,{name:v.dir?"folder":"doc"})}),h.jsx("span",{className:"label",children:v.name})]},y.key)})})})}function sI(e){const n=e.split("/"),r=[];let o="";for(let s=0;s{o=o?o+"/"+s:s;const u=o,d=l===r.length-1;return h.jsxs("span",{children:[l>0&&h.jsx("span",{className:"crumb-sep",children:"/"}),d?h.jsx("span",{children:s}):h.jsx("span",{className:"crumb-seg",title:u,onClick:()=>n(u),children:s})]},u)})})}function ow(e){if(e==="")return[];const n=e.split(` -`);return n[n.length-1]===""&&n.pop(),n}const cI=4e6;function uI(e,n){let r=0;for(;rs.push({op:"-",line:l[v],an:r+v+1}),y=v=>s.push({op:"+",line:u[v],bn:r+v+1});if(d*p>cI){for(let v=0;v=0;C--)for(let _=p-1;_>=0;_--)v[C][_]=l[C]===u[_]?v[C+1][_+1]+1:Math.max(v[C+1][_],v[C][_+1]);let b=0,x=0;for(;b=v[b][x+1]?m(b++):y(x++);for(;bo.op==="+").length,del:r.filter(o=>o.op==="-").length}}const DC=1<<20,fI=8192;function hI(e){if(e.byteLength>DC)return{kind:"too-large",size:e.byteLength};if(e.subarray(0,fI).includes(0))return{kind:"binary"};try{return{kind:"text",text:new TextDecoder("utf-8",{fatal:!0}).decode(e)}}catch{return{kind:"binary"}}}function Zm(e,n,r,o){let s=e+"blob?sha="+encodeURIComponent(n);return r&&(s+="&name="+encodeURIComponent(r)),o&&(s+="&download=1"),s}async function mI(e){const n=await tT(e),r=Number(n.headers.get("Content-Length"));return r>DC?{kind:"too-large",size:r}:hI(new Uint8Array(await n.arrayBuffer()))}function zC(e,n,r,o){return Ht({queryKey:n,queryFn:()=>mI(e),enabled:r,...o?{staleTime:1/0,gcTime:1/0}:{},retry:!1})}function aw(e,n,r){return zC(n?Zm(e,n):"",["blob",e,n],!!n,!0)}function pI(e){return e.slice(e.lastIndexOf("/")+1)}function gI({apiBase:e,path:n,prev:r,cur:o}){const s=pI(n);return h.jsxs("span",{className:"dv-dl",children:[h.jsx("a",{href:Zm(e,r,s,!0),children:"download previous"}),h.jsx("a",{href:Zm(e,o,s,!0),children:"download this version"})]})}function vI({apiBase:e,path:n,prev:r,cur:o}){const s=aw(e,r),l=aw(e,o),u=s.data?.kind==="text"&&l.data?.kind==="text",d=w.useMemo(()=>s.data?.kind==="text"&&l.data?.kind==="text"?dI(s.data.text,l.data.text):null,[s.data,l.data]);if(s.error||l.error)return h.jsx("div",{className:"dv dv-msg",children:"Could not load one of the versions."});if(!s.data||!l.data)return h.jsx("div",{className:"dv dv-msg",children:"Loading changes…"});if(!u){const v=s.data.kind==="too-large"||l.data.kind==="too-large";return h.jsxs("div",{className:"dv dv-msg",children:[v?"Too large to diff — download to compare.":"Binary file — no diff available.",h.jsx(gI,{apiBase:e,path:n,prev:r,cur:o})]})}const{lines:p,add:m,del:y}=d;return h.jsxs("div",{className:"dv",children:[h.jsxs("div",{className:"dv-head",children:[h.jsxs("span",{className:"dv-stat",children:[h.jsxs("span",{className:"dv-add",children:["+",m]})," ",h.jsxs("span",{className:"dv-del",children:["−",y]})]}),m===0&&y===0&&h.jsx("span",{className:"dv-same",children:"No line changes"})]}),h.jsx("div",{className:"dv-body",children:p.map((v,b)=>h.jsxs("div",{className:"dv-line dv-"+(v.op==="="?"ctx":v.op==="+"?"ins":"rm"),children:[h.jsx("span",{className:"dv-n",children:v.an??""}),h.jsx("span",{className:"dv-n",children:v.bn??""}),h.jsx("span",{className:"dv-mark",children:v.op==="="?" ":v.op}),h.jsx("span",{className:"dv-text",children:v.line||" "})]},b))})]})}const yI={add:"added",edit:"edited",delete:"deleted"};function kC({text:e}){return h.jsx(h.Fragment,{children:e.split(/(https?:\/\/\S+)/).map((n,r)=>/^https?:\/\//.test(n)?h.jsx("a",{href:n,target:"_blank",rel:"noopener",children:n},r):n)})}function dg({entry:e,apiBase:n,onOpen:r,diff:o,restore:s,remove:l,restoreSha:u,inRun:d}){const[p,m]=w.useState(!1),[y,v]=w.useState(!1),b=e.kind==="put"?"edit":e.kind,x=ld(e),C=[e.device.name||e.device.id,e.device.os,e.device.ip].filter(Boolean).join(" · "),_=b!=="delete",E=!!o&&b!=="delete"&&!!e.blob,T=!!d&&b==="add",j=!!s&&!!u&&!T,O=!!l&&T,k=!!s?.busy&&s.busy===e.path+u,I=!!l?.busy&&l.busy===e.path,B=_&&!!e.blob,H=e.path.split("/").pop()||e.path,V=new Date(e.time).toLocaleString(),pe=n+"blob?sha="+e.blob+"&name="+encodeURIComponent(H)+"&download=1",ve=()=>v(!y),de=Q=>{Q.target.tagName!=="A"&&_&&r(e.path,e.blob)};return h.jsxs("div",{className:"hentry "+b+(_?" clickable":""),tabIndex:_?0:void 0,role:_?"button":void 0,onClick:de,onKeyDown:Q=>{_&&(Q.key==="Enter"||Q.key===" ")&&(Q.preventDefault(),r(e.path,e.blob))},children:[h.jsxs("div",{className:"hline",children:[h.jsx("span",{className:"hkind",children:yI[b]||b}),h.jsx("span",{className:"hpath",children:e.path}),h.jsx("span",{className:"htime",children:V})]}),h.jsxs("div",{className:"hmeta",children:[h.jsx("span",{className:"hwho",children:x}),h.jsx("span",{className:"hdev",children:C}),h.jsx("span",{className:"hsize",children:e.size?ug(e.size):""}),j&&h.jsxs("button",{type:"button",className:"hrestore-btn",disabled:k,title:"Put this version of "+e.path+" back as a new change",onClick:Q=>{Q.stopPropagation(),s.onRestore(e.path,u)},onKeyDown:Q=>Q.stopPropagation(),children:[h.jsx(ht,{name:"hist"}),k?"restoring…":"restore"]}),O&&h.jsxs("button",{type:"button",className:"hremove-btn",disabled:I,title:"Remove "+e.path+" — this run created it",onClick:Q=>{Q.stopPropagation(),l.onRemove(e.path)},onKeyDown:Q=>Q.stopPropagation(),children:[h.jsx(ht,{name:"trash"}),I?"removing…":"undo — remove file"]})]}),e.note&&!d&&h.jsx("div",{className:"hnote"+(p?" open":""),tabIndex:0,role:"button",title:p?"Collapse note":"Show full note","aria-expanded":p,onClick:Q=>{Q.stopPropagation(),Q.target.tagName!=="A"&&m(!p)},onKeyDown:Q=>{(Q.key==="Enter"||Q.key===" ")&&(Q.preventDefault(),Q.stopPropagation(),m(!p))},children:h.jsx(kC,{text:e.note})}),(E||B)&&h.jsxs("div",{className:"hactions",children:[E&&(o.prev?h.jsxs("button",{type:"button",className:"hdiff-btn"+(y?" open":""),"aria-expanded":y,onClick:Q=>{Q.stopPropagation(),ve()},onKeyDown:Q=>Q.stopPropagation(),children:[h.jsx(ht,{name:y?"chevd":"chev"}),y?"hide changes":"show changes"]}):h.jsx("div",{className:"hdiff-none",children:"First version — nothing to compare against"})),B&&h.jsxs(h.Fragment,{children:[h.jsxs("button",{type:"button",className:"hver-btn","aria-label":`Open ${H} as of ${V}`,onClick:Q=>{Q.stopPropagation(),r(e.path,e.blob)},onKeyDown:Q=>Q.stopPropagation(),children:[h.jsx(ht,{name:"clock"}),"Open this version"]}),h.jsxs("a",{className:"hver-btn",download:!0,href:pe,"aria-label":`Download ${H} as of ${V}`,onClick:Q=>Q.stopPropagation(),onKeyDown:Q=>{Q.stopPropagation(),Q.key===" "&&(Q.preventDefault(),Q.currentTarget.click())},children:[h.jsx(ht,{name:"download"}),"Download"]})]})]}),E&&o.prev&&y&&h.jsx("div",{onClick:Q=>Q.stopPropagation(),children:h.jsx(vI,{apiBase:o.apiBase,path:e.path,prev:o.prev,cur:e.blob})})]})}function bI(e){const{node:n,heatMap:r,onOpen:o}=e,s=(n.children||[]).slice().sort((m,y)=>Number(y.dir||!1)-Number(m.dir||!1)||m.name.localeCompare(y.name)),l=s.filter(m=>m.dir).length,u=s.length-l,d=[];l&&d.push(l+(l===1?" folder":" folders")),u&&d.push(u+(u===1?" file":" files"));const p=nw(r,n.path,!0);return p&&d.push(Ys(p)+" in 30 days"),h.jsxs("div",{className:"dirlist",children:[h.jsxs("h1",{className:"dl-title",children:[h.jsx("span",{className:"dl-title-icon",children:h.jsx(ht,{name:"folder"})}),h.jsx("span",{children:n.name})]}),h.jsx("p",{className:"dl-sub",children:d.join(" · ")||"Empty folder"}),s.length===0?h.jsx("div",{className:"dl-empty",children:"Nothing in this folder yet."}):h.jsx("div",{className:"dl-items",children:s.map(m=>{let y="";if(m.dir){const b=(m.children||[]).length;y=b+(b===1?" item":" items")}else y=[m.size?ug(m.size):"",m.time?new Date(m.time).toLocaleDateString():""].filter(Boolean).join(" · ");const v=nw(r,m.path,!!m.dir);return v&&(y=Ys(v)+(y?" · "+y:"")),h.jsxs("div",{className:"dl-row",tabIndex:0,role:"button",title:m.path,onClick:()=>o(m.path),onKeyDown:b=>{(b.key==="Enter"||b.key===" ")&&(b.preventDefault(),o(m.path))},children:[h.jsx("span",{className:"ticon",children:h.jsx(ht,{name:m.dir?"folder":"doc"})}),h.jsx("span",{className:"dl-name",children:m.name}),v&&h.jsx("span",{className:"heatdot lvl"+D8(v),role:"img","aria-label":Ys(v)+" in 30 days",title:Ys(v)+" in 30 days"}),h.jsx("span",{className:"dl-meta",children:y})]},m.path)})}),e.hub&&h.jsx(xI,{apiBase:e.apiBase,prefix:n.path+"/",onOpen:o,onFullHistory:()=>e.onFullHistory(n.path+"/"),onRendered:e.onRendered})]})}function xI(e){const n=P8(e.apiBase,e.prefix,!0),{onRendered:r}=e;return w.useEffect(()=>{n&&n.length&&r&&r()},[n,r]),!n||n.length===0?null:h.jsxs("div",{className:"dl-history",children:[h.jsx("h3",{className:"dl-h3",children:"Recent changes"}),h.jsx("div",{className:"history dl-hlist",children:n.map((o,s)=>h.jsx(dg,{entry:o,apiBase:e.apiBase,onOpen:e.onOpen},s))}),h.jsx("button",{className:"ai-btn dl-more",onClick:e.onFullHistory,children:"Full history"})]})}function wI(e){const{apiBase:n,path:r,version:o,onMeta:s}=e,l=o?n+"blob?sha="+o+"&name="+encodeURIComponent(r):n+"file?path="+encodeURIComponent(r);return w.useEffect(()=>()=>s(""),[r,s]),r8.test(r)?h.jsx(CI,{...e}):bC.test(r)?h.jsx("iframe",{className:"htmlview",sandbox:"allow-scripts",src:l,title:r,onLoad:e.onRendered}):xC.test(r)?h.jsx("iframe",{className:"pdfview",src:l,title:r,onLoad:e.onRendered}):i8.test(r)?h.jsx(TI,{src:l,alt:r,version:o,onRendered:e.onRendered}):o8.test(r)?h.jsx(jI,{...e,fileURL:l}):h.jsx(SI,{...e,fileURL:l})}function SI(e){const{apiBase:n,path:r,version:o,fileURL:s,onRendered:l}=e,{data:u,error:d}=zC(s,["text",s],!0,!!o);return w.useEffect(()=>{u&&l?.()},[u,l]),d?h.jsx(cd,{version:o,err:d}):u?u.kind==="text"?h.jsx("pre",{className:"plain",children:u.text},r):h.jsx(_I,{apiBase:n,path:r,version:o,fileURL:s,children:u.kind==="too-large"?`Too large to preview (${ug(u.size)}).`:"No preview for this file type."}):null}function _I(e){const{apiBase:n,path:r,version:o,fileURL:s}=e;return h.jsxs("div",{className:"filecard",children:[h.jsx("div",{className:"name",children:r.split("/").pop()}),h.jsx("p",{children:e.children}),h.jsx("a",{className:"btn",download:!0,href:o?s+"&download=1":n+"download?path="+encodeURIComponent(r),children:"Download"})]})}function CI(e){const{apiBase:n,path:r,version:o,heatMap:s,flatFiles:l,onOpenFile:u,onMeta:d,onRendered:p}=e,{data:m,error:y}=Ht({queryKey:["render",n,r,o||""],queryFn:()=>sn(n+"render?path="+encodeURIComponent(r)+(o?"&sha="+o:"")),retry:o?!1:void 0}),v=w.useMemo(()=>m?RI(m.html,r,n):"",[m,r,n]);return w.useEffect(()=>{if(!m)return;const b=[];(m.user_name||m.user||m.author)&&b.push(ld(m)+(m.device?" on "+m.device:"")),m.time&&b.push(new Date(m.time).toLocaleString());const x=o?null:s&&s[m.path];x&&Ba(x)&&b.push(Ys(x)+" / 30d"),d(b.join(" · ")),p?.()},[m,o,s,d,p]),y?h.jsx(cd,{version:o,err:y}):m?h.jsx("div",{dangerouslySetInnerHTML:{__html:v},onClick:b=>EI(b,r,l,u)}):null}function EI(e,n,r,o){const s=e.target.closest("a");if(!s||!e.currentTarget.contains(s))return;const l=s.getAttribute("href")||"",u=n.includes("/")?n.slice(0,n.lastIndexOf("/")):"";l.startsWith("wiki:")?(e.preventDefault(),OI(decodeURIComponent(l.slice(5)),r,o)):/^([a-z]+:|\/|#)/i.test(l)||(e.preventDefault(),o(wC(u,decodeURIComponent(l))))}function RI(e,n,r){const o=n.includes("/")?n.slice(0,n.lastIndexOf("/")):"",s=u=>r+"file?path="+encodeURIComponent(u),l=new DOMParser().parseFromString(e,"text/html");for(const u of l.querySelectorAll("img")){const d=u.getAttribute("src")||"";/^([a-z]+:|\/)/i.test(d)||u.setAttribute("src",s(wC(o,d)))}for(const u of l.querySelectorAll("a")){const d=u.getAttribute("href")||"";/^https?:/i.test(d)&&(u.setAttribute("target","_blank"),u.setAttribute("rel","noopener"))}return l.body.innerHTML}function TI(e){const[n,r]=w.useState(!1);return n?h.jsx(cd,{version:e.version,err:new Error("could not be loaded")}):h.jsx("img",{src:e.src,alt:e.alt,onLoad:e.onRendered,onError:()=>r(!0)})}function cd({version:e,err:n}){return h.jsx("div",{className:"empty",children:e?"That version isn't available.":"Could not load file: "+n.message})}function jI(e){const{path:n,version:r,fileURL:o,onRendered:s}=e,{data:l,error:u}=Ht({queryKey:["text",o],queryFn:async()=>{const d=await fetch(o);if(!d.ok)throw new Error(await d.text());return d.text()},retry:r?!1:void 0});return w.useEffect(()=>{l!=null&&s?.()},[l,s]),u?h.jsx(cd,{version:r,err:u}):l==null?null:h.jsx("pre",{className:"plain",children:l},n)}function OI(e,n,r){const o=e.toLowerCase(),s=n.find(l=>l.path.toLowerCase()===o||l.path.toLowerCase()===o+".md")||n.find(l=>{const u=l.name.toLowerCase();return u===o||u===o+".md"});s&&r(s.path)}const AI=[{value:"",label:"Never"},{value:"24h",label:"In 24 hours"},{value:"168h",label:"In 7 days"},{value:"720h",label:"In 30 days"}];function MI({url:e,copied:n,onClose:r}){const o=e.split("/s/")[1],[s,l]=w.useState(""),[u,d]=w.useState(),[p,m]=w.useState(!1),y=w.useRef(null);async function v(b){const x=s;l(b),m(!0);try{const C=await er("PATCH","/api/shares/"+o,{expires_in:b});d(C.expires)}catch(C){Ke(C.message,!0),l(x)}finally{m(!1)}}return h.jsx(Vp,{open:!0,onOpenChange:b=>!b&&r(),children:h.jsxs(Pp,{className:"modal",showCloseButton:!1,onOpenAutoFocus:b=>{b.preventDefault(),y.current?.focus()},children:[h.jsx(Yu,{asChild:!0,children:h.jsx("h3",{children:"Public link"})}),h.jsxs("p",{children:[h.jsx("b",{children:"Anyone with this link can view this file"})," — no account needed. It always shows the latest version until it expires or you revoke it."]}),h.jsx("div",{className:"modal-url",children:e}),h.jsxs("div",{className:"modal-expiry",children:[h.jsx("label",{htmlFor:"share-expiry",children:"Expires"}),h.jsx("select",{id:"share-expiry",value:s,disabled:p,onChange:b=>v(b.target.value),children:AI.map(b=>h.jsx("option",{value:b.value,children:b.label},b.value))}),h.jsx("span",{className:"modal-expiry-note",children:_C(u)})]}),h.jsxs("div",{className:"modal-actions",children:[h.jsx(Tt,{ref:y,variant:"primary",onClick:()=>Ha(e).then(b=>Ke(b?"Copied.":"Select and copy the link above.")),children:n?"Copied ✓":"Copy link"}),h.jsx(Tt,{variant:"subtle",onClick:()=>window.open(e,"_blank"),children:"Open"}),h.jsx(Tt,{variant:"subtle",onClick:r,children:"Done"})]})]})})}function NI({shares:e,canRevoke:n,onChanged:r}){return e.length===0?null:h.jsxs("div",{className:"share-banner",role:"status",children:[h.jsxs("div",{className:"sb-head",children:[h.jsx(ht,{name:"share"}),h.jsx("b",{children:"Publicly shared"}),h.jsxs("span",{className:"sb-count",children:[e.length," active link",e.length>1?"s":""]})]}),h.jsxs("p",{className:"sb-note",children:[h.jsx("b",{children:"Anyone with this link can view this file"})," — no account needed. It always shows the latest version until you revoke it."]}),e.map(o=>h.jsxs("div",{className:"sb-link",children:[h.jsx("span",{className:"sb-url mono",title:o.url,children:o.url}),h.jsx("span",{className:"sb-meta",children:CC(o,!1)}),h.jsxs("span",{className:"sb-actions",children:[h.jsx(Tt,{variant:"subtle",onClick:()=>Ha(o.url).then(s=>Ke(s?"Copied.":"Select and copy the link.")),children:"Copy link"}),h.jsx(Tt,{variant:"subtle",onClick:()=>window.open(o.url,"_blank"),children:"Open"}),n&&h.jsx("button",{className:"ai-del","aria-label":`Revoke the share of ${o.path}`,onClick:()=>RC(o,r),children:"Revoke"})]})]},o.token))]})}var sw=1,DI=.9,zI=.8,kI=.17,rm=.1,im=.999,LI=.9999,$I=.99,II=/[\\\/_+.#"@\[\(\{&]/,FI=/[\\\/_+.#"@\[\(\{&]/g,VI=/[\s-]/,LC=/[\s-]/g;function Km(e,n,r,o,s,l,u){if(l===n.length)return s===e.length?sw:$I;var d=`${s},${l}`;if(u[d]!==void 0)return u[d];for(var p=o.charAt(l),m=r.indexOf(p,s),y=0,v,b,x,C;m>=0;)v=Km(e,n,r,o,m+1,l+1,u),v>y&&(m===s?v*=sw:II.test(e.charAt(m-1))?(v*=zI,x=e.slice(s,m-1).match(FI),x&&s>0&&(v*=Math.pow(im,x.length))):VI.test(e.charAt(m-1))?(v*=DI,C=e.slice(s,m-1).match(LC),C&&s>0&&(v*=Math.pow(im,C.length))):(v*=kI,s>0&&(v*=Math.pow(im,m-s))),e.charAt(m)!==n.charAt(l)&&(v*=LI)),(vv&&(v=b*rm)),v>y&&(y=v),m=r.indexOf(p,m+1);return u[d]=y,y}function lw(e){return e.toLowerCase().replace(LC," ")}function PI(e,n,r){return e=r&&r.length>0?`${e+" "+r.join(" ")}`:e,Km(e,n,lw(e),lw(n),0,0,{})}var qs='[cmdk-group=""]',om='[cmdk-group-items=""]',UI='[cmdk-group-heading=""]',$C='[cmdk-item=""]',cw=`${$C}:not([aria-disabled="true"])`,Ym="cmdk-item-select",Oa="data-value",HI=(e,n,r)=>PI(e,n,r),IC=w.createContext(void 0),_l=()=>w.useContext(IC),FC=w.createContext(void 0),fg=()=>w.useContext(FC),VC=w.createContext(void 0),PC=w.forwardRef((e,n)=>{let r=Aa(()=>{var M,U;return{search:"",value:(U=(M=e.value)!=null?M:e.defaultValue)!=null?U:"",selectedItemId:void 0,filtered:{count:0,items:new Map,groups:new Set}}}),o=Aa(()=>new Set),s=Aa(()=>new Map),l=Aa(()=>new Map),u=Aa(()=>new Set),d=UC(e),{label:p,children:m,value:y,onValueChange:v,filter:b,shouldFilter:x,loop:C,disablePointerSelection:_=!1,vimBindings:E=!0,...T}=e,j=fn(),O=fn(),k=fn(),I=w.useRef(null),B=eF();Oo(()=>{if(y!==void 0){let M=y.trim();r.current.value=M,H.emit()}},[y]),Oo(()=>{B(6,le)},[]);let H=w.useMemo(()=>({subscribe:M=>(u.current.add(M),()=>u.current.delete(M)),snapshot:()=>r.current,setState:(M,U,X)=>{var K,se,ee,ge;if(!Object.is(r.current[M],U)){if(r.current[M]=U,M==="search")Q(),ve(),B(1,de);else if(M==="value"){if(document.activeElement.hasAttribute("cmdk-input")||document.activeElement.hasAttribute("cmdk-root")){let ye=document.getElementById(k);ye?ye.focus():(K=document.getElementById(j))==null||K.focus()}if(B(7,()=>{var ye;r.current.selectedItemId=(ye=he())==null?void 0:ye.id,H.emit()}),X||B(5,le),((se=d.current)==null?void 0:se.value)!==void 0){let ye=U??"";(ge=(ee=d.current).onValueChange)==null||ge.call(ee,ye);return}}H.emit()}},emit:()=>{u.current.forEach(M=>M())}}),[]),V=w.useMemo(()=>({value:(M,U,X)=>{var K;U!==((K=l.current.get(M))==null?void 0:K.value)&&(l.current.set(M,{value:U,keywords:X}),r.current.filtered.items.set(M,pe(U,X)),B(2,()=>{ve(),H.emit()}))},item:(M,U)=>(o.current.add(M),U&&(s.current.has(U)?s.current.get(U).add(M):s.current.set(U,new Set([M]))),B(3,()=>{Q(),ve(),r.current.value||de(),H.emit()}),()=>{l.current.delete(M),o.current.delete(M),r.current.filtered.items.delete(M);let X=he();B(4,()=>{Q(),X?.getAttribute("id")===M&&de(),H.emit()})}),group:M=>(s.current.has(M)||s.current.set(M,new Set),()=>{l.current.delete(M),s.current.delete(M)}),filter:()=>d.current.shouldFilter,label:p||e["aria-label"],getDisablePointerSelection:()=>d.current.disablePointerSelection,listId:j,inputId:k,labelId:O,listInnerRef:I}),[]);function pe(M,U){var X,K;let se=(K=(X=d.current)==null?void 0:X.filter)!=null?K:HI;return M?se(M,r.current.search,U):0}function ve(){if(!r.current.search||d.current.shouldFilter===!1)return;let M=r.current.filtered.items,U=[];r.current.filtered.groups.forEach(K=>{let se=s.current.get(K),ee=0;se.forEach(ge=>{let ye=M.get(ge);ee=Math.max(ye,ee)}),U.push([K,ee])});let X=I.current;xe().sort((K,se)=>{var ee,ge;let ye=K.getAttribute("id"),Ne=se.getAttribute("id");return((ee=M.get(Ne))!=null?ee:0)-((ge=M.get(ye))!=null?ge:0)}).forEach(K=>{let se=K.closest(om);se?se.appendChild(K.parentElement===se?K:K.closest(`${om} > *`)):X.appendChild(K.parentElement===X?K:K.closest(`${om} > *`))}),U.sort((K,se)=>se[1]-K[1]).forEach(K=>{var se;let ee=(se=I.current)==null?void 0:se.querySelector(`${qs}[${Oa}="${encodeURIComponent(K[0])}"]`);ee?.parentElement.appendChild(ee)})}function de(){let M=xe().find(X=>X.getAttribute("aria-disabled")!=="true"),U=M?.getAttribute(Oa);H.setState("value",U||void 0)}function Q(){var M,U,X,K;if(!r.current.search||d.current.shouldFilter===!1){r.current.filtered.count=o.current.size;return}r.current.filtered.groups=new Set;let se=0;for(let ee of o.current){let ge=(U=(M=l.current.get(ee))==null?void 0:M.value)!=null?U:"",ye=(K=(X=l.current.get(ee))==null?void 0:X.keywords)!=null?K:[],Ne=pe(ge,ye);r.current.filtered.items.set(ee,Ne),Ne>0&&se++}for(let[ee,ge]of s.current)for(let ye of ge)if(r.current.filtered.items.get(ye)>0){r.current.filtered.groups.add(ee);break}r.current.filtered.count=se}function le(){var M,U,X;let K=he();K&&(((M=K.parentElement)==null?void 0:M.firstChild)===K&&((X=(U=K.closest(qs))==null?void 0:U.querySelector(UI))==null||X.scrollIntoView({block:"nearest"})),K.scrollIntoView({block:"nearest"}))}function he(){var M;return(M=I.current)==null?void 0:M.querySelector(`${$C}[aria-selected="true"]`)}function xe(){var M;return Array.from(((M=I.current)==null?void 0:M.querySelectorAll(cw))||[])}function N(M){let U=xe()[M];U&&H.setState("value",U.getAttribute(Oa))}function Z(M){var U;let X=he(),K=xe(),se=K.findIndex(ge=>ge===X),ee=K[se+M];(U=d.current)!=null&&U.loop&&(ee=se+M<0?K[K.length-1]:se+M===K.length?K[0]:K[se+M]),ee&&H.setState("value",ee.getAttribute(Oa))}function ie(M){let U=he(),X=U?.closest(qs),K;for(;X&&!K;)X=M>0?JI(X,qs):WI(X,qs),K=X?.querySelector(cw);K?H.setState("value",K.getAttribute(Oa)):Z(M)}let te=()=>N(xe().length-1),ne=M=>{M.preventDefault(),M.metaKey?te():M.altKey?ie(1):Z(1)},z=M=>{M.preventDefault(),M.metaKey?N(0):M.altKey?ie(-1):Z(-1)};return w.createElement($e.div,{ref:n,tabIndex:-1,...T,"cmdk-root":"",onKeyDown:M=>{var U;(U=T.onKeyDown)==null||U.call(T,M);let X=M.nativeEvent.isComposing||M.keyCode===229;if(!(M.defaultPrevented||X))switch(M.key){case"n":case"j":{E&&M.ctrlKey&&ne(M);break}case"ArrowDown":{ne(M);break}case"p":case"k":{E&&M.ctrlKey&&z(M);break}case"ArrowUp":{z(M);break}case"Home":{M.preventDefault(),N(0);break}case"End":{M.preventDefault(),te();break}case"Enter":{M.preventDefault();let K=he();if(K){let se=new Event(Ym);K.dispatchEvent(se)}}}}},w.createElement("label",{"cmdk-label":"",htmlFor:V.inputId,id:V.labelId,style:nF},p),dd(e,M=>w.createElement(FC.Provider,{value:H},w.createElement(IC.Provider,{value:V},M))))}),BI=w.forwardRef((e,n)=>{var r,o;let s=fn(),l=w.useRef(null),u=w.useContext(VC),d=_l(),p=UC(e),m=(o=(r=p.current)==null?void 0:r.forceMount)!=null?o:u?.forceMount;Oo(()=>{if(!m)return d.item(s,u?.id)},[m]);let y=HC(s,l,[e.value,e.children,l],e.keywords),v=fg(),b=Hi(B=>B.value&&B.value===y.current),x=Hi(B=>m||d.filter()===!1?!0:B.search?B.filtered.items.get(s)>0:!0);w.useEffect(()=>{let B=l.current;if(!(!B||e.disabled))return B.addEventListener(Ym,C),()=>B.removeEventListener(Ym,C)},[x,e.onSelect,e.disabled]);function C(){var B,H;_(),(H=(B=p.current).onSelect)==null||H.call(B,y.current)}function _(){v.setState("value",y.current,!0)}if(!x)return null;let{disabled:E,value:T,onSelect:j,forceMount:O,keywords:k,...I}=e;return w.createElement($e.div,{ref:Fa(l,n),...I,id:s,"cmdk-item":"",role:"option","aria-disabled":!!E,"aria-selected":!!b,"data-disabled":!!E,"data-selected":!!b,onPointerMove:E||d.getDisablePointerSelection()?void 0:_,onClick:E?void 0:C},e.children)}),qI=w.forwardRef((e,n)=>{let{heading:r,children:o,forceMount:s,...l}=e,u=fn(),d=w.useRef(null),p=w.useRef(null),m=fn(),y=_l(),v=Hi(x=>s||y.filter()===!1?!0:x.search?x.filtered.groups.has(u):!0);Oo(()=>y.group(u),[]),HC(u,d,[e.value,e.heading,p]);let b=w.useMemo(()=>({id:u,forceMount:s}),[s]);return w.createElement($e.div,{ref:Fa(d,n),...l,"cmdk-group":"",role:"presentation",hidden:v?void 0:!0},r&&w.createElement("div",{ref:p,"cmdk-group-heading":"","aria-hidden":!0,id:m},r),dd(e,x=>w.createElement("div",{"cmdk-group-items":"",role:"group","aria-labelledby":r?m:void 0},w.createElement(VC.Provider,{value:b},x))))}),GI=w.forwardRef((e,n)=>{let{alwaysRender:r,...o}=e,s=w.useRef(null),l=Hi(u=>!u.search);return!r&&!l?null:w.createElement($e.div,{ref:Fa(s,n),...o,"cmdk-separator":"",role:"separator"})}),ZI=w.forwardRef((e,n)=>{let{onValueChange:r,...o}=e,s=e.value!=null,l=fg(),u=Hi(m=>m.search),d=Hi(m=>m.selectedItemId),p=_l();return w.useEffect(()=>{e.value!=null&&l.setState("search",e.value)},[e.value]),w.createElement($e.input,{ref:n,...o,"cmdk-input":"",autoComplete:"off",autoCorrect:"off",spellCheck:!1,"aria-autocomplete":"list",role:"combobox","aria-expanded":!0,"aria-controls":p.listId,"aria-labelledby":p.labelId,"aria-activedescendant":d,id:p.inputId,type:"text",value:s?e.value:u,onChange:m=>{s||l.setState("search",m.target.value),r?.(m.target.value)}})}),KI=w.forwardRef((e,n)=>{let{children:r,label:o="Suggestions",...s}=e,l=w.useRef(null),u=w.useRef(null),d=Hi(m=>m.selectedItemId),p=_l();return w.useEffect(()=>{if(u.current&&l.current){let m=u.current,y=l.current,v,b=new ResizeObserver(()=>{v=requestAnimationFrame(()=>{let x=m.offsetHeight;y.style.setProperty("--cmdk-list-height",x.toFixed(1)+"px")})});return b.observe(m),()=>{cancelAnimationFrame(v),b.unobserve(m)}}},[]),w.createElement($e.div,{ref:Fa(l,n),...s,"cmdk-list":"",role:"listbox",tabIndex:-1,"aria-activedescendant":d,"aria-label":o,id:p.listId},dd(e,m=>w.createElement("div",{ref:Fa(u,p.listInnerRef),"cmdk-list-sizer":""},m)))}),YI=w.forwardRef((e,n)=>{let{open:r,onOpenChange:o,overlayClassName:s,contentClassName:l,container:u,...d}=e;return w.createElement(sp,{open:r,onOpenChange:o},w.createElement(cp,{container:u},w.createElement(up,{"cmdk-overlay":"",className:s}),w.createElement(dp,{"aria-label":e.label,"cmdk-dialog":"",className:l},w.createElement(PC,{ref:n,...d}))))}),QI=w.forwardRef((e,n)=>Hi(r=>r.filtered.count===0)?w.createElement($e.div,{ref:n,...e,"cmdk-empty":"",role:"presentation"}):null),XI=w.forwardRef((e,n)=>{let{progress:r,children:o,label:s="Loading...",...l}=e;return w.createElement($e.div,{ref:n,...l,"cmdk-loading":"",role:"progressbar","aria-valuenow":r,"aria-valuemin":0,"aria-valuemax":100,"aria-label":s},dd(e,u=>w.createElement("div",{"aria-hidden":!0},u)))}),ud=Object.assign(PC,{List:KI,Item:BI,Input:ZI,Group:qI,Separator:GI,Dialog:YI,Empty:QI,Loading:XI});function JI(e,n){let r=e.nextElementSibling;for(;r;){if(r.matches(n))return r;r=r.nextElementSibling}}function WI(e,n){let r=e.previousElementSibling;for(;r;){if(r.matches(n))return r;r=r.previousElementSibling}}function UC(e){let n=w.useRef(e);return Oo(()=>{n.current=e}),n}var Oo=typeof window>"u"?w.useEffect:w.useLayoutEffect;function Aa(e){let n=w.useRef();return n.current===void 0&&(n.current=e()),n}function Hi(e){let n=fg(),r=()=>e(n.snapshot());return w.useSyncExternalStore(n.subscribe,r,r)}function HC(e,n,r,o=[]){let s=w.useRef(),l=_l();return Oo(()=>{var u;let d=(()=>{var m;for(let y of r){if(typeof y=="string")return y.trim();if(typeof y=="object"&&"current"in y)return y.current?(m=y.current.textContent)==null?void 0:m.trim():s.current}})(),p=o.map(m=>m.trim());l.value(e,d,p),(u=n.current)==null||u.setAttribute(Oa,d),s.current=d}),s}var eF=()=>{let[e,n]=w.useState(),r=Aa(()=>new Map);return Oo(()=>{r.current.forEach(o=>o()),r.current=new Map},[e]),(o,s)=>{r.current.set(o,s),n({})}};function tF(e){let n=e.type;return typeof n=="function"?n(e.props):"render"in n?n.render(e.props):e}function dd({asChild:e,children:n},r){return e&&w.isValidElement(n)?w.cloneElement(tF(n),{ref:n.ref},r(n.props.children)):r(n)}var nF={position:"absolute",width:"1px",height:"1px",padding:"0",margin:"-1px",overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",borderWidth:"0"};function rF({className:e,...n}){return h.jsx(ud,{"data-slot":"command",className:Xe("flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",e),...n})}function iF({className:e,...n}){return h.jsxs("div",{"data-slot":"command-input-wrapper",className:"flex h-9 items-center gap-2 border-b px-3",children:[h.jsx(f_,{className:"size-4 shrink-0 opacity-50"}),h.jsx(ud.Input,{"data-slot":"command-input",className:Xe("flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",e),...n})]})}function oF({className:e,...n}){return h.jsx(ud.List,{"data-slot":"command-list",className:Xe("max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto",e),...n})}function aF({className:e,...n}){return h.jsx(ud.Item,{"data-slot":"command-item",className:Xe("relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground",e),...n})}function uw(e,n){if(!e)return{score:0,hits:[]};const r=e.toLowerCase(),o=n.toLowerCase();let s=0,l=0,u=0;const d=[];for(let p=0;p3&&o.endsWith("ies")?s=o.slice(0,-3)+"y":o.length>3&&o.endsWith("es")?s=o.slice(0,-2):o.length>2&&o.endsWith("s")&&(s=o.slice(0,-1)),s?uw(s,n):null}function lF({text:e,hits:n}){const r=[];let o=0;return n.forEach((s,l)=>{s>o&&r.push(e.slice(o,s)),r.push(h.jsx("b",{children:e[s]},l)),o=s+1}),r.push(e.slice(o)),h.jsx("span",{className:"plabel",children:r})}function cF({open:e,onClose:n,candidates:r}){const[o,s]=w.useState(""),l=w.useMemo(()=>{if(!e)return[];const d=[];for(const p of r()){const m=sF(o,p.label);m&&d.push({...p,score:m.score,hits:m.hits})}return d.sort((p,m)=>m.score-p.score),d.slice(0,40)},[e,o,r]);w.useEffect(()=>{e&&s("")},[e]);const u=d=>{n(),d.run()};return h.jsx(Vp,{open:e,onOpenChange:d=>!d&&n(),children:h.jsxs(Pp,{id:"palette",className:"palette",showCloseButton:!1,"aria-describedby":void 0,children:[h.jsx(Yu,{className:"sr-only",children:"Search and quick actions"}),h.jsxs(rF,{shouldFilter:!1,loop:!0,children:[h.jsxs("div",{id:"palette-inputwrap",children:[h.jsx(ht,{name:"search"}),h.jsx(iF,{id:"palette-input",placeholder:"Search file names, projects, actions…",autoComplete:"off",spellCheck:!1,value:o,onValueChange:s})]}),h.jsx(oF,{id:"palette-results",children:l.length===0?h.jsx("div",{className:"pempty",children:"No matches — search covers file names, projects, and actions"}):l.map(d=>h.jsxs(aF,{value:d.kind+":"+d.label,onSelect:()=>u(d),children:[h.jsx("span",{className:"picon",children:h.jsx(ht,{name:d.icon})}),h.jsx(lF,{text:d.label,hits:d.hits}),h.jsx("span",{className:"pkind",children:d.kind})]},d.kind+":"+d.label))}),h.jsx("footer",{id:"palette-hint",children:"↑↓ navigate · ⏎ select · esc close"})]})]})})}const Qs=3,Ma=30;function uF(e,n){return Ht({queryKey:["heatDevices",e],queryFn:()=>sn(e+"heat?by=device&days=30"),enabled:n,retry:!1,staleTime:6e4}).data?.devices??null}function dw(e){const[n,r]=w.useState("all"),{flatFiles:o,heatMap:s,devices:l,scope:u}=e,d=b=>!u||b===u||b.startsWith(u+"/"),p=u?o.filter(b=>d(b.path)):o,m=l&&u?l.map(b=>{const x={};for(const[C,_]of Object.entries(b.folders||{}))d(C)&&(x[C]=_);return{...b,folders:x}}).filter(b=>Object.keys(b.folders).length>0):l,y=Date.now(),v=p.map(b=>{const x=s&&s[b.path]||{},C=b.time?Math.max(0,(y-new Date(b.time).getTime())/864e5):0,_=n==="all"?Ba(x):x[n]||0;return{path:b.path,reads:_,agent:x.agent||0,human:x.human||0,share:x.share||0,total:Ba(x),days:C,danger:_>=Qs&&C>=Ma}});return h.jsxs("div",{className:"insights",children:[h.jsxs("h1",{className:"in-title",children:["Knowledge insights",u?h.jsxs("span",{className:"in-scope",children:[" · ",u]}):null]}),h.jsx("p",{className:"dl-sub",children:u?`Reads over the last 30 days × freshness, for ${u} and everything in it.`:"Reads over the last 30 days × how long since each file changed. Hot but stale knowledge — read a lot, maintained by nobody — is the danger zone."}),h.jsx("div",{className:"in-lens",children:["all","human","agent"].map(b=>h.jsx("button",{className:"in-lens-btn"+(b===n?" active":""),onClick:()=>r(b),children:b==="all"?"All reads":b==="human"?"Human reads":"Agent reads"},b))}),h.jsx("h3",{className:"dl-h3",children:"Map — cell size = reads, color = freshness (scale below)"}),h.jsx(dF,{pts:v,onOpenFile:e.onOpenFile,onOpenFolder:e.onOpenFolder,isFolder:e.isFolder}),h.jsx("h3",{className:"dl-h3",children:"Reads × freshness"}),h.jsx(hF,{pts:v,onOpenFile:e.onOpenFile}),h.jsx("h3",{className:"dl-h3",children:"Hot path — top files by reads"}),h.jsx(mF,{pts:v,lens:n,onOpenFile:e.onOpenFile}),m&&m.length>0&&h.jsxs(h.Fragment,{children:[h.jsx("h3",{className:"dl-h3",children:"Agent coverage — which agents read which areas"}),h.jsx(pF,{devices:m})]})]})}function BC(e){const n=[[76,195,138],[232,196,84],[224,93,93]],r=Math.min(1,Math.max(0,e/300))*(n.length-1),o=Math.min(n.length-2,Math.floor(r)),s=r-o,l=n[o].map((u,d)=>Math.round(u+(n[o+1][d]-u)*s));return`rgb(${l[0]},${l[1]},${l[2]})`}function fw(e,n,r,o,s){const l=e.reduce((m,y)=>m+y.value,0);if(!l||o<=0||s<=0)return[];const u=e.slice().sort((m,y)=>y.value-m.value).map(m=>({it:m,a:m.value/l*o*s})),d=(m,y)=>{const b=m.reduce((C,_)=>C+_.a,0)/y;let x=0;for(const C of m){const _=C.a/b;x=Math.max(x,_/b,b/_)}return x},p=[];for(;u.length;){const m=o>=s,y=m?s:o,v=[u.shift()];for(;u.length&&d(v.concat(u[0]),y)<=d(v,y);)v.push(u.shift());const b=v.reduce((C,_)=>C+_.a,0)/y;let x=0;for(const C of v){const _=C.a/b;m?p.push({item:C.it,x:n,y:r+x,w:b,h:_}):p.push({item:C.it,x:n+x,y:r,w:_,h:b}),x+=_}m?(n+=b,o-=b):(r+=b,s-=b)}return p}const am=15;function hw(e,n,r){const o=Math.floor((r-8)/6),s=`${e} · ${n}`;return s.length<=o?{label:s,fit:o}:{label:e.length>o?e.slice(0,Math.max(1,o-1))+"…":e,fit:o}}const mw=(e,n)=>`${e} ${n}${e===1?"":"s"}`;function dF({pts:e,onOpenFile:n,onOpenFolder:r,isFolder:o}){const u=new Map;for(const p of e){const m=p.path.includes("/")?p.path.split("/")[0]:"/";let y=u.get(m);y||u.set(m,y={name:m,files:[],value:0,reads:0}),y.files.push(p),y.value+=p.reads+1,y.reads+=p.reads}const d=[];for(const p of fw([...u.values()],0,0,720,480)){const m=p.item,y=m.name==="/"?"":m.name,v=m.name==="/"?"(root)":m.name;if(d.push(h.jsx("rect",{x:p.x+1,y:p.y+1,width:Math.max(0,p.w-2),height:Math.max(0,p.h-2),rx:3,className:"in-tm-group","data-dir":y,children:h.jsx("title",{children:`${m.name==="/"?"(root)":m.name+"/"} — ${mw(m.reads,"read")}/30d · ${mw(m.files.length,"file")}`})},"g"+m.name)),p.w>46&&p.h>am+10){const{label:x}=hw(v,m.reads,p.w);d.push(h.jsx("text",{x:p.x+5,y:p.y+12,className:"in-tm-glabel","data-dir":y,children:x},"gl"+m.name))}const b=fw(m.files.map(x=>({...x,name:x.path.split("/").pop(),value:x.reads+1})),p.x+2,p.y+am,Math.max(0,p.w-4),Math.max(0,p.h-am-2));for(const x of b)if(d.push(h.jsx("rect",{x:x.x+.6,y:x.y+.6,width:Math.max(.4,x.w-1.2),height:Math.max(.4,x.h-1.2),rx:1.5,fill:BC(x.item.days),className:"in-tm-cell","data-path":x.item.path,children:h.jsx("title",{children:`${x.item.path} — ${x.item.reads} read${x.item.reads===1?"":"s"}/30d · changed ${Math.round(x.item.days)}d ago`})},x.item.path)),x.w>54&&x.h>16){const{label:C,fit:_}=hw((x.item.danger?"⚠ ":"")+x.item.name,x.item.reads,x.w);_>=5&&d.push(h.jsx("text",{x:x.x+4.5,y:x.y+12.5,className:"in-tm-label","data-path":x.item.path,children:C},"l"+x.item.path))}}return h.jsxs(h.Fragment,{children:[h.jsx("svg",{viewBox:"0 0 720 480",className:"in-chart in-treemap",onClick:p=>{const m=p.target.closest("[data-path], [data-dir]");if(!m)return;const y=m.getAttribute("data-path");if(y)return n(y);const v=m.getAttribute("data-dir");v&&o(v)&&r(v)},children:d}),h.jsx(fF,{pts:e})]})}function fF({pts:e}){const n=L8(e.map(o=>o.days));if(!n)return null;const r=I8(n.min,n.max);return h.jsxs("p",{className:"in-legend in-tm-legend",children:["freshness 0d",h.jsx("span",{className:"in-sw in-sw-age",style:{background:`linear-gradient(to right, ${[0,60,150,300].map(BC).join(", ")})`}}),"300d+",h.jsx("span",{className:"in-tm-range",children:$8(n.min,n.max)?`all files here: ${r} old — colour carries no signal in this range`:`observed: ${r} old`})]})}function hF({pts:e,onOpenFile:n}){const s={l:44,r:16,t:20,b:34},l=Math.max(Ma*2,...e.map(v=>v.days)),u=Math.max(Qs*2,...e.map(v=>v.reads)),d=v=>Math.log10(v+1)/Math.log10(l+1),p=v=>Math.log10(v+1)/Math.log10(u+1),m=v=>s.l+d(v)*(720-s.l-s.r),y=v=>360-s.b-p(v)*(360-s.t-s.b);return h.jsxs("svg",{viewBox:"0 0 720 360",className:"in-chart",children:[h.jsx("rect",{x:m(Ma),y:s.t,width:720-s.r-m(Ma),height:y(Qs)-s.t,className:"in-danger-zone"}),h.jsx("line",{x1:m(Ma),y1:s.t,x2:m(Ma),y2:360-s.b,className:"in-threshold"}),h.jsx("line",{x1:s.l,y1:y(Qs),x2:720-s.r,y2:y(Qs),className:"in-threshold"}),h.jsx("line",{x1:s.l,y1:360-s.b,x2:720-s.r,y2:360-s.b,className:"in-axis"}),h.jsx("line",{x1:s.l,y1:s.t,x2:s.l,y2:360-s.b,className:"in-axis"}),h.jsx("text",{x:(s.l+720-s.r)/2,y:352,className:"in-label",children:"days since last change →"}),h.jsx("text",{x:12,y:(s.t+360-s.b)/2,className:"in-label",transform:`rotate(-90 12 ${(s.t+360-s.b)/2})`,children:"reads / 30d →"}),h.jsx("text",{x:720-s.r-6,y:s.t+14,className:"in-quad in-quad-danger",textAnchor:"end",children:"hot + stale"}),h.jsx("text",{x:s.l+6,y:s.t+14,className:"in-quad",children:"hot + fresh"}),h.jsx("text",{x:720-s.r-6,y:360-s.b-8,className:"in-quad",textAnchor:"end",children:"cold + stale"}),h.jsx("text",{x:s.l+6,y:360-s.b-8,className:"in-quad",children:"cold + fresh"}),h.jsx("text",{x:720-s.r-6,y:s.t+28,className:"in-label",textAnchor:"end",children:"dot size = agent share of reads"}),e.map(v=>{const b=v.total?(v.agent||0)/v.total:0;return h.jsx("circle",{cx:Number(m(v.days).toFixed(1)),cy:Number(y(v.reads).toFixed(1)),r:Number((3+4*b).toFixed(1)),className:"in-pt"+(v.danger?" danger":v.reads?"":" cold"),onClick:()=>n(v.path),children:h.jsx("title",{children:`${v.path} — ${v.reads} read${v.reads===1?"":"s"} / 30d · changed ${Math.round(v.days)}d ago`})},v.path)})]})}function mF({pts:e,lens:n,onOpenFile:r}){const o=e.filter(u=>u.reads>0).sort((u,d)=>d.reads-u.reads||d.days-u.days).slice(0,20);if(!o.length)return h.jsx("div",{className:"dl-empty",children:"No reads in the window yet."});const s=o[0].reads,l=o.some(u=>u.share>0);return h.jsxs(h.Fragment,{children:[h.jsx("div",{className:"in-hotpath",children:o.map(u=>{const d=n==="agent"?{agent:1,human:0,share:0}:n==="human"?{agent:0,human:1,share:0}:z8(u),p=u.reads/s*100;return h.jsxs("div",{className:"in-hp-row",tabIndex:0,role:"button",title:u.danger?`${u.reads} read${u.reads===1?"":"s"}/30d · unchanged ${Math.round(u.days)}d — review this file`:u.path,onClick:()=>r(u.path),onKeyDown:m=>{(m.key==="Enter"||m.key===" ")&&(m.preventDefault(),r(u.path))},children:[h.jsx("span",{className:"in-hp-name"+(u.danger?" danger":""),children:u.path+(u.danger?" ⚠":"")}),h.jsxs("span",{className:"in-hp-bar",children:[h.jsx("span",{className:"in-hp-agent",style:{width:(p*d.agent).toFixed(1)+"%"}}),h.jsx("span",{className:"in-hp-human",style:{width:(p*d.human).toFixed(1)+"%"}}),h.jsx("span",{className:"in-hp-share",style:{width:(p*d.share).toFixed(1)+"%"}})]}),h.jsx("span",{className:"in-hp-count",children:u.reads})]},u.path)})}),h.jsxs("p",{className:"in-legend",children:[h.jsx("span",{className:"in-sw agent"})," agent reads ",h.jsx("span",{className:"in-sw human"})," human reads",l&&h.jsxs(h.Fragment,{children:[" ",h.jsx("span",{className:"in-sw share"})," shared reads"]})]})]})}function pF({devices:e}){const n=new Map;for(const b of e)for(const[x,C]of Object.entries(b.folders||{}))n.set(x,(n.get(x)||0)+C);const r=[...n.entries()].sort((b,x)=>x[1]-b[1]).slice(0,12).map(b=>b[0]),o=e.slice(0,12),s=140,l=6,u=Math.min(76,Math.max(34,(720-s-8)/r.length)),d=26,p=720,m=l+o.length*d+58,y=Math.max(1,...o.flatMap(b=>r.map(x=>(b.folders||{})[x]||0))),v=b=>{const x=[23,25,31],C=[245,166,35],_=x.map((E,T)=>Math.round(E+(C[T]-E)*b));return`rgb(${_[0]},${_[1]},${_[2]})`};return h.jsxs("svg",{viewBox:`0 0 ${p} ${m}`,className:"in-chart in-matrix",children:[o.map((b,x)=>{let C=b.name||b.id||"";return C.length>20&&(C=C.slice(0,19)+"…"),h.jsxs("g",{children:[h.jsx("text",{x:s-8,y:l+x*d+17,textAnchor:"end",className:"in-label",children:C}),r.map((_,E)=>{const T=(b.folders||{})[_]||0;return h.jsx("rect",{x:s+E*u,y:l+x*d,width:u-4,height:d-4,rx:3,fill:v(Math.sqrt(T/y)),children:h.jsx("title",{children:`${b.name||b.id} × ${_||"(root)"}: ${T} read${T===1?"":"s"}/30d`})},_)})]},b.id||x)}),r.map((b,x)=>{const C=s+x*u+(u-4)/2,_=l+o.length*d+14;return h.jsx("text",{x:C,y:_,className:"in-label",textAnchor:"end",transform:`rotate(-28 ${C} ${_})`,children:b||"(root)"},b)})]})}function qC(e){return new Set(e.entries.map(n=>n.path)).size}function gF(e){const n=l=>l.note+"\0"+(l.device?.id??""),r=new Map;e.forEach((l,u)=>{if(!l.note)return;const d=r.get(n(l));if(d){d.entries.push(l),d.idx.push(u);return}r.set(n(l),{note:l.note,entries:[l],idx:[u]})});const o=[],s=new Set;return e.forEach((l,u)=>{const d=l.note?r.get(n(l)):void 0;if(!d||qC(d)<2){o.push({i:u});return}s.has(d)||(s.add(d),o.push({run:d,i:u}))}),o}function vF(e){const{apiBase:n,target:r,isFolder:o,onMeta:s,onRendered:l,restore:u,remove:d}=e,p=r?o(r)?{prefix:r+"/"}:{path:r}:{prefix:""},m="path"in p&&p.path!==void 0?"path="+encodeURIComponent(p.path):"prefix="+encodeURIComponent(p.prefix??""),{data:y,error:v}=Ht({queryKey:["history",n,m,200],queryFn:()=>sn(n+"history?"+m+"&n=200"),staleTime:15e3});if(w.useEffect(()=>{v&&s("History unavailable: "+v.message)},[v,s]),w.useEffect(()=>{y&&l?.()},[y,l]),!y)return null;const b=y.entries||[],x=!!r&&!o(r),C=E=>{for(let T=E+1;Tb[E].kind==="delete"?C(E):b[E].blob;return h.jsxs("div",{className:"history",children:[b.length===0&&h.jsx("div",{className:"empty",children:"No history yet."}),gF(b).map((E,T)=>E.run?h.jsx(yF,{run:E.run,onOpen:e.onOpen,apiBase:n,perFile:x,prevBlob:C,restoreSha:_,restore:u,remove:d},"g"+T):h.jsx(dg,{entry:b[E.i],apiBase:n,onOpen:e.onOpen,diff:x?{apiBase:n,prev:C(E.i)}:void 0,restore:u,restoreSha:_(E.i)},"r"+E.i))]})}function yF({run:e,onOpen:n,apiBase:r,perFile:o,prevBlob:s,restoreSha:l,restore:u,remove:d}){const[p,m]=w.useState(!0),y=e.entries[0],v=ld(y),b=[y.device.name||y.device.id,y.device.os].filter(Boolean).join(" · "),x=e.entries.map(E=>new Date(E.time).getTime()),C=bF(Math.min(...x),Math.max(...x)),_=qC(e);return h.jsxs("div",{className:"hrun"+(p?" open":""),children:[h.jsxs("div",{className:"hrun-head",children:[h.jsx("button",{type:"button",className:"hrun-toggle","aria-expanded":p,title:p?"Collapse this run":"Expand this run",onClick:()=>m(!p),children:h.jsx(ht,{name:p?"chevd":"chev"})}),h.jsx("span",{className:"hrun-note",children:h.jsx(kC,{text:e.note})}),h.jsxs("span",{className:"hrun-meta",children:[_," file",_===1?"":"s"," · ",v,b?" · "+b:""]}),h.jsx("span",{className:"hrun-time",children:C})]}),p&&h.jsx("div",{className:"hrun-body",children:e.entries.map((E,T)=>h.jsx(dg,{entry:E,apiBase:r,onOpen:n,diff:o?{apiBase:r,prev:s(e.idx[T])}:void 0,restore:u,remove:d,restoreSha:l(e.idx[T]),inRun:!0},T))})]})}function bF(e,n){const r=new Date(e),o=new Date(n),s=u=>u.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});if(r.toDateString()!==o.toDateString())return r.toLocaleString()+" – "+o.toLocaleString();const l=o.toLocaleDateString();return e===n?l+" "+s(o):l+" "+s(r)+" – "+s(o)}function xF(e,n){return e?n(e)?e+"/ (folder)":e:"all changes"}function wF(e){const{apiBase:n,path:r,version:o}=e,s="path="+encodeURIComponent(r),{data:l}=Ht({queryKey:["history",n,s,200],queryFn:()=>sn(n+"history?"+s+"&n=200"),staleTime:15e3}),u=l?.entries?.find(y=>y.blob===o),d=u?ld(u):"",p=u?.time?new Date(u.time).toLocaleString():"",m=n+"blob?sha="+o+"&name="+encodeURIComponent(r.split("/").pop()||r)+"&download=1";return h.jsxs("div",{className:"vbanner",role:"status",children:[h.jsx("span",{className:"vb-icon",children:h.jsx(ht,{name:"clock"})}),h.jsxs("div",{className:"vb-text",children:[h.jsx("b",{children:[p&&"Version from "+p,d&&"by "+d].filter(Boolean).join(" ")||"Earlier version"}),h.jsx("span",{children:"This is not the current file."})]}),h.jsxs("div",{className:"vb-actions",children:[h.jsx("button",{className:"ai-btn",onClick:e.onViewCurrent,children:"View current"}),h.jsx("a",{className:"ai-btn",download:!0,href:m,children:"Download this version"})]})]})}function GC(e){const{config:n,apiBase:r,route:o,hub:s,project:l}=e,u=qp(),d=Ao(),{tree:p,flatFiles:m,dirIndex:y,loaded:v}=F8(r,!s||!!l),b=V8(r,s&&!!l&&!!n.reads?.enabled),x=s&&!!l&&!o.path&&!o.view,C=o.view==="dashboard"||x,_=uF(r,C);w.useEffect(()=>{C&&d.invalidateQueries({queryKey:["heat",r]})},[C,r,d]);const E=o.path,T=o.view?void 0:o.version,j=E||(o.view==="dashboard"||o.view==="history")&&o.viewTarget||"",O=!!E&&y.has(E),k=!!E&&v&&!O&&m.some(D=>D.path===E),I=!!E&&v&&!O&&!k,B=O&&!o.view,[H,V]=w.useState(()=>new Set),pe=w.useRef(!0);w.useEffect(()=>{if(!p||!pe.current)return;pe.current=!1;const D=(p.children||[]).filter($=>$.dir);D.length===1&&V($=>new Set($).add(D[0].path))},[p]),w.useEffect(()=>{!j||!v||V(D=>{const $=new Set(D);for(const W of sI(j))$.add(W);return y.has(j)&&$.add(j),$})},[j,v,y]);const ve=w.useCallback(D=>{V($=>{const W=new Set($);return W.has(D)?W.delete(D):W.add(D),W})},[]),de=w.useRef(null),Q=w.useRef(new Map),le=w.useRef({key:"",want:0,attempts:0});w.useEffect(()=>{le.current={key:u,want:g3()==="POP"?Q.current.get(u)??0:0,attempts:0}},[u]);const he=w.useCallback(()=>{const D=de.current,$=le.current;!D||$.key!==u||$.attempts>=3||($.attempts++,D.scrollTo({top:$.want,behavior:"instant"}))},[u]),xe=w.useCallback(()=>{de.current&&Q.current.set(u,de.current.scrollTop)},[u]),N=w.useCallback((D,$)=>{pn(Qu(D,l?.id,$)),mr()},[l?.id]),Z=w.useCallback(D=>pn(bo("history",l?.id,D)),[l?.id]),[ie,te]=w.useState(""),[ne,z]=w.useState(null),[M,U]=w.useState(!1),[X,K]=w.useState(!1);w.useEffect(()=>RD(()=>K(!0)),[]);const se=w.useRef(null),ee=e.panel??null,ge=!ee&&s&&!!l&&k&&wo(l.perm,"write"),{data:ye}=x_(l?.id,s&&!!l),Ne=w.useCallback(()=>{d.invalidateQueries({queryKey:["shares",l?.id]})},[d,l?.id]),Ie=k?(ye||[]).filter(D=>D.path===E):[],Ve=!ee&&s&&!!l,dt=!ee&&k,Qe=!ee&&(k||s&&!!l&&O),vn=T?r+"blob?sha="+T+"&name="+encodeURIComponent(E)+"&download=1":r+"download?path="+encodeURIComponent(E),cn=w.useCallback(async()=>{try{const D=await fetch(r+"shares",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:E})});if(!D.ok)throw new Error(await D.text());const $=await D.json();Tw("share_created");const W=await Ha($.url);z({url:$.url,copied:W}),Ne()}catch(D){Ke("Share failed: "+D.message,!0)}},[r,E,Ne]),[Kt,ir]=w.useState(""),Dt=s&&!!l&&wo(l?.perm,"write"),or=w.useCallback(async(D,$)=>{ir(D+$);try{await So(r+"restore",{path:D,sha:$}),d.invalidateQueries({queryKey:["history",r]}),d.invalidateQueries({queryKey:["tree",r]}),d.invalidateQueries({queryKey:["render",r,D]}),d.invalidateQueries({queryKey:["text"]}),Ke("Restored "+D+" — it syncs to every device like any other change.")}catch(W){Ke("Restore failed: "+W.message,!0)}finally{ir("")}},[r,d]),[Nr,jt]=w.useState(""),Un=w.useCallback(async D=>{if(await xl("Remove "+D+"?","It disappears from every synced device. History keeps it — you can restore it from the DELETED row afterwards.","Remove file",!0)){jt(D);try{await So(r+"remove",{path:D}),d.invalidateQueries({queryKey:["history",r]}),d.invalidateQueries({queryKey:["tree",r]}),d.invalidateQueries({queryKey:["render",r,D]}),d.invalidateQueries({queryKey:["text"]}),Ke("Removed "+D+" — it syncs to every device like any other change.")}catch($){Ke("Remove failed: "+$.message,!0)}finally{jt("")}}},[r,d]),xt=w.useCallback(()=>{if(!E)return Z("");Z(O?E+"/":E)},[E,O,Z]);w.useEffect(()=>{const D=$=>{($.metaKey||$.ctrlKey)&&$.key.toLowerCase()==="k"&&($.preventDefault(),K(W=>!W))};return window.addEventListener("keydown",D),()=>window.removeEventListener("keydown",D)},[]);const oi=w.useCallback(()=>{const D=[],$=(W,ue,me,be)=>D.push({icon:W,label:ue,kind:me,run:be});if(s&&l&&E&&(k&&$("share","Share: "+E,"action",cn),$("hist","History: "+E,"action",xt),k&&$("download","Download: "+E,"action",()=>se.current?.click())),s&&l&&$("hist","History: whole project","action",()=>Z("")),s)for(const W of e.projects||[])(!l||W.id!==l.id)&&$("folder","Switch to project: "+W.name,"project",()=>pn("/"+W.id));n.auth?.enabled&&$("power","Sign out","action",()=>window.location.href="/auth/logout");for(const W of y.keys())$("folder",W,"folder",()=>N(W));for(const W of m)$("doc",W.path,"file",()=>N(W.path));return D},[s,l,E,k,n.auth?.enabled,y,m,e.projects,cn,xt,Z,N]);w.useEffect(()=>{if(!M)return;const D=()=>U(!1);return document.addEventListener("click",D),()=>document.removeEventListener("click",D)},[M]);const yn=w.useCallback(D=>y.has(D),[y]);let Dr="app",ar,Yt;ee?Yt=ee.body:o.view==="dashboard"?Yt=h.jsx(dw,{flatFiles:m,heatMap:b,devices:_,scope:o.viewTarget||"",onOpenFile:N,onOpenFolder:N,isFolder:yn}):o.view==="history"?Yt=h.jsx(vF,{apiBase:r,target:o.viewTarget||"",isFolder:yn,onOpen:N,onMeta:te,onRendered:he,restore:Dt?{onRestore:or,busy:Kt}:void 0,remove:Dt?{onRemove:Un,busy:Nr}:void 0}):E?v?I?Yt=h.jsxs("div",{className:"notfound",children:[h.jsx("h1",{children:"Couldn't find that"}),h.jsxs("p",{children:[h.jsx("code",{children:E})," isn't in this project right now."]}),h.jsx("p",{className:"nf-sub",children:"If it was just created, it may still be uploading or syncing from a teammate's device — this page checks again automatically every few seconds, so refresh or come back in a moment."}),h.jsx("button",{className:"pbtn",onClick:()=>d.invalidateQueries({queryKey:["tree",r]}),children:"Check again"})]}):O?Yt=h.jsx(bI,{node:y.get(E),heatMap:b,hub:s&&!!l,apiBase:r,onOpen:N,onFullHistory:Z,onRendered:he}):(Dr=bC.test(E)||xC.test(E)?"wide":"read",ar="markdown",Yt=h.jsxs(h.Fragment,{children:[T&&h.jsx(wF,{apiBase:r,path:E,version:T,onViewCurrent:()=>N(E)}),h.jsx(wI,{apiBase:r,path:E,version:T,heatMap:b,flatFiles:m,onOpenFile:N,onMeta:te,onRendered:he})]})):Yt=h.jsx("div",{className:"empty",children:"Loading…"}):x?Yt=h.jsxs(h.Fragment,{children:[h.jsx(MC,{project:l}),h.jsx("div",{className:"home-insights",children:h.jsx(dw,{flatFiles:m,heatMap:b,devices:_,onOpenFile:N,onOpenFolder:N,isFolder:yn})})]}):Yt=h.jsx("div",{className:"empty",children:"Select a file to read it."});const bn=ee?ee.crumb:E?h.jsx(lI,{path:E,onOpenFolder:N}):o.view==="dashboard"?"Dashboard — "+(o.viewTarget||l?.name||""):o.view==="history"?"History — "+xF(o.viewTarget||"",yn):x?l.name:null,A=h.jsx(ll,{crumb:bn,meta:ie,actions:h.jsxs(h.Fragment,{children:[ge&&h.jsx(Tt,{id:"share-btn",variant:"toolbar",className:"icon-only",title:"Share","aria-label":"Share",onClick:cn,children:h.jsx(ht,{name:"share"})}),Ve&&!E&&!o.view&&h.jsxs(Tt,{id:"history-btn",variant:"toolbar",onClick:xt,children:[h.jsx(ht,{name:"hist"})," ",h.jsx("span",{className:"lbl",children:"History"})]}),dt&&h.jsx("a",{id:"download",hidden:!0,download:!0,href:vn,ref:se,children:"Download"}),Qe&&h.jsx(Tt,{id:"more-btn",variant:"toolbar",className:"icon-only",title:"More actions","aria-label":"More actions",onClick:D=>{D.stopPropagation(),U(!M)},children:h.jsx(ht,{name:"dots"})}),M&&h.jsxs("div",{id:"more-menu",role:"menu",children:[Ve&&h.jsx("button",{className:"more-item",onClick:xt,children:"History"}),dt&&h.jsx("button",{className:"more-item",onClick:()=>se.current?.click(),children:"Download"}),s&&!!l&&h.jsx("button",{className:"more-item",onClick:()=>{e.onClosePanel?.(),pn(bo("dashboard",l?.id,E))},children:"Dashboard"})]})]})});return h.jsxs(h.Fragment,{children:[h.jsx(sl,{vault:e.sidebar.vault,projectsNav:e.sidebar.projectsNav,orgBar:e.sidebar.orgBar,tree:h.jsx(aI,{root:p,expanded:H,onToggle:ve,currentPath:j,listingShowing:B,onOpen:N}),topbar:A,contentRef:de,onContentScroll:xe,children:h.jsxs(yu,{width:Dr,className:ar,children:[!ee&&k&&h.jsx(NI,{shares:Ie,canRevoke:!!l&&wo(l.perm,"write"),onChanged:Ne}),Yt]})}),ne&&h.jsx(MI,{url:ne.url,copied:ne.copied,onClose:()=>{z(null),Ne()}}),h.jsx(cF,{open:X,onClose:()=>K(!1),candidates:oi})]})}function SF({config:e}){const n=qp(),r=Hp(),[o,s]=w.useState(null),[l,u]=w.useState(null);w.useEffect(()=>u(null),[n]);const d=w.useMemo(()=>{const V=n.split("?")[0].match(/^\/join\/([0-9a-f]+)\/?$/);return V?V[1]:null},[n]),{data:p}=u3(!d),{data:m}=d3(!d),y=!!e.auth.admin,{data:v}=w_(y),b=w.useMemo(()=>__(n,"hub"),[n]),x=w.useMemo(()=>p&&(p.find(V=>V.id===b.project)||o&&p.find(V=>V.org===o)||p[0])||null,[p,b.project,o]);if(w.useEffect(()=>{document.title=x?x.name+" — BearDrive":e.brand||"BearDrive"},[x,e]),d)return h.jsx(_F,{token:d,onDone:async V=>{s(V),await r(),pn("/",{replace:!0})}});const C=e.brand||"BearDrive",_=x&&m?.find(V=>V.id===x.org)||null,E=h.jsx(Ku,{name:C,onHome:()=>pn("/"),search:!!x}),T=e.me?h.jsx(_8,{me:e.me,org:_,orgActive:!!b.org,billing:e.billing,admin:y?{pending:v?.length||0,onClick:()=>{u({kind:"hub"}),mr()}}:void 0}):void 0;if(!p||!m)return h.jsx(sl,{vault:E,topbar:h.jsx(ll,{}),children:h.jsx(yu,{children:h.jsx("div",{className:"empty",children:"Loading…"})})});if(!x)return h.jsx(sl,{vault:E,projectsNav:h.jsx(ew,{projects:p}),orgBar:T,topbar:h.jsx(ll,{}),children:h.jsx(yu,{children:h.jsx(N8,{})})});const j=l?.kind==="hub"?{crumb:"Signup & access",body:h.jsx(p8,{})}:null,O=b.org?m.find(V=>V.id===b.org):null,I=b.org&&!O?{crumb:"Organization",body:h.jsxs("div",{className:"empty",children:[h.jsx("h3",{children:"Organization not found"}),h.jsx("p",{children:"This organization doesn't exist, or you're no longer a member."}),h.jsx("p",{children:h.jsxs("a",{...bu("/"+x.id),children:["Back to ",x.name]})})]})}:O?{crumb:"Organization",body:h.jsx(f8,{org:O,projects:p,myEmail:e.me?.email||""})}:null,B=b.billing?{crumb:"Billing",body:e.billing?h.jsx(C8,{url:e.billing.url}):h.jsxs("div",{className:"empty",children:[h.jsx("h3",{children:"No billing on this hub"}),h.jsx("p",{children:"This BearDrive hub doesn't have a billing surface."})]})}:null,H=b.view==="settings"?{crumb:"Project settings",body:h.jsx(j8,{project:x,org:_,onDeleted:async()=>{await r(),pn("/")}})}:b.view==="install"?{crumb:"Installation",body:h.jsx(MC,{project:x})}:null;return!b.org&&!b.billing&&b.project!==x.id?h.jsx(ou,{to:"/"+x.id}):b.legacyView&&b.view?h.jsx(ou,{to:bo(b.view,x.id,b.viewTarget)}):b.trailingSlash&&b.path?h.jsx(ou,{to:Qu(b.path,x.id,b.version)}):h.jsx(GC,{config:e,apiBase:"/api/p/"+x.id+"/",route:b,hub:!0,project:x,projects:p,sidebar:{vault:E,projectsNav:h.jsx(ew,{projects:p,currentId:x.id,menu:{active:l?null:b.view==="dashboard"&&!b.viewTarget?"dashboard":b.view==="install"?"install":b.view==="history"&&!b.viewTarget?"history":b.view==="settings"?"settings":null,onDashboard:()=>{u(null),pn(bo("dashboard",x.id)),mr()},onInstall:()=>{u(null),pn(bo("install",x.id)),mr()},onHistory:()=>{u(null),pn(bo("history",x.id)),mr()},onSettings:()=>{u(null),pn(bo("settings",x.id)),mr()}}}),orgBar:T},panel:j||I||B||H,onClosePanel:()=>u(null)},x.id)}function _F({token:e,onDone:n}){return w.useEffect(()=>{let r=!1;return So("/api/invites/"+e).then(o=>{r||(Ke(`Welcome — you joined the “${o.org.name}” team. Opening its projects…`),n(o.org.id))}).catch(o=>{r||String(o.message).includes("signing in")||(Ke("Could not accept the invite: "+o.message,!0),n(null))}),()=>{r=!0}},[e]),h.jsx(sl,{vault:h.jsx(Ku,{name:"BearDrive"}),topbar:h.jsx(ll,{}),children:h.jsx(yu,{children:h.jsx("div",{className:"empty",children:"Joining…"})})})}function CF({config:e}){const n=qp(),r=e.volume||"BearDrive";w.useEffect(()=>{document.title=e.brand||r},[e,r]);const o=w.useMemo(()=>__(n,"volume"),[n]);return o.trailingSlash&&o.path?h.jsx(ou,{to:Qu(o.path)}):h.jsx(GC,{config:e,apiBase:"/api/",route:o,hub:!1,sidebar:{vault:h.jsx(Ku,{name:r,showSignout:e.auth.enabled,search:!0})}})}function EF(){const{data:e}=nT();return h.jsxs(SD,{delayDuration:150,children:[e?e.mode==="hub"?h.jsx(SF,{config:e}):h.jsx(CF,{config:e}):h.jsx(sl,{vault:h.jsx(Ku,{name:"…",showSignout:!1}),topbar:h.jsx(ll,{}),children:h.jsx("div",{className:"empty",children:"Loading…"})}),h.jsx(n3,{}),h.jsx(s3,{})]})}const RF=new F2({defaultOptions:{queries:{retry:1,refetchOnWindowFocus:!1}}});h2.createRoot(document.getElementById("root")).render(h.jsx(w.StrictMode,{children:h.jsx(V2,{client:RF,children:h.jsx(EF,{})})})); +`);return n[n.length-1]===""&&n.pop(),n}const cI=4e6;function uI(e,n){let r=0;for(;rs.push({op:"-",line:l[v],an:r+v+1}),y=v=>s.push({op:"+",line:u[v],bn:r+v+1});if(d*p>cI){for(let v=0;v=0;C--)for(let _=p-1;_>=0;_--)v[C][_]=l[C]===u[_]?v[C+1][_+1]+1:Math.max(v[C+1][_],v[C][_+1]);let b=0,x=0;for(;b=v[b][x+1]?m(b++):y(x++);for(;bo.op==="+").length,del:r.filter(o=>o.op==="-").length}}const DC=1<<20,fI=8192;function hI(e){if(e.byteLength>DC)return{kind:"too-large",size:e.byteLength};if(e.subarray(0,fI).includes(0))return{kind:"binary"};try{return{kind:"text",text:new TextDecoder("utf-8",{fatal:!0}).decode(e)}}catch{return{kind:"binary"}}}function Zm(e,n,r,o){let s=e+"blob?sha="+encodeURIComponent(n);return r&&(s+="&name="+encodeURIComponent(r)),o&&(s+="&download=1"),s}async function mI(e){const n=await tT(e),r=Number(n.headers.get("Content-Length"));return r>DC?{kind:"too-large",size:r}:hI(new Uint8Array(await n.arrayBuffer()))}function zC(e,n,r,o){return Ht({queryKey:n,queryFn:()=>mI(e),enabled:r,...o?{staleTime:1/0,gcTime:1/0}:{},retry:!1})}function aw(e,n,r){return zC(n?Zm(e,n):"",["blob",e,n],!!n,!0)}function pI(e){return e.slice(e.lastIndexOf("/")+1)}function gI({apiBase:e,path:n,prev:r,cur:o}){const s=pI(n);return h.jsxs("span",{className:"dv-dl",children:[h.jsx("a",{href:Zm(e,r,s,!0),children:"download previous"}),h.jsx("a",{href:Zm(e,o,s,!0),children:"download this version"})]})}function vI({apiBase:e,path:n,prev:r,cur:o}){const s=aw(e,r),l=aw(e,o),u=s.data?.kind==="text"&&l.data?.kind==="text",d=w.useMemo(()=>s.data?.kind==="text"&&l.data?.kind==="text"?dI(s.data.text,l.data.text):null,[s.data,l.data]);if(s.error||l.error)return h.jsx("div",{className:"dv dv-msg",children:"Could not load one of the versions."});if(!s.data||!l.data)return h.jsx("div",{className:"dv dv-msg",children:"Loading changes…"});if(!u){const v=s.data.kind==="too-large"||l.data.kind==="too-large";return h.jsxs("div",{className:"dv dv-msg",children:[v?"Too large to diff — download to compare.":"Binary file — no diff available.",h.jsx(gI,{apiBase:e,path:n,prev:r,cur:o})]})}const{lines:p,add:m,del:y}=d;return h.jsxs("div",{className:"dv",children:[h.jsxs("div",{className:"dv-head",children:[h.jsxs("span",{className:"dv-stat",children:[h.jsxs("span",{className:"dv-add",children:["+",m]})," ",h.jsxs("span",{className:"dv-del",children:["−",y]})]}),m===0&&y===0&&h.jsx("span",{className:"dv-same",children:"No line changes"})]}),h.jsx("div",{className:"dv-body",children:p.map((v,b)=>h.jsxs("div",{className:"dv-line dv-"+(v.op==="="?"ctx":v.op==="+"?"ins":"rm"),children:[h.jsx("span",{className:"dv-n",children:v.an??""}),h.jsx("span",{className:"dv-n",children:v.bn??""}),h.jsx("span",{className:"dv-mark",children:v.op==="="?" ":v.op}),h.jsx("span",{className:"dv-text",children:v.line||" "})]},b))})]})}const yI={add:"added",edit:"edited",delete:"deleted"};function kC({text:e}){return h.jsx(h.Fragment,{children:e.split(/(https?:\/\/\S+)/).map((n,r)=>/^https?:\/\//.test(n)?h.jsx("a",{href:n,target:"_blank",rel:"noopener",children:n},r):n)})}function dg({entry:e,apiBase:n,onOpen:r,diff:o,restore:s,remove:l,restoreSha:u,inRun:d}){const[p,m]=w.useState(!1),[y,v]=w.useState(!1),b=e.kind==="put"?"edit":e.kind,x=ld(e),C=[e.device.name||e.device.id,e.device.os].filter(Boolean).join(" · "),_=b!=="delete",E=!!o&&b!=="delete"&&!!e.blob,T=!!d&&b==="add",j=!!s&&!!u&&!T,O=!!l&&T,k=!!s?.busy&&s.busy===e.path+u,I=!!l?.busy&&l.busy===e.path,B=_&&!!e.blob,H=e.path.split("/").pop()||e.path,V=new Date(e.time).toLocaleString(),pe=n+"blob?sha="+e.blob+"&name="+encodeURIComponent(H)+"&download=1",ve=()=>v(!y),de=Q=>{Q.target.tagName!=="A"&&_&&r(e.path,e.blob)};return h.jsxs("div",{className:"hentry "+b+(_?" clickable":""),tabIndex:_?0:void 0,role:_?"button":void 0,onClick:de,onKeyDown:Q=>{_&&(Q.key==="Enter"||Q.key===" ")&&(Q.preventDefault(),r(e.path,e.blob))},children:[h.jsxs("div",{className:"hline",children:[h.jsx("span",{className:"hkind",children:yI[b]||b}),h.jsx("span",{className:"hpath",children:e.path}),h.jsx("span",{className:"htime",children:V})]}),h.jsxs("div",{className:"hmeta",children:[h.jsx("span",{className:"hwho",children:x}),h.jsx("span",{className:"hdev",children:C}),h.jsx("span",{className:"hsize",children:e.size?ug(e.size):""}),j&&h.jsxs("button",{type:"button",className:"hrestore-btn",disabled:k,title:"Put this version of "+e.path+" back as a new change",onClick:Q=>{Q.stopPropagation(),s.onRestore(e.path,u)},onKeyDown:Q=>Q.stopPropagation(),children:[h.jsx(ht,{name:"hist"}),k?"restoring…":"restore"]}),O&&h.jsxs("button",{type:"button",className:"hremove-btn",disabled:I,title:"Remove "+e.path+" — this run created it",onClick:Q=>{Q.stopPropagation(),l.onRemove(e.path)},onKeyDown:Q=>Q.stopPropagation(),children:[h.jsx(ht,{name:"trash"}),I?"removing…":"undo — remove file"]})]}),e.note&&!d&&h.jsx("div",{className:"hnote"+(p?" open":""),tabIndex:0,role:"button",title:p?"Collapse note":"Show full note","aria-expanded":p,onClick:Q=>{Q.stopPropagation(),Q.target.tagName!=="A"&&m(!p)},onKeyDown:Q=>{(Q.key==="Enter"||Q.key===" ")&&(Q.preventDefault(),Q.stopPropagation(),m(!p))},children:h.jsx(kC,{text:e.note})}),(E||B)&&h.jsxs("div",{className:"hactions",children:[E&&(o.prev?h.jsxs("button",{type:"button",className:"hdiff-btn"+(y?" open":""),"aria-expanded":y,onClick:Q=>{Q.stopPropagation(),ve()},onKeyDown:Q=>Q.stopPropagation(),children:[h.jsx(ht,{name:y?"chevd":"chev"}),y?"hide changes":"show changes"]}):h.jsx("div",{className:"hdiff-none",children:"First version — nothing to compare against"})),B&&h.jsxs(h.Fragment,{children:[h.jsxs("button",{type:"button",className:"hver-btn","aria-label":`Open ${H} as of ${V}`,onClick:Q=>{Q.stopPropagation(),r(e.path,e.blob)},onKeyDown:Q=>Q.stopPropagation(),children:[h.jsx(ht,{name:"clock"}),"Open this version"]}),h.jsxs("a",{className:"hver-btn",download:!0,href:pe,"aria-label":`Download ${H} as of ${V}`,onClick:Q=>Q.stopPropagation(),onKeyDown:Q=>{Q.stopPropagation(),Q.key===" "&&(Q.preventDefault(),Q.currentTarget.click())},children:[h.jsx(ht,{name:"download"}),"Download"]})]})]}),E&&o.prev&&y&&h.jsx("div",{onClick:Q=>Q.stopPropagation(),children:h.jsx(vI,{apiBase:o.apiBase,path:e.path,prev:o.prev,cur:e.blob})})]})}function bI(e){const{node:n,heatMap:r,onOpen:o}=e,s=(n.children||[]).slice().sort((m,y)=>Number(y.dir||!1)-Number(m.dir||!1)||m.name.localeCompare(y.name)),l=s.filter(m=>m.dir).length,u=s.length-l,d=[];l&&d.push(l+(l===1?" folder":" folders")),u&&d.push(u+(u===1?" file":" files"));const p=nw(r,n.path,!0);return p&&d.push(Ys(p)+" in 30 days"),h.jsxs("div",{className:"dirlist",children:[h.jsxs("h1",{className:"dl-title",children:[h.jsx("span",{className:"dl-title-icon",children:h.jsx(ht,{name:"folder"})}),h.jsx("span",{children:n.name})]}),h.jsx("p",{className:"dl-sub",children:d.join(" · ")||"Empty folder"}),s.length===0?h.jsx("div",{className:"dl-empty",children:"Nothing in this folder yet."}):h.jsx("div",{className:"dl-items",children:s.map(m=>{let y="";if(m.dir){const b=(m.children||[]).length;y=b+(b===1?" item":" items")}else y=[m.size?ug(m.size):"",m.time?new Date(m.time).toLocaleDateString():""].filter(Boolean).join(" · ");const v=nw(r,m.path,!!m.dir);return v&&(y=Ys(v)+(y?" · "+y:"")),h.jsxs("div",{className:"dl-row",tabIndex:0,role:"button",title:m.path,onClick:()=>o(m.path),onKeyDown:b=>{(b.key==="Enter"||b.key===" ")&&(b.preventDefault(),o(m.path))},children:[h.jsx("span",{className:"ticon",children:h.jsx(ht,{name:m.dir?"folder":"doc"})}),h.jsx("span",{className:"dl-name",children:m.name}),v&&h.jsx("span",{className:"heatdot lvl"+D8(v),role:"img","aria-label":Ys(v)+" in 30 days",title:Ys(v)+" in 30 days"}),h.jsx("span",{className:"dl-meta",children:y})]},m.path)})}),e.hub&&h.jsx(xI,{apiBase:e.apiBase,prefix:n.path+"/",onOpen:o,onFullHistory:()=>e.onFullHistory(n.path+"/"),onRendered:e.onRendered})]})}function xI(e){const n=P8(e.apiBase,e.prefix,!0),{onRendered:r}=e;return w.useEffect(()=>{n&&n.length&&r&&r()},[n,r]),!n||n.length===0?null:h.jsxs("div",{className:"dl-history",children:[h.jsx("h3",{className:"dl-h3",children:"Recent changes"}),h.jsx("div",{className:"history dl-hlist",children:n.map((o,s)=>h.jsx(dg,{entry:o,apiBase:e.apiBase,onOpen:e.onOpen},s))}),h.jsx("button",{className:"ai-btn dl-more",onClick:e.onFullHistory,children:"Full history"})]})}function wI(e){const{apiBase:n,path:r,version:o,onMeta:s}=e,l=o?n+"blob?sha="+o+"&name="+encodeURIComponent(r):n+"file?path="+encodeURIComponent(r);return w.useEffect(()=>()=>s(""),[r,s]),r8.test(r)?h.jsx(CI,{...e}):bC.test(r)?h.jsx("iframe",{className:"htmlview",sandbox:"allow-scripts",src:l,title:r,onLoad:e.onRendered}):xC.test(r)?h.jsx("iframe",{className:"pdfview",src:l,title:r,onLoad:e.onRendered}):i8.test(r)?h.jsx(TI,{src:l,alt:r,version:o,onRendered:e.onRendered}):o8.test(r)?h.jsx(jI,{...e,fileURL:l}):h.jsx(SI,{...e,fileURL:l})}function SI(e){const{apiBase:n,path:r,version:o,fileURL:s,onRendered:l}=e,{data:u,error:d}=zC(s,["text",s],!0,!!o);return w.useEffect(()=>{u&&l?.()},[u,l]),d?h.jsx(cd,{version:o,err:d}):u?u.kind==="text"?h.jsx("pre",{className:"plain",children:u.text},r):h.jsx(_I,{apiBase:n,path:r,version:o,fileURL:s,children:u.kind==="too-large"?`Too large to preview (${ug(u.size)}).`:"No preview for this file type."}):null}function _I(e){const{apiBase:n,path:r,version:o,fileURL:s}=e;return h.jsxs("div",{className:"filecard",children:[h.jsx("div",{className:"name",children:r.split("/").pop()}),h.jsx("p",{children:e.children}),h.jsx("a",{className:"btn",download:!0,href:o?s+"&download=1":n+"download?path="+encodeURIComponent(r),children:"Download"})]})}function CI(e){const{apiBase:n,path:r,version:o,heatMap:s,flatFiles:l,onOpenFile:u,onMeta:d,onRendered:p}=e,{data:m,error:y}=Ht({queryKey:["render",n,r,o||""],queryFn:()=>sn(n+"render?path="+encodeURIComponent(r)+(o?"&sha="+o:"")),retry:o?!1:void 0}),v=w.useMemo(()=>m?RI(m.html,r,n):"",[m,r,n]);return w.useEffect(()=>{if(!m)return;const b=[];(m.user_name||m.user||m.author)&&b.push(ld(m)+(m.device?" on "+m.device:"")),m.time&&b.push(new Date(m.time).toLocaleString());const x=o?null:s&&s[m.path];x&&Ba(x)&&b.push(Ys(x)+" / 30d"),d(b.join(" · ")),p?.()},[m,o,s,d,p]),y?h.jsx(cd,{version:o,err:y}):m?h.jsx("div",{dangerouslySetInnerHTML:{__html:v},onClick:b=>EI(b,r,l,u)}):null}function EI(e,n,r,o){const s=e.target.closest("a");if(!s||!e.currentTarget.contains(s))return;const l=s.getAttribute("href")||"",u=n.includes("/")?n.slice(0,n.lastIndexOf("/")):"";l.startsWith("wiki:")?(e.preventDefault(),OI(decodeURIComponent(l.slice(5)),r,o)):/^([a-z]+:|\/|#)/i.test(l)||(e.preventDefault(),o(wC(u,decodeURIComponent(l))))}function RI(e,n,r){const o=n.includes("/")?n.slice(0,n.lastIndexOf("/")):"",s=u=>r+"file?path="+encodeURIComponent(u),l=new DOMParser().parseFromString(e,"text/html");for(const u of l.querySelectorAll("img")){const d=u.getAttribute("src")||"";/^([a-z]+:|\/)/i.test(d)||u.setAttribute("src",s(wC(o,d)))}for(const u of l.querySelectorAll("a")){const d=u.getAttribute("href")||"";/^https?:/i.test(d)&&(u.setAttribute("target","_blank"),u.setAttribute("rel","noopener"))}return l.body.innerHTML}function TI(e){const[n,r]=w.useState(!1);return n?h.jsx(cd,{version:e.version,err:new Error("could not be loaded")}):h.jsx("img",{src:e.src,alt:e.alt,onLoad:e.onRendered,onError:()=>r(!0)})}function cd({version:e,err:n}){return h.jsx("div",{className:"empty",children:e?"That version isn't available.":"Could not load file: "+n.message})}function jI(e){const{path:n,version:r,fileURL:o,onRendered:s}=e,{data:l,error:u}=Ht({queryKey:["text",o],queryFn:async()=>{const d=await fetch(o);if(!d.ok)throw new Error(await d.text());return d.text()},retry:r?!1:void 0});return w.useEffect(()=>{l!=null&&s?.()},[l,s]),u?h.jsx(cd,{version:r,err:u}):l==null?null:h.jsx("pre",{className:"plain",children:l},n)}function OI(e,n,r){const o=e.toLowerCase(),s=n.find(l=>l.path.toLowerCase()===o||l.path.toLowerCase()===o+".md")||n.find(l=>{const u=l.name.toLowerCase();return u===o||u===o+".md"});s&&r(s.path)}const AI=[{value:"",label:"Never"},{value:"24h",label:"In 24 hours"},{value:"168h",label:"In 7 days"},{value:"720h",label:"In 30 days"}];function MI({url:e,copied:n,onClose:r}){const o=e.split("/s/")[1],[s,l]=w.useState(""),[u,d]=w.useState(),[p,m]=w.useState(!1),y=w.useRef(null);async function v(b){const x=s;l(b),m(!0);try{const C=await er("PATCH","/api/shares/"+o,{expires_in:b});d(C.expires)}catch(C){Ke(C.message,!0),l(x)}finally{m(!1)}}return h.jsx(Vp,{open:!0,onOpenChange:b=>!b&&r(),children:h.jsxs(Pp,{className:"modal",showCloseButton:!1,onOpenAutoFocus:b=>{b.preventDefault(),y.current?.focus()},children:[h.jsx(Yu,{asChild:!0,children:h.jsx("h3",{children:"Public link"})}),h.jsxs("p",{children:[h.jsx("b",{children:"Anyone with this link can view this file"})," — no account needed. It always shows the latest version until it expires or you revoke it."]}),h.jsx("div",{className:"modal-url",children:e}),h.jsxs("div",{className:"modal-expiry",children:[h.jsx("label",{htmlFor:"share-expiry",children:"Expires"}),h.jsx("select",{id:"share-expiry",value:s,disabled:p,onChange:b=>v(b.target.value),children:AI.map(b=>h.jsx("option",{value:b.value,children:b.label},b.value))}),h.jsx("span",{className:"modal-expiry-note",children:_C(u)})]}),h.jsxs("div",{className:"modal-actions",children:[h.jsx(Tt,{ref:y,variant:"primary",onClick:()=>Ha(e).then(b=>Ke(b?"Copied.":"Select and copy the link above.")),children:n?"Copied ✓":"Copy link"}),h.jsx(Tt,{variant:"subtle",onClick:()=>window.open(e,"_blank"),children:"Open"}),h.jsx(Tt,{variant:"subtle",onClick:r,children:"Done"})]})]})})}function NI({shares:e,canRevoke:n,onChanged:r}){return e.length===0?null:h.jsxs("div",{className:"share-banner",role:"status",children:[h.jsxs("div",{className:"sb-head",children:[h.jsx(ht,{name:"share"}),h.jsx("b",{children:"Publicly shared"}),h.jsxs("span",{className:"sb-count",children:[e.length," active link",e.length>1?"s":""]})]}),h.jsxs("p",{className:"sb-note",children:[h.jsx("b",{children:"Anyone with this link can view this file"})," — no account needed. It always shows the latest version until you revoke it."]}),e.map(o=>h.jsxs("div",{className:"sb-link",children:[h.jsx("span",{className:"sb-url mono",title:o.url,children:o.url}),h.jsx("span",{className:"sb-meta",children:CC(o,!1)}),h.jsxs("span",{className:"sb-actions",children:[h.jsx(Tt,{variant:"subtle",onClick:()=>Ha(o.url).then(s=>Ke(s?"Copied.":"Select and copy the link.")),children:"Copy link"}),h.jsx(Tt,{variant:"subtle",onClick:()=>window.open(o.url,"_blank"),children:"Open"}),n&&h.jsx("button",{className:"ai-del","aria-label":`Revoke the share of ${o.path}`,onClick:()=>RC(o,r),children:"Revoke"})]})]},o.token))]})}var sw=1,DI=.9,zI=.8,kI=.17,rm=.1,im=.999,LI=.9999,$I=.99,II=/[\\\/_+.#"@\[\(\{&]/,FI=/[\\\/_+.#"@\[\(\{&]/g,VI=/[\s-]/,LC=/[\s-]/g;function Km(e,n,r,o,s,l,u){if(l===n.length)return s===e.length?sw:$I;var d=`${s},${l}`;if(u[d]!==void 0)return u[d];for(var p=o.charAt(l),m=r.indexOf(p,s),y=0,v,b,x,C;m>=0;)v=Km(e,n,r,o,m+1,l+1,u),v>y&&(m===s?v*=sw:II.test(e.charAt(m-1))?(v*=zI,x=e.slice(s,m-1).match(FI),x&&s>0&&(v*=Math.pow(im,x.length))):VI.test(e.charAt(m-1))?(v*=DI,C=e.slice(s,m-1).match(LC),C&&s>0&&(v*=Math.pow(im,C.length))):(v*=kI,s>0&&(v*=Math.pow(im,m-s))),e.charAt(m)!==n.charAt(l)&&(v*=LI)),(vv&&(v=b*rm)),v>y&&(y=v),m=r.indexOf(p,m+1);return u[d]=y,y}function lw(e){return e.toLowerCase().replace(LC," ")}function PI(e,n,r){return e=r&&r.length>0?`${e+" "+r.join(" ")}`:e,Km(e,n,lw(e),lw(n),0,0,{})}var qs='[cmdk-group=""]',om='[cmdk-group-items=""]',UI='[cmdk-group-heading=""]',$C='[cmdk-item=""]',cw=`${$C}:not([aria-disabled="true"])`,Ym="cmdk-item-select",Oa="data-value",HI=(e,n,r)=>PI(e,n,r),IC=w.createContext(void 0),_l=()=>w.useContext(IC),FC=w.createContext(void 0),fg=()=>w.useContext(FC),VC=w.createContext(void 0),PC=w.forwardRef((e,n)=>{let r=Aa(()=>{var M,U;return{search:"",value:(U=(M=e.value)!=null?M:e.defaultValue)!=null?U:"",selectedItemId:void 0,filtered:{count:0,items:new Map,groups:new Set}}}),o=Aa(()=>new Set),s=Aa(()=>new Map),l=Aa(()=>new Map),u=Aa(()=>new Set),d=UC(e),{label:p,children:m,value:y,onValueChange:v,filter:b,shouldFilter:x,loop:C,disablePointerSelection:_=!1,vimBindings:E=!0,...T}=e,j=fn(),O=fn(),k=fn(),I=w.useRef(null),B=eF();Oo(()=>{if(y!==void 0){let M=y.trim();r.current.value=M,H.emit()}},[y]),Oo(()=>{B(6,le)},[]);let H=w.useMemo(()=>({subscribe:M=>(u.current.add(M),()=>u.current.delete(M)),snapshot:()=>r.current,setState:(M,U,X)=>{var K,se,ee,ge;if(!Object.is(r.current[M],U)){if(r.current[M]=U,M==="search")Q(),ve(),B(1,de);else if(M==="value"){if(document.activeElement.hasAttribute("cmdk-input")||document.activeElement.hasAttribute("cmdk-root")){let ye=document.getElementById(k);ye?ye.focus():(K=document.getElementById(j))==null||K.focus()}if(B(7,()=>{var ye;r.current.selectedItemId=(ye=he())==null?void 0:ye.id,H.emit()}),X||B(5,le),((se=d.current)==null?void 0:se.value)!==void 0){let ye=U??"";(ge=(ee=d.current).onValueChange)==null||ge.call(ee,ye);return}}H.emit()}},emit:()=>{u.current.forEach(M=>M())}}),[]),V=w.useMemo(()=>({value:(M,U,X)=>{var K;U!==((K=l.current.get(M))==null?void 0:K.value)&&(l.current.set(M,{value:U,keywords:X}),r.current.filtered.items.set(M,pe(U,X)),B(2,()=>{ve(),H.emit()}))},item:(M,U)=>(o.current.add(M),U&&(s.current.has(U)?s.current.get(U).add(M):s.current.set(U,new Set([M]))),B(3,()=>{Q(),ve(),r.current.value||de(),H.emit()}),()=>{l.current.delete(M),o.current.delete(M),r.current.filtered.items.delete(M);let X=he();B(4,()=>{Q(),X?.getAttribute("id")===M&&de(),H.emit()})}),group:M=>(s.current.has(M)||s.current.set(M,new Set),()=>{l.current.delete(M),s.current.delete(M)}),filter:()=>d.current.shouldFilter,label:p||e["aria-label"],getDisablePointerSelection:()=>d.current.disablePointerSelection,listId:j,inputId:k,labelId:O,listInnerRef:I}),[]);function pe(M,U){var X,K;let se=(K=(X=d.current)==null?void 0:X.filter)!=null?K:HI;return M?se(M,r.current.search,U):0}function ve(){if(!r.current.search||d.current.shouldFilter===!1)return;let M=r.current.filtered.items,U=[];r.current.filtered.groups.forEach(K=>{let se=s.current.get(K),ee=0;se.forEach(ge=>{let ye=M.get(ge);ee=Math.max(ye,ee)}),U.push([K,ee])});let X=I.current;xe().sort((K,se)=>{var ee,ge;let ye=K.getAttribute("id"),Ne=se.getAttribute("id");return((ee=M.get(Ne))!=null?ee:0)-((ge=M.get(ye))!=null?ge:0)}).forEach(K=>{let se=K.closest(om);se?se.appendChild(K.parentElement===se?K:K.closest(`${om} > *`)):X.appendChild(K.parentElement===X?K:K.closest(`${om} > *`))}),U.sort((K,se)=>se[1]-K[1]).forEach(K=>{var se;let ee=(se=I.current)==null?void 0:se.querySelector(`${qs}[${Oa}="${encodeURIComponent(K[0])}"]`);ee?.parentElement.appendChild(ee)})}function de(){let M=xe().find(X=>X.getAttribute("aria-disabled")!=="true"),U=M?.getAttribute(Oa);H.setState("value",U||void 0)}function Q(){var M,U,X,K;if(!r.current.search||d.current.shouldFilter===!1){r.current.filtered.count=o.current.size;return}r.current.filtered.groups=new Set;let se=0;for(let ee of o.current){let ge=(U=(M=l.current.get(ee))==null?void 0:M.value)!=null?U:"",ye=(K=(X=l.current.get(ee))==null?void 0:X.keywords)!=null?K:[],Ne=pe(ge,ye);r.current.filtered.items.set(ee,Ne),Ne>0&&se++}for(let[ee,ge]of s.current)for(let ye of ge)if(r.current.filtered.items.get(ye)>0){r.current.filtered.groups.add(ee);break}r.current.filtered.count=se}function le(){var M,U,X;let K=he();K&&(((M=K.parentElement)==null?void 0:M.firstChild)===K&&((X=(U=K.closest(qs))==null?void 0:U.querySelector(UI))==null||X.scrollIntoView({block:"nearest"})),K.scrollIntoView({block:"nearest"}))}function he(){var M;return(M=I.current)==null?void 0:M.querySelector(`${$C}[aria-selected="true"]`)}function xe(){var M;return Array.from(((M=I.current)==null?void 0:M.querySelectorAll(cw))||[])}function N(M){let U=xe()[M];U&&H.setState("value",U.getAttribute(Oa))}function Z(M){var U;let X=he(),K=xe(),se=K.findIndex(ge=>ge===X),ee=K[se+M];(U=d.current)!=null&&U.loop&&(ee=se+M<0?K[K.length-1]:se+M===K.length?K[0]:K[se+M]),ee&&H.setState("value",ee.getAttribute(Oa))}function ie(M){let U=he(),X=U?.closest(qs),K;for(;X&&!K;)X=M>0?JI(X,qs):WI(X,qs),K=X?.querySelector(cw);K?H.setState("value",K.getAttribute(Oa)):Z(M)}let te=()=>N(xe().length-1),ne=M=>{M.preventDefault(),M.metaKey?te():M.altKey?ie(1):Z(1)},z=M=>{M.preventDefault(),M.metaKey?N(0):M.altKey?ie(-1):Z(-1)};return w.createElement($e.div,{ref:n,tabIndex:-1,...T,"cmdk-root":"",onKeyDown:M=>{var U;(U=T.onKeyDown)==null||U.call(T,M);let X=M.nativeEvent.isComposing||M.keyCode===229;if(!(M.defaultPrevented||X))switch(M.key){case"n":case"j":{E&&M.ctrlKey&&ne(M);break}case"ArrowDown":{ne(M);break}case"p":case"k":{E&&M.ctrlKey&&z(M);break}case"ArrowUp":{z(M);break}case"Home":{M.preventDefault(),N(0);break}case"End":{M.preventDefault(),te();break}case"Enter":{M.preventDefault();let K=he();if(K){let se=new Event(Ym);K.dispatchEvent(se)}}}}},w.createElement("label",{"cmdk-label":"",htmlFor:V.inputId,id:V.labelId,style:nF},p),dd(e,M=>w.createElement(FC.Provider,{value:H},w.createElement(IC.Provider,{value:V},M))))}),BI=w.forwardRef((e,n)=>{var r,o;let s=fn(),l=w.useRef(null),u=w.useContext(VC),d=_l(),p=UC(e),m=(o=(r=p.current)==null?void 0:r.forceMount)!=null?o:u?.forceMount;Oo(()=>{if(!m)return d.item(s,u?.id)},[m]);let y=HC(s,l,[e.value,e.children,l],e.keywords),v=fg(),b=Hi(B=>B.value&&B.value===y.current),x=Hi(B=>m||d.filter()===!1?!0:B.search?B.filtered.items.get(s)>0:!0);w.useEffect(()=>{let B=l.current;if(!(!B||e.disabled))return B.addEventListener(Ym,C),()=>B.removeEventListener(Ym,C)},[x,e.onSelect,e.disabled]);function C(){var B,H;_(),(H=(B=p.current).onSelect)==null||H.call(B,y.current)}function _(){v.setState("value",y.current,!0)}if(!x)return null;let{disabled:E,value:T,onSelect:j,forceMount:O,keywords:k,...I}=e;return w.createElement($e.div,{ref:Fa(l,n),...I,id:s,"cmdk-item":"",role:"option","aria-disabled":!!E,"aria-selected":!!b,"data-disabled":!!E,"data-selected":!!b,onPointerMove:E||d.getDisablePointerSelection()?void 0:_,onClick:E?void 0:C},e.children)}),qI=w.forwardRef((e,n)=>{let{heading:r,children:o,forceMount:s,...l}=e,u=fn(),d=w.useRef(null),p=w.useRef(null),m=fn(),y=_l(),v=Hi(x=>s||y.filter()===!1?!0:x.search?x.filtered.groups.has(u):!0);Oo(()=>y.group(u),[]),HC(u,d,[e.value,e.heading,p]);let b=w.useMemo(()=>({id:u,forceMount:s}),[s]);return w.createElement($e.div,{ref:Fa(d,n),...l,"cmdk-group":"",role:"presentation",hidden:v?void 0:!0},r&&w.createElement("div",{ref:p,"cmdk-group-heading":"","aria-hidden":!0,id:m},r),dd(e,x=>w.createElement("div",{"cmdk-group-items":"",role:"group","aria-labelledby":r?m:void 0},w.createElement(VC.Provider,{value:b},x))))}),GI=w.forwardRef((e,n)=>{let{alwaysRender:r,...o}=e,s=w.useRef(null),l=Hi(u=>!u.search);return!r&&!l?null:w.createElement($e.div,{ref:Fa(s,n),...o,"cmdk-separator":"",role:"separator"})}),ZI=w.forwardRef((e,n)=>{let{onValueChange:r,...o}=e,s=e.value!=null,l=fg(),u=Hi(m=>m.search),d=Hi(m=>m.selectedItemId),p=_l();return w.useEffect(()=>{e.value!=null&&l.setState("search",e.value)},[e.value]),w.createElement($e.input,{ref:n,...o,"cmdk-input":"",autoComplete:"off",autoCorrect:"off",spellCheck:!1,"aria-autocomplete":"list",role:"combobox","aria-expanded":!0,"aria-controls":p.listId,"aria-labelledby":p.labelId,"aria-activedescendant":d,id:p.inputId,type:"text",value:s?e.value:u,onChange:m=>{s||l.setState("search",m.target.value),r?.(m.target.value)}})}),KI=w.forwardRef((e,n)=>{let{children:r,label:o="Suggestions",...s}=e,l=w.useRef(null),u=w.useRef(null),d=Hi(m=>m.selectedItemId),p=_l();return w.useEffect(()=>{if(u.current&&l.current){let m=u.current,y=l.current,v,b=new ResizeObserver(()=>{v=requestAnimationFrame(()=>{let x=m.offsetHeight;y.style.setProperty("--cmdk-list-height",x.toFixed(1)+"px")})});return b.observe(m),()=>{cancelAnimationFrame(v),b.unobserve(m)}}},[]),w.createElement($e.div,{ref:Fa(l,n),...s,"cmdk-list":"",role:"listbox",tabIndex:-1,"aria-activedescendant":d,"aria-label":o,id:p.listId},dd(e,m=>w.createElement("div",{ref:Fa(u,p.listInnerRef),"cmdk-list-sizer":""},m)))}),YI=w.forwardRef((e,n)=>{let{open:r,onOpenChange:o,overlayClassName:s,contentClassName:l,container:u,...d}=e;return w.createElement(sp,{open:r,onOpenChange:o},w.createElement(cp,{container:u},w.createElement(up,{"cmdk-overlay":"",className:s}),w.createElement(dp,{"aria-label":e.label,"cmdk-dialog":"",className:l},w.createElement(PC,{ref:n,...d}))))}),QI=w.forwardRef((e,n)=>Hi(r=>r.filtered.count===0)?w.createElement($e.div,{ref:n,...e,"cmdk-empty":"",role:"presentation"}):null),XI=w.forwardRef((e,n)=>{let{progress:r,children:o,label:s="Loading...",...l}=e;return w.createElement($e.div,{ref:n,...l,"cmdk-loading":"",role:"progressbar","aria-valuenow":r,"aria-valuemin":0,"aria-valuemax":100,"aria-label":s},dd(e,u=>w.createElement("div",{"aria-hidden":!0},u)))}),ud=Object.assign(PC,{List:KI,Item:BI,Input:ZI,Group:qI,Separator:GI,Dialog:YI,Empty:QI,Loading:XI});function JI(e,n){let r=e.nextElementSibling;for(;r;){if(r.matches(n))return r;r=r.nextElementSibling}}function WI(e,n){let r=e.previousElementSibling;for(;r;){if(r.matches(n))return r;r=r.previousElementSibling}}function UC(e){let n=w.useRef(e);return Oo(()=>{n.current=e}),n}var Oo=typeof window>"u"?w.useEffect:w.useLayoutEffect;function Aa(e){let n=w.useRef();return n.current===void 0&&(n.current=e()),n}function Hi(e){let n=fg(),r=()=>e(n.snapshot());return w.useSyncExternalStore(n.subscribe,r,r)}function HC(e,n,r,o=[]){let s=w.useRef(),l=_l();return Oo(()=>{var u;let d=(()=>{var m;for(let y of r){if(typeof y=="string")return y.trim();if(typeof y=="object"&&"current"in y)return y.current?(m=y.current.textContent)==null?void 0:m.trim():s.current}})(),p=o.map(m=>m.trim());l.value(e,d,p),(u=n.current)==null||u.setAttribute(Oa,d),s.current=d}),s}var eF=()=>{let[e,n]=w.useState(),r=Aa(()=>new Map);return Oo(()=>{r.current.forEach(o=>o()),r.current=new Map},[e]),(o,s)=>{r.current.set(o,s),n({})}};function tF(e){let n=e.type;return typeof n=="function"?n(e.props):"render"in n?n.render(e.props):e}function dd({asChild:e,children:n},r){return e&&w.isValidElement(n)?w.cloneElement(tF(n),{ref:n.ref},r(n.props.children)):r(n)}var nF={position:"absolute",width:"1px",height:"1px",padding:"0",margin:"-1px",overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",borderWidth:"0"};function rF({className:e,...n}){return h.jsx(ud,{"data-slot":"command",className:Xe("flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",e),...n})}function iF({className:e,...n}){return h.jsxs("div",{"data-slot":"command-input-wrapper",className:"flex h-9 items-center gap-2 border-b px-3",children:[h.jsx(f_,{className:"size-4 shrink-0 opacity-50"}),h.jsx(ud.Input,{"data-slot":"command-input",className:Xe("flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",e),...n})]})}function oF({className:e,...n}){return h.jsx(ud.List,{"data-slot":"command-list",className:Xe("max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto",e),...n})}function aF({className:e,...n}){return h.jsx(ud.Item,{"data-slot":"command-item",className:Xe("relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground",e),...n})}function uw(e,n){if(!e)return{score:0,hits:[]};const r=e.toLowerCase(),o=n.toLowerCase();let s=0,l=0,u=0;const d=[];for(let p=0;p3&&o.endsWith("ies")?s=o.slice(0,-3)+"y":o.length>3&&o.endsWith("es")?s=o.slice(0,-2):o.length>2&&o.endsWith("s")&&(s=o.slice(0,-1)),s?uw(s,n):null}function lF({text:e,hits:n}){const r=[];let o=0;return n.forEach((s,l)=>{s>o&&r.push(e.slice(o,s)),r.push(h.jsx("b",{children:e[s]},l)),o=s+1}),r.push(e.slice(o)),h.jsx("span",{className:"plabel",children:r})}function cF({open:e,onClose:n,candidates:r}){const[o,s]=w.useState(""),l=w.useMemo(()=>{if(!e)return[];const d=[];for(const p of r()){const m=sF(o,p.label);m&&d.push({...p,score:m.score,hits:m.hits})}return d.sort((p,m)=>m.score-p.score),d.slice(0,40)},[e,o,r]);w.useEffect(()=>{e&&s("")},[e]);const u=d=>{n(),d.run()};return h.jsx(Vp,{open:e,onOpenChange:d=>!d&&n(),children:h.jsxs(Pp,{id:"palette",className:"palette",showCloseButton:!1,"aria-describedby":void 0,children:[h.jsx(Yu,{className:"sr-only",children:"Search and quick actions"}),h.jsxs(rF,{shouldFilter:!1,loop:!0,children:[h.jsxs("div",{id:"palette-inputwrap",children:[h.jsx(ht,{name:"search"}),h.jsx(iF,{id:"palette-input",placeholder:"Search file names, projects, actions…",autoComplete:"off",spellCheck:!1,value:o,onValueChange:s})]}),h.jsx(oF,{id:"palette-results",children:l.length===0?h.jsx("div",{className:"pempty",children:"No matches — search covers file names, projects, and actions"}):l.map(d=>h.jsxs(aF,{value:d.kind+":"+d.label,onSelect:()=>u(d),children:[h.jsx("span",{className:"picon",children:h.jsx(ht,{name:d.icon})}),h.jsx(lF,{text:d.label,hits:d.hits}),h.jsx("span",{className:"pkind",children:d.kind})]},d.kind+":"+d.label))}),h.jsx("footer",{id:"palette-hint",children:"↑↓ navigate · ⏎ select · esc close"})]})]})})}const Qs=3,Ma=30;function uF(e,n){return Ht({queryKey:["heatDevices",e],queryFn:()=>sn(e+"heat?by=device&days=30"),enabled:n,retry:!1,staleTime:6e4}).data?.devices??null}function dw(e){const[n,r]=w.useState("all"),{flatFiles:o,heatMap:s,devices:l,scope:u}=e,d=b=>!u||b===u||b.startsWith(u+"/"),p=u?o.filter(b=>d(b.path)):o,m=l&&u?l.map(b=>{const x={};for(const[C,_]of Object.entries(b.folders||{}))d(C)&&(x[C]=_);return{...b,folders:x}}).filter(b=>Object.keys(b.folders).length>0):l,y=Date.now(),v=p.map(b=>{const x=s&&s[b.path]||{},C=b.time?Math.max(0,(y-new Date(b.time).getTime())/864e5):0,_=n==="all"?Ba(x):x[n]||0;return{path:b.path,reads:_,agent:x.agent||0,human:x.human||0,share:x.share||0,total:Ba(x),days:C,danger:_>=Qs&&C>=Ma}});return h.jsxs("div",{className:"insights",children:[h.jsxs("h1",{className:"in-title",children:["Knowledge insights",u?h.jsxs("span",{className:"in-scope",children:[" · ",u]}):null]}),h.jsx("p",{className:"dl-sub",children:u?`Reads over the last 30 days × freshness, for ${u} and everything in it.`:"Reads over the last 30 days × how long since each file changed. Hot but stale knowledge — read a lot, maintained by nobody — is the danger zone."}),h.jsx("div",{className:"in-lens",children:["all","human","agent"].map(b=>h.jsx("button",{className:"in-lens-btn"+(b===n?" active":""),onClick:()=>r(b),children:b==="all"?"All reads":b==="human"?"Human reads":"Agent reads"},b))}),h.jsx("h3",{className:"dl-h3",children:"Map — cell size = reads, color = freshness (scale below)"}),h.jsx(dF,{pts:v,onOpenFile:e.onOpenFile,onOpenFolder:e.onOpenFolder,isFolder:e.isFolder}),h.jsx("h3",{className:"dl-h3",children:"Reads × freshness"}),h.jsx(hF,{pts:v,onOpenFile:e.onOpenFile}),h.jsx("h3",{className:"dl-h3",children:"Hot path — top files by reads"}),h.jsx(mF,{pts:v,lens:n,onOpenFile:e.onOpenFile}),m&&m.length>0&&h.jsxs(h.Fragment,{children:[h.jsx("h3",{className:"dl-h3",children:"Agent coverage — which agents read which areas"}),h.jsx(pF,{devices:m})]})]})}function BC(e){const n=[[76,195,138],[232,196,84],[224,93,93]],r=Math.min(1,Math.max(0,e/300))*(n.length-1),o=Math.min(n.length-2,Math.floor(r)),s=r-o,l=n[o].map((u,d)=>Math.round(u+(n[o+1][d]-u)*s));return`rgb(${l[0]},${l[1]},${l[2]})`}function fw(e,n,r,o,s){const l=e.reduce((m,y)=>m+y.value,0);if(!l||o<=0||s<=0)return[];const u=e.slice().sort((m,y)=>y.value-m.value).map(m=>({it:m,a:m.value/l*o*s})),d=(m,y)=>{const b=m.reduce((C,_)=>C+_.a,0)/y;let x=0;for(const C of m){const _=C.a/b;x=Math.max(x,_/b,b/_)}return x},p=[];for(;u.length;){const m=o>=s,y=m?s:o,v=[u.shift()];for(;u.length&&d(v.concat(u[0]),y)<=d(v,y);)v.push(u.shift());const b=v.reduce((C,_)=>C+_.a,0)/y;let x=0;for(const C of v){const _=C.a/b;m?p.push({item:C.it,x:n,y:r+x,w:b,h:_}):p.push({item:C.it,x:n+x,y:r,w:_,h:b}),x+=_}m?(n+=b,o-=b):(r+=b,s-=b)}return p}const am=15;function hw(e,n,r){const o=Math.floor((r-8)/6),s=`${e} · ${n}`;return s.length<=o?{label:s,fit:o}:{label:e.length>o?e.slice(0,Math.max(1,o-1))+"…":e,fit:o}}const mw=(e,n)=>`${e} ${n}${e===1?"":"s"}`;function dF({pts:e,onOpenFile:n,onOpenFolder:r,isFolder:o}){const u=new Map;for(const p of e){const m=p.path.includes("/")?p.path.split("/")[0]:"/";let y=u.get(m);y||u.set(m,y={name:m,files:[],value:0,reads:0}),y.files.push(p),y.value+=p.reads+1,y.reads+=p.reads}const d=[];for(const p of fw([...u.values()],0,0,720,480)){const m=p.item,y=m.name==="/"?"":m.name,v=m.name==="/"?"(root)":m.name;if(d.push(h.jsx("rect",{x:p.x+1,y:p.y+1,width:Math.max(0,p.w-2),height:Math.max(0,p.h-2),rx:3,className:"in-tm-group","data-dir":y,children:h.jsx("title",{children:`${m.name==="/"?"(root)":m.name+"/"} — ${mw(m.reads,"read")}/30d · ${mw(m.files.length,"file")}`})},"g"+m.name)),p.w>46&&p.h>am+10){const{label:x}=hw(v,m.reads,p.w);d.push(h.jsx("text",{x:p.x+5,y:p.y+12,className:"in-tm-glabel","data-dir":y,children:x},"gl"+m.name))}const b=fw(m.files.map(x=>({...x,name:x.path.split("/").pop(),value:x.reads+1})),p.x+2,p.y+am,Math.max(0,p.w-4),Math.max(0,p.h-am-2));for(const x of b)if(d.push(h.jsx("rect",{x:x.x+.6,y:x.y+.6,width:Math.max(.4,x.w-1.2),height:Math.max(.4,x.h-1.2),rx:1.5,fill:BC(x.item.days),className:"in-tm-cell","data-path":x.item.path,children:h.jsx("title",{children:`${x.item.path} — ${x.item.reads} read${x.item.reads===1?"":"s"}/30d · changed ${Math.round(x.item.days)}d ago`})},x.item.path)),x.w>54&&x.h>16){const{label:C,fit:_}=hw((x.item.danger?"⚠ ":"")+x.item.name,x.item.reads,x.w);_>=5&&d.push(h.jsx("text",{x:x.x+4.5,y:x.y+12.5,className:"in-tm-label","data-path":x.item.path,children:C},"l"+x.item.path))}}return h.jsxs(h.Fragment,{children:[h.jsx("svg",{viewBox:"0 0 720 480",className:"in-chart in-treemap",onClick:p=>{const m=p.target.closest("[data-path], [data-dir]");if(!m)return;const y=m.getAttribute("data-path");if(y)return n(y);const v=m.getAttribute("data-dir");v&&o(v)&&r(v)},children:d}),h.jsx(fF,{pts:e})]})}function fF({pts:e}){const n=L8(e.map(o=>o.days));if(!n)return null;const r=I8(n.min,n.max);return h.jsxs("p",{className:"in-legend in-tm-legend",children:["freshness 0d",h.jsx("span",{className:"in-sw in-sw-age",style:{background:`linear-gradient(to right, ${[0,60,150,300].map(BC).join(", ")})`}}),"300d+",h.jsx("span",{className:"in-tm-range",children:$8(n.min,n.max)?`all files here: ${r} old — colour carries no signal in this range`:`observed: ${r} old`})]})}function hF({pts:e,onOpenFile:n}){const s={l:44,r:16,t:20,b:34},l=Math.max(Ma*2,...e.map(v=>v.days)),u=Math.max(Qs*2,...e.map(v=>v.reads)),d=v=>Math.log10(v+1)/Math.log10(l+1),p=v=>Math.log10(v+1)/Math.log10(u+1),m=v=>s.l+d(v)*(720-s.l-s.r),y=v=>360-s.b-p(v)*(360-s.t-s.b);return h.jsxs("svg",{viewBox:"0 0 720 360",className:"in-chart",children:[h.jsx("rect",{x:m(Ma),y:s.t,width:720-s.r-m(Ma),height:y(Qs)-s.t,className:"in-danger-zone"}),h.jsx("line",{x1:m(Ma),y1:s.t,x2:m(Ma),y2:360-s.b,className:"in-threshold"}),h.jsx("line",{x1:s.l,y1:y(Qs),x2:720-s.r,y2:y(Qs),className:"in-threshold"}),h.jsx("line",{x1:s.l,y1:360-s.b,x2:720-s.r,y2:360-s.b,className:"in-axis"}),h.jsx("line",{x1:s.l,y1:s.t,x2:s.l,y2:360-s.b,className:"in-axis"}),h.jsx("text",{x:(s.l+720-s.r)/2,y:352,className:"in-label",children:"days since last change →"}),h.jsx("text",{x:12,y:(s.t+360-s.b)/2,className:"in-label",transform:`rotate(-90 12 ${(s.t+360-s.b)/2})`,children:"reads / 30d →"}),h.jsx("text",{x:720-s.r-6,y:s.t+14,className:"in-quad in-quad-danger",textAnchor:"end",children:"hot + stale"}),h.jsx("text",{x:s.l+6,y:s.t+14,className:"in-quad",children:"hot + fresh"}),h.jsx("text",{x:720-s.r-6,y:360-s.b-8,className:"in-quad",textAnchor:"end",children:"cold + stale"}),h.jsx("text",{x:s.l+6,y:360-s.b-8,className:"in-quad",children:"cold + fresh"}),h.jsx("text",{x:720-s.r-6,y:s.t+28,className:"in-label",textAnchor:"end",children:"dot size = agent share of reads"}),e.map(v=>{const b=v.total?(v.agent||0)/v.total:0;return h.jsx("circle",{cx:Number(m(v.days).toFixed(1)),cy:Number(y(v.reads).toFixed(1)),r:Number((3+4*b).toFixed(1)),className:"in-pt"+(v.danger?" danger":v.reads?"":" cold"),onClick:()=>n(v.path),children:h.jsx("title",{children:`${v.path} — ${v.reads} read${v.reads===1?"":"s"} / 30d · changed ${Math.round(v.days)}d ago`})},v.path)})]})}function mF({pts:e,lens:n,onOpenFile:r}){const o=e.filter(u=>u.reads>0).sort((u,d)=>d.reads-u.reads||d.days-u.days).slice(0,20);if(!o.length)return h.jsx("div",{className:"dl-empty",children:"No reads in the window yet."});const s=o[0].reads,l=o.some(u=>u.share>0);return h.jsxs(h.Fragment,{children:[h.jsx("div",{className:"in-hotpath",children:o.map(u=>{const d=n==="agent"?{agent:1,human:0,share:0}:n==="human"?{agent:0,human:1,share:0}:z8(u),p=u.reads/s*100;return h.jsxs("div",{className:"in-hp-row",tabIndex:0,role:"button",title:u.danger?`${u.reads} read${u.reads===1?"":"s"}/30d · unchanged ${Math.round(u.days)}d — review this file`:u.path,onClick:()=>r(u.path),onKeyDown:m=>{(m.key==="Enter"||m.key===" ")&&(m.preventDefault(),r(u.path))},children:[h.jsx("span",{className:"in-hp-name"+(u.danger?" danger":""),children:u.path+(u.danger?" ⚠":"")}),h.jsxs("span",{className:"in-hp-bar",children:[h.jsx("span",{className:"in-hp-agent",style:{width:(p*d.agent).toFixed(1)+"%"}}),h.jsx("span",{className:"in-hp-human",style:{width:(p*d.human).toFixed(1)+"%"}}),h.jsx("span",{className:"in-hp-share",style:{width:(p*d.share).toFixed(1)+"%"}})]}),h.jsx("span",{className:"in-hp-count",children:u.reads})]},u.path)})}),h.jsxs("p",{className:"in-legend",children:[h.jsx("span",{className:"in-sw agent"})," agent reads ",h.jsx("span",{className:"in-sw human"})," human reads",l&&h.jsxs(h.Fragment,{children:[" ",h.jsx("span",{className:"in-sw share"})," shared reads"]})]})]})}function pF({devices:e}){const n=new Map;for(const b of e)for(const[x,C]of Object.entries(b.folders||{}))n.set(x,(n.get(x)||0)+C);const r=[...n.entries()].sort((b,x)=>x[1]-b[1]).slice(0,12).map(b=>b[0]),o=e.slice(0,12),s=140,l=6,u=Math.min(76,Math.max(34,(720-s-8)/r.length)),d=26,p=720,m=l+o.length*d+58,y=Math.max(1,...o.flatMap(b=>r.map(x=>(b.folders||{})[x]||0))),v=b=>{const x=[23,25,31],C=[245,166,35],_=x.map((E,T)=>Math.round(E+(C[T]-E)*b));return`rgb(${_[0]},${_[1]},${_[2]})`};return h.jsxs("svg",{viewBox:`0 0 ${p} ${m}`,className:"in-chart in-matrix",children:[o.map((b,x)=>{let C=b.name||b.id||"";return C.length>20&&(C=C.slice(0,19)+"…"),h.jsxs("g",{children:[h.jsx("text",{x:s-8,y:l+x*d+17,textAnchor:"end",className:"in-label",children:C}),r.map((_,E)=>{const T=(b.folders||{})[_]||0;return h.jsx("rect",{x:s+E*u,y:l+x*d,width:u-4,height:d-4,rx:3,fill:v(Math.sqrt(T/y)),children:h.jsx("title",{children:`${b.name||b.id} × ${_||"(root)"}: ${T} read${T===1?"":"s"}/30d`})},_)})]},b.id||x)}),r.map((b,x)=>{const C=s+x*u+(u-4)/2,_=l+o.length*d+14;return h.jsx("text",{x:C,y:_,className:"in-label",textAnchor:"end",transform:`rotate(-28 ${C} ${_})`,children:b||"(root)"},b)})]})}function qC(e){return new Set(e.entries.map(n=>n.path)).size}function gF(e){const n=l=>l.note+"\0"+(l.device?.id??""),r=new Map;e.forEach((l,u)=>{if(!l.note)return;const d=r.get(n(l));if(d){d.entries.push(l),d.idx.push(u);return}r.set(n(l),{note:l.note,entries:[l],idx:[u]})});const o=[],s=new Set;return e.forEach((l,u)=>{const d=l.note?r.get(n(l)):void 0;if(!d||qC(d)<2){o.push({i:u});return}s.has(d)||(s.add(d),o.push({run:d,i:u}))}),o}function vF(e){const{apiBase:n,target:r,isFolder:o,onMeta:s,onRendered:l,restore:u,remove:d}=e,p=r?o(r)?{prefix:r+"/"}:{path:r}:{prefix:""},m="path"in p&&p.path!==void 0?"path="+encodeURIComponent(p.path):"prefix="+encodeURIComponent(p.prefix??""),{data:y,error:v}=Ht({queryKey:["history",n,m,200],queryFn:()=>sn(n+"history?"+m+"&n=200"),staleTime:15e3});if(w.useEffect(()=>{v&&s("History unavailable: "+v.message)},[v,s]),w.useEffect(()=>{y&&l?.()},[y,l]),!y)return null;const b=y.entries||[],x=!!r&&!o(r),C=E=>{for(let T=E+1;Tb[E].kind==="delete"?C(E):b[E].blob;return h.jsxs("div",{className:"history",children:[b.length===0&&h.jsx("div",{className:"empty",children:"No history yet."}),gF(b).map((E,T)=>E.run?h.jsx(yF,{run:E.run,onOpen:e.onOpen,apiBase:n,perFile:x,prevBlob:C,restoreSha:_,restore:u,remove:d},"g"+T):h.jsx(dg,{entry:b[E.i],apiBase:n,onOpen:e.onOpen,diff:x?{apiBase:n,prev:C(E.i)}:void 0,restore:u,restoreSha:_(E.i)},"r"+E.i))]})}function yF({run:e,onOpen:n,apiBase:r,perFile:o,prevBlob:s,restoreSha:l,restore:u,remove:d}){const[p,m]=w.useState(!0),y=e.entries[0],v=ld(y),b=[y.device.name||y.device.id,y.device.os].filter(Boolean).join(" · "),x=e.entries.map(E=>new Date(E.time).getTime()),C=bF(Math.min(...x),Math.max(...x)),_=qC(e);return h.jsxs("div",{className:"hrun"+(p?" open":""),children:[h.jsxs("div",{className:"hrun-head",children:[h.jsx("button",{type:"button",className:"hrun-toggle","aria-expanded":p,title:p?"Collapse this run":"Expand this run",onClick:()=>m(!p),children:h.jsx(ht,{name:p?"chevd":"chev"})}),h.jsx("span",{className:"hrun-note",children:h.jsx(kC,{text:e.note})}),h.jsxs("span",{className:"hrun-meta",children:[_," file",_===1?"":"s"," · ",v,b?" · "+b:""]}),h.jsx("span",{className:"hrun-time",children:C})]}),p&&h.jsx("div",{className:"hrun-body",children:e.entries.map((E,T)=>h.jsx(dg,{entry:E,apiBase:r,onOpen:n,diff:o?{apiBase:r,prev:s(e.idx[T])}:void 0,restore:u,remove:d,restoreSha:l(e.idx[T]),inRun:!0},T))})]})}function bF(e,n){const r=new Date(e),o=new Date(n),s=u=>u.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});if(r.toDateString()!==o.toDateString())return r.toLocaleString()+" – "+o.toLocaleString();const l=o.toLocaleDateString();return e===n?l+" "+s(o):l+" "+s(r)+" – "+s(o)}function xF(e,n){return e?n(e)?e+"/ (folder)":e:"all changes"}function wF(e){const{apiBase:n,path:r,version:o}=e,s="path="+encodeURIComponent(r),{data:l}=Ht({queryKey:["history",n,s,200],queryFn:()=>sn(n+"history?"+s+"&n=200"),staleTime:15e3}),u=l?.entries?.find(y=>y.blob===o),d=u?ld(u):"",p=u?.time?new Date(u.time).toLocaleString():"",m=n+"blob?sha="+o+"&name="+encodeURIComponent(r.split("/").pop()||r)+"&download=1";return h.jsxs("div",{className:"vbanner",role:"status",children:[h.jsx("span",{className:"vb-icon",children:h.jsx(ht,{name:"clock"})}),h.jsxs("div",{className:"vb-text",children:[h.jsx("b",{children:[p&&"Version from "+p,d&&"by "+d].filter(Boolean).join(" ")||"Earlier version"}),h.jsx("span",{children:"This is not the current file."})]}),h.jsxs("div",{className:"vb-actions",children:[h.jsx("button",{className:"ai-btn",onClick:e.onViewCurrent,children:"View current"}),h.jsx("a",{className:"ai-btn",download:!0,href:m,children:"Download this version"})]})]})}function GC(e){const{config:n,apiBase:r,route:o,hub:s,project:l}=e,u=qp(),d=Ao(),{tree:p,flatFiles:m,dirIndex:y,loaded:v}=F8(r,!s||!!l),b=V8(r,s&&!!l&&!!n.reads?.enabled),x=s&&!!l&&!o.path&&!o.view,C=o.view==="dashboard"||x,_=uF(r,C);w.useEffect(()=>{C&&d.invalidateQueries({queryKey:["heat",r]})},[C,r,d]);const E=o.path,T=o.view?void 0:o.version,j=E||(o.view==="dashboard"||o.view==="history")&&o.viewTarget||"",O=!!E&&y.has(E),k=!!E&&v&&!O&&m.some(D=>D.path===E),I=!!E&&v&&!O&&!k,B=O&&!o.view,[H,V]=w.useState(()=>new Set),pe=w.useRef(!0);w.useEffect(()=>{if(!p||!pe.current)return;pe.current=!1;const D=(p.children||[]).filter($=>$.dir);D.length===1&&V($=>new Set($).add(D[0].path))},[p]),w.useEffect(()=>{!j||!v||V(D=>{const $=new Set(D);for(const W of sI(j))$.add(W);return y.has(j)&&$.add(j),$})},[j,v,y]);const ve=w.useCallback(D=>{V($=>{const W=new Set($);return W.has(D)?W.delete(D):W.add(D),W})},[]),de=w.useRef(null),Q=w.useRef(new Map),le=w.useRef({key:"",want:0,attempts:0});w.useEffect(()=>{le.current={key:u,want:g3()==="POP"?Q.current.get(u)??0:0,attempts:0}},[u]);const he=w.useCallback(()=>{const D=de.current,$=le.current;!D||$.key!==u||$.attempts>=3||($.attempts++,D.scrollTo({top:$.want,behavior:"instant"}))},[u]),xe=w.useCallback(()=>{de.current&&Q.current.set(u,de.current.scrollTop)},[u]),N=w.useCallback((D,$)=>{pn(Qu(D,l?.id,$)),mr()},[l?.id]),Z=w.useCallback(D=>pn(bo("history",l?.id,D)),[l?.id]),[ie,te]=w.useState(""),[ne,z]=w.useState(null),[M,U]=w.useState(!1),[X,K]=w.useState(!1);w.useEffect(()=>RD(()=>K(!0)),[]);const se=w.useRef(null),ee=e.panel??null,ge=!ee&&s&&!!l&&k&&wo(l.perm,"write"),{data:ye}=x_(l?.id,s&&!!l),Ne=w.useCallback(()=>{d.invalidateQueries({queryKey:["shares",l?.id]})},[d,l?.id]),Ie=k?(ye||[]).filter(D=>D.path===E):[],Ve=!ee&&s&&!!l,dt=!ee&&k,Qe=!ee&&(k||s&&!!l&&O),vn=T?r+"blob?sha="+T+"&name="+encodeURIComponent(E)+"&download=1":r+"download?path="+encodeURIComponent(E),cn=w.useCallback(async()=>{try{const D=await fetch(r+"shares",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:E})});if(!D.ok)throw new Error(await D.text());const $=await D.json();Tw("share_created");const W=await Ha($.url);z({url:$.url,copied:W}),Ne()}catch(D){Ke("Share failed: "+D.message,!0)}},[r,E,Ne]),[Kt,ir]=w.useState(""),Dt=s&&!!l&&wo(l?.perm,"write"),or=w.useCallback(async(D,$)=>{ir(D+$);try{await So(r+"restore",{path:D,sha:$}),d.invalidateQueries({queryKey:["history",r]}),d.invalidateQueries({queryKey:["tree",r]}),d.invalidateQueries({queryKey:["render",r,D]}),d.invalidateQueries({queryKey:["text"]}),Ke("Restored "+D+" — it syncs to every device like any other change.")}catch(W){Ke("Restore failed: "+W.message,!0)}finally{ir("")}},[r,d]),[Nr,jt]=w.useState(""),Un=w.useCallback(async D=>{if(await xl("Remove "+D+"?","It disappears from every synced device. History keeps it — you can restore it from the DELETED row afterwards.","Remove file",!0)){jt(D);try{await So(r+"remove",{path:D}),d.invalidateQueries({queryKey:["history",r]}),d.invalidateQueries({queryKey:["tree",r]}),d.invalidateQueries({queryKey:["render",r,D]}),d.invalidateQueries({queryKey:["text"]}),Ke("Removed "+D+" — it syncs to every device like any other change.")}catch($){Ke("Remove failed: "+$.message,!0)}finally{jt("")}}},[r,d]),xt=w.useCallback(()=>{if(!E)return Z("");Z(O?E+"/":E)},[E,O,Z]);w.useEffect(()=>{const D=$=>{($.metaKey||$.ctrlKey)&&$.key.toLowerCase()==="k"&&($.preventDefault(),K(W=>!W))};return window.addEventListener("keydown",D),()=>window.removeEventListener("keydown",D)},[]);const oi=w.useCallback(()=>{const D=[],$=(W,ue,me,be)=>D.push({icon:W,label:ue,kind:me,run:be});if(s&&l&&E&&(k&&$("share","Share: "+E,"action",cn),$("hist","History: "+E,"action",xt),k&&$("download","Download: "+E,"action",()=>se.current?.click())),s&&l&&$("hist","History: whole project","action",()=>Z("")),s)for(const W of e.projects||[])(!l||W.id!==l.id)&&$("folder","Switch to project: "+W.name,"project",()=>pn("/"+W.id));n.auth?.enabled&&$("power","Sign out","action",()=>window.location.href="/auth/logout");for(const W of y.keys())$("folder",W,"folder",()=>N(W));for(const W of m)$("doc",W.path,"file",()=>N(W.path));return D},[s,l,E,k,n.auth?.enabled,y,m,e.projects,cn,xt,Z,N]);w.useEffect(()=>{if(!M)return;const D=()=>U(!1);return document.addEventListener("click",D),()=>document.removeEventListener("click",D)},[M]);const yn=w.useCallback(D=>y.has(D),[y]);let Dr="app",ar,Yt;ee?Yt=ee.body:o.view==="dashboard"?Yt=h.jsx(dw,{flatFiles:m,heatMap:b,devices:_,scope:o.viewTarget||"",onOpenFile:N,onOpenFolder:N,isFolder:yn}):o.view==="history"?Yt=h.jsx(vF,{apiBase:r,target:o.viewTarget||"",isFolder:yn,onOpen:N,onMeta:te,onRendered:he,restore:Dt?{onRestore:or,busy:Kt}:void 0,remove:Dt?{onRemove:Un,busy:Nr}:void 0}):E?v?I?Yt=h.jsxs("div",{className:"notfound",children:[h.jsx("h1",{children:"Couldn't find that"}),h.jsxs("p",{children:[h.jsx("code",{children:E})," isn't in this project right now."]}),h.jsx("p",{className:"nf-sub",children:"If it was just created, it may still be uploading or syncing from a teammate's device — this page checks again automatically every few seconds, so refresh or come back in a moment."}),h.jsx("button",{className:"pbtn",onClick:()=>d.invalidateQueries({queryKey:["tree",r]}),children:"Check again"})]}):O?Yt=h.jsx(bI,{node:y.get(E),heatMap:b,hub:s&&!!l,apiBase:r,onOpen:N,onFullHistory:Z,onRendered:he}):(Dr=bC.test(E)||xC.test(E)?"wide":"read",ar="markdown",Yt=h.jsxs(h.Fragment,{children:[T&&h.jsx(wF,{apiBase:r,path:E,version:T,onViewCurrent:()=>N(E)}),h.jsx(wI,{apiBase:r,path:E,version:T,heatMap:b,flatFiles:m,onOpenFile:N,onMeta:te,onRendered:he})]})):Yt=h.jsx("div",{className:"empty",children:"Loading…"}):x?Yt=h.jsxs(h.Fragment,{children:[h.jsx(MC,{project:l}),h.jsx("div",{className:"home-insights",children:h.jsx(dw,{flatFiles:m,heatMap:b,devices:_,onOpenFile:N,onOpenFolder:N,isFolder:yn})})]}):Yt=h.jsx("div",{className:"empty",children:"Select a file to read it."});const bn=ee?ee.crumb:E?h.jsx(lI,{path:E,onOpenFolder:N}):o.view==="dashboard"?"Dashboard — "+(o.viewTarget||l?.name||""):o.view==="history"?"History — "+xF(o.viewTarget||"",yn):x?l.name:null,A=h.jsx(ll,{crumb:bn,meta:ie,actions:h.jsxs(h.Fragment,{children:[ge&&h.jsx(Tt,{id:"share-btn",variant:"toolbar",className:"icon-only",title:"Share","aria-label":"Share",onClick:cn,children:h.jsx(ht,{name:"share"})}),Ve&&!E&&!o.view&&h.jsxs(Tt,{id:"history-btn",variant:"toolbar",onClick:xt,children:[h.jsx(ht,{name:"hist"})," ",h.jsx("span",{className:"lbl",children:"History"})]}),dt&&h.jsx("a",{id:"download",hidden:!0,download:!0,href:vn,ref:se,children:"Download"}),Qe&&h.jsx(Tt,{id:"more-btn",variant:"toolbar",className:"icon-only",title:"More actions","aria-label":"More actions",onClick:D=>{D.stopPropagation(),U(!M)},children:h.jsx(ht,{name:"dots"})}),M&&h.jsxs("div",{id:"more-menu",role:"menu",children:[Ve&&h.jsx("button",{className:"more-item",onClick:xt,children:"History"}),dt&&h.jsx("button",{className:"more-item",onClick:()=>se.current?.click(),children:"Download"}),s&&!!l&&h.jsx("button",{className:"more-item",onClick:()=>{e.onClosePanel?.(),pn(bo("dashboard",l?.id,E))},children:"Dashboard"})]})]})});return h.jsxs(h.Fragment,{children:[h.jsx(sl,{vault:e.sidebar.vault,projectsNav:e.sidebar.projectsNav,orgBar:e.sidebar.orgBar,tree:h.jsx(aI,{root:p,expanded:H,onToggle:ve,currentPath:j,listingShowing:B,onOpen:N}),topbar:A,contentRef:de,onContentScroll:xe,children:h.jsxs(yu,{width:Dr,className:ar,children:[!ee&&k&&h.jsx(NI,{shares:Ie,canRevoke:!!l&&wo(l.perm,"write"),onChanged:Ne}),Yt]})}),ne&&h.jsx(MI,{url:ne.url,copied:ne.copied,onClose:()=>{z(null),Ne()}}),h.jsx(cF,{open:X,onClose:()=>K(!1),candidates:oi})]})}function SF({config:e}){const n=qp(),r=Hp(),[o,s]=w.useState(null),[l,u]=w.useState(null);w.useEffect(()=>u(null),[n]);const d=w.useMemo(()=>{const V=n.split("?")[0].match(/^\/join\/([0-9a-f]+)\/?$/);return V?V[1]:null},[n]),{data:p}=u3(!d),{data:m}=d3(!d),y=!!e.auth.admin,{data:v}=w_(y),b=w.useMemo(()=>__(n,"hub"),[n]),x=w.useMemo(()=>p&&(p.find(V=>V.id===b.project)||o&&p.find(V=>V.org===o)||p[0])||null,[p,b.project,o]);if(w.useEffect(()=>{document.title=x?x.name+" — BearDrive":e.brand||"BearDrive"},[x,e]),d)return h.jsx(_F,{token:d,onDone:async V=>{s(V),await r(),pn("/",{replace:!0})}});const C=e.brand||"BearDrive",_=x&&m?.find(V=>V.id===x.org)||null,E=h.jsx(Ku,{name:C,onHome:()=>pn("/"),search:!!x}),T=e.me?h.jsx(_8,{me:e.me,org:_,orgActive:!!b.org,billing:e.billing,admin:y?{pending:v?.length||0,onClick:()=>{u({kind:"hub"}),mr()}}:void 0}):void 0;if(!p||!m)return h.jsx(sl,{vault:E,topbar:h.jsx(ll,{}),children:h.jsx(yu,{children:h.jsx("div",{className:"empty",children:"Loading…"})})});if(!x)return h.jsx(sl,{vault:E,projectsNav:h.jsx(ew,{projects:p}),orgBar:T,topbar:h.jsx(ll,{}),children:h.jsx(yu,{children:h.jsx(N8,{})})});const j=l?.kind==="hub"?{crumb:"Signup & access",body:h.jsx(p8,{})}:null,O=b.org?m.find(V=>V.id===b.org):null,I=b.org&&!O?{crumb:"Organization",body:h.jsxs("div",{className:"empty",children:[h.jsx("h3",{children:"Organization not found"}),h.jsx("p",{children:"This organization doesn't exist, or you're no longer a member."}),h.jsx("p",{children:h.jsxs("a",{...bu("/"+x.id),children:["Back to ",x.name]})})]})}:O?{crumb:"Organization",body:h.jsx(f8,{org:O,projects:p,myEmail:e.me?.email||""})}:null,B=b.billing?{crumb:"Billing",body:e.billing?h.jsx(C8,{url:e.billing.url}):h.jsxs("div",{className:"empty",children:[h.jsx("h3",{children:"No billing on this hub"}),h.jsx("p",{children:"This BearDrive hub doesn't have a billing surface."})]})}:null,H=b.view==="settings"?{crumb:"Project settings",body:h.jsx(j8,{project:x,org:_,onDeleted:async()=>{await r(),pn("/")}})}:b.view==="install"?{crumb:"Installation",body:h.jsx(MC,{project:x})}:null;return!b.org&&!b.billing&&b.project!==x.id?h.jsx(ou,{to:"/"+x.id}):b.legacyView&&b.view?h.jsx(ou,{to:bo(b.view,x.id,b.viewTarget)}):b.trailingSlash&&b.path?h.jsx(ou,{to:Qu(b.path,x.id,b.version)}):h.jsx(GC,{config:e,apiBase:"/api/p/"+x.id+"/",route:b,hub:!0,project:x,projects:p,sidebar:{vault:E,projectsNav:h.jsx(ew,{projects:p,currentId:x.id,menu:{active:l?null:b.view==="dashboard"&&!b.viewTarget?"dashboard":b.view==="install"?"install":b.view==="history"&&!b.viewTarget?"history":b.view==="settings"?"settings":null,onDashboard:()=>{u(null),pn(bo("dashboard",x.id)),mr()},onInstall:()=>{u(null),pn(bo("install",x.id)),mr()},onHistory:()=>{u(null),pn(bo("history",x.id)),mr()},onSettings:()=>{u(null),pn(bo("settings",x.id)),mr()}}}),orgBar:T},panel:j||I||B||H,onClosePanel:()=>u(null)},x.id)}function _F({token:e,onDone:n}){return w.useEffect(()=>{let r=!1;return So("/api/invites/"+e).then(o=>{r||(Ke(`Welcome — you joined the “${o.org.name}” team. Opening its projects…`),n(o.org.id))}).catch(o=>{r||String(o.message).includes("signing in")||(Ke("Could not accept the invite: "+o.message,!0),n(null))}),()=>{r=!0}},[e]),h.jsx(sl,{vault:h.jsx(Ku,{name:"BearDrive"}),topbar:h.jsx(ll,{}),children:h.jsx(yu,{children:h.jsx("div",{className:"empty",children:"Joining…"})})})}function CF({config:e}){const n=qp(),r=e.volume||"BearDrive";w.useEffect(()=>{document.title=e.brand||r},[e,r]);const o=w.useMemo(()=>__(n,"volume"),[n]);return o.trailingSlash&&o.path?h.jsx(ou,{to:Qu(o.path)}):h.jsx(GC,{config:e,apiBase:"/api/",route:o,hub:!1,sidebar:{vault:h.jsx(Ku,{name:r,showSignout:e.auth.enabled,search:!0})}})}function EF(){const{data:e}=nT();return h.jsxs(SD,{delayDuration:150,children:[e?e.mode==="hub"?h.jsx(SF,{config:e}):h.jsx(CF,{config:e}):h.jsx(sl,{vault:h.jsx(Ku,{name:"…",showSignout:!1}),topbar:h.jsx(ll,{}),children:h.jsx("div",{className:"empty",children:"Loading…"})}),h.jsx(n3,{}),h.jsx(s3,{})]})}const RF=new F2({defaultOptions:{queries:{retry:1,refetchOnWindowFocus:!1}}});h2.createRoot(document.getElementById("root")).render(h.jsx(w.StrictMode,{children:h.jsx(V2,{client:RF,children:h.jsx(EF,{})})})); diff --git a/internal/webapp/static/index.html b/internal/webapp/static/index.html index 16d7656..92efef1 100644 --- a/internal/webapp/static/index.html +++ b/internal/webapp/static/index.html @@ -5,7 +5,7 @@ BearDrive - + diff --git a/web/docs/src/content/docs/guides/agent-artifacts.md b/web/docs/src/content/docs/guides/agent-artifacts.md index 8d52ee5..4d0c255 100644 --- a/web/docs/src/content/docs/guides/agent-artifacts.md +++ b/web/docs/src/content/docs/guides/agent-artifacts.md @@ -94,8 +94,7 @@ bdrive log -n 50 # more of them ``` The web UI's **History** view shows the same thing with view and download of any -past version, including which device (name, OS, and the IP the server observed) -made each change. Folder rows have a history shortcut for a subtree feed. +past version, including which device (name and OS) made each change. Folder rows have a history shortcut for a subtree feed. This is the part a memory API can't give you: when an agent asserts something, you can see which agent wrote it, when, from where, and what the file said diff --git a/web/docs/src/content/docs/self-hosting/authentication.md b/web/docs/src/content/docs/self-hosting/authentication.md index 2b00d3c..7f2b66c 100644 --- a/web/docs/src/content/docs/self-hosting/authentication.md +++ b/web/docs/src/content/docs/self-hosting/authentication.md @@ -82,7 +82,8 @@ alone can't grant. `bdrive login --device` forces that flow. Every sync and every `bdrive init` then authenticates with that token. The hub's device registry records per-device name, OS, account, and the IP the server -observed — that's what History displays. +observed. History shows the device name and OS; the IP stays in the registry +and is never reported to project members. ## Password reset