const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/TableSchemaView-CyBnv8tU.js","assets/vendor-codemirror-D5amxuPd.js","assets/vendor-ui-BLV2MnSs.js","assets/vendor-ag-grid-NsbaVf01.js","assets/ExportDialog-CWNmn9L4.js"])))=>i.map(i=>d[i]);
import{j as e,s as Fe,R as qe,o as Ae,M as Se,P as ct,k as dt}from"./vendor-codemirror-D5amxuPd.js";import{r as i,g as ut,R as Be,c as ue,X as fe,C as Qe,a as xt,L as re,b as me,D as Ue,W as mt,E as ft,T as oe,S as ht,d as ke,e as he,U as le,f as Ee,h as He,i as ye,j as Je,k as De,l as pt,P as bt,m as gt,n as vt,o as jt,p as We,q as yt,B as wt,s as St,H as Nt,F as Ct,t as kt}from"./vendor-ui-BLV2MnSs.js";import{r as Ke,t as Et,A as Tt}from"./vendor-ag-grid-NsbaVf01.js";(function(){const a=document.createElement("link").relList;if(a&&a.supports&&a.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))n(r);new MutationObserver(r=>{for(const o of r)if(o.type==="childList")for(const l of o.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&n(l)}).observe(document,{childList:!0,subtree:!0});function s(r){const o={};return r.integrity&&(o.integrity=r.integrity),r.referrerPolicy&&(o.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?o.credentials="include":r.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function n(r){if(r.ep)return;r.ep=!0;const o=s(r);fetch(r.href,o)}})();var Ne={},Ie=Ke;Ne.createRoot=Ie.createRoot,Ne.hydrateRoot=Ie.hydrateRoot;const $t={},ze=t=>{let a;const s=new Set,n=(x,b)=>{const j=typeof x=="function"?x(a):x;if(!Object.is(j,a)){const y=a;a=b??(typeof j!="object"||j===null)?j:Object.assign({},a,j),s.forEach(S=>S(a,y))}},r=()=>a,d={setState:n,getState:r,getInitialState:()=>u,subscribe:x=>(s.add(x),()=>s.delete(x)),destroy:()=>{($t?"production":void 0)!=="production"&&console.warn("[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."),s.clear()}},u=a=t(n,r,d);return d},_t=t=>t?ze(t):ze;var Ve={exports:{}},Ge={},Ye={exports:{}},Xe={};/**
 * @license React
 * use-sync-external-store-shim.production.js
 *
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */var ie=i;function Dt(t,a){return t===a&&(t!==0||1/t===1/a)||t!==t&&a!==a}var It=typeof Object.is=="function"?Object.is:Dt,zt=ie.useState,Rt=ie.useEffect,Lt=ie.useLayoutEffect,Pt=ie.useDebugValue;function Ot(t,a){var s=a(),n=zt({inst:{value:s,getSnapshot:a}}),r=n[0].inst,o=n[1];return Lt(function(){r.value=s,r.getSnapshot=a,we(r)&&o({inst:r})},[t,s,a]),Rt(function(){return we(r)&&o({inst:r}),t(function(){we(r)&&o({inst:r})})},[t]),Pt(s),s}function we(t){var a=t.getSnapshot;t=t.value;try{var s=a();return!It(t,s)}catch{return!0}}function Mt(t,a){return a()}var Ft=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?Mt:Ot;Xe.useSyncExternalStore=ie.useSyncExternalStore!==void 0?ie.useSyncExternalStore:Ft;Ye.exports=Xe;var qt=Ye.exports;/**
 * @license React
 * use-sync-external-store-shim/with-selector.production.js
 *
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */var pe=i,At=qt;function Bt(t,a){return t===a&&(t!==0||1/t===1/a)||t!==t&&a!==a}var Qt=typeof Object.is=="function"?Object.is:Bt,Ut=At.useSyncExternalStore,Ht=pe.useRef,Jt=pe.useEffect,Wt=pe.useMemo,Kt=pe.useDebugValue;Ge.useSyncExternalStoreWithSelector=function(t,a,s,n,r){var o=Ht(null);if(o.current===null){var l={hasValue:!1,value:null};o.current=l}else l=o.current;o=Wt(function(){function d(y){if(!u){if(u=!0,x=y,y=n(y),r!==void 0&&l.hasValue){var S=l.value;if(r(S,y))return b=S}return b=y}if(S=b,Qt(x,y))return S;var m=n(y);return r!==void 0&&r(S,m)?(x=y,S):(x=y,b=m)}var u=!1,x,b,j=s===void 0?null:s;return[function(){return d(a())},j===null?void 0:function(){return d(j())}]},[a,s,n,r]);var c=Ut(t,o[0],o[1]);return Jt(function(){l.hasValue=!0,l.value=c},[c]),Kt(c),c};Ve.exports=Ge;var Vt=Ve.exports;const Gt=ut(Vt),Ze={},{useDebugValue:Yt}=Be,{useSyncExternalStoreWithSelector:Xt}=Gt;let Re=!1;const Zt=t=>t;function es(t,a=Zt,s){(Ze?"production":void 0)!=="production"&&s&&!Re&&(console.warn("[DEPRECATED] Use `createWithEqualityFn` instead of `create` or use `useStoreWithEqualityFn` instead of `useStore`. They can be imported from 'zustand/traditional'. https://github.com/pmndrs/zustand/discussions/1937"),Re=!0);const n=Xt(t.subscribe,t.getState,t.getServerState||t.getInitialState,a,s);return Yt(n),n}const Le=t=>{(Ze?"production":void 0)!=="production"&&typeof t!="function"&&console.warn("[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`.");const a=typeof t=="function"?_t(t):t,s=(n,r)=>es(a,n,r);return Object.assign(s,a),s},be=t=>t?Le(t):Le,ts={};function ss(t,a){let s;try{s=t()}catch{return}return{getItem:r=>{var o;const l=d=>d===null?null:JSON.parse(d,void 0),c=(o=s.getItem(r))!=null?o:null;return c instanceof Promise?c.then(l):l(c)},setItem:(r,o)=>s.setItem(r,JSON.stringify(o,void 0)),removeItem:r=>s.removeItem(r)}}const ce=t=>a=>{try{const s=t(a);return s instanceof Promise?s:{then(n){return ce(n)(s)},catch(n){return this}}}catch(s){return{then(n){return this},catch(n){return ce(n)(s)}}}},as=(t,a)=>(s,n,r)=>{let o={getStorage:()=>localStorage,serialize:JSON.stringify,deserialize:JSON.parse,partialize:g=>g,version:0,merge:(g,C)=>({...C,...g}),...a},l=!1;const c=new Set,d=new Set;let u;try{u=o.getStorage()}catch{}if(!u)return t((...g)=>{console.warn(`[zustand persist middleware] Unable to update item '${o.name}', the given storage is currently unavailable.`),s(...g)},n,r);const x=ce(o.serialize),b=()=>{const g=o.partialize({...n()});let C;const v=x({state:g,version:o.version}).then(I=>u.setItem(o.name,I)).catch(I=>{C=I});if(C)throw C;return v},j=r.setState;r.setState=(g,C)=>{j(g,C),b()};const y=t((...g)=>{s(...g),b()},n,r);let S;const m=()=>{var g;if(!u)return;l=!1,c.forEach(v=>v(n()));const C=((g=o.onRehydrateStorage)==null?void 0:g.call(o,n()))||void 0;return ce(u.getItem.bind(u))(o.name).then(v=>{if(v)return o.deserialize(v)}).then(v=>{if(v)if(typeof v.version=="number"&&v.version!==o.version){if(o.migrate)return o.migrate(v.state,v.version);console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}else return v.state}).then(v=>{var I;return S=o.merge(v,(I=n())!=null?I:y),s(S,!0),b()}).then(()=>{C==null||C(S,void 0),l=!0,d.forEach(v=>v(S))}).catch(v=>{C==null||C(void 0,v)})};return r.persist={setOptions:g=>{o={...o,...g},g.getStorage&&(u=g.getStorage())},clearStorage:()=>{u==null||u.removeItem(o.name)},getOptions:()=>o,rehydrate:()=>m(),hasHydrated:()=>l,onHydrate:g=>(c.add(g),()=>{c.delete(g)}),onFinishHydration:g=>(d.add(g),()=>{d.delete(g)})},m(),S||y},ns=(t,a)=>(s,n,r)=>{let o={storage:ss(()=>localStorage),partialize:m=>m,version:0,merge:(m,g)=>({...g,...m}),...a},l=!1;const c=new Set,d=new Set;let u=o.storage;if(!u)return t((...m)=>{console.warn(`[zustand persist middleware] Unable to update item '${o.name}', the given storage is currently unavailable.`),s(...m)},n,r);const x=()=>{const m=o.partialize({...n()});return u.setItem(o.name,{state:m,version:o.version})},b=r.setState;r.setState=(m,g)=>{b(m,g),x()};const j=t((...m)=>{s(...m),x()},n,r);r.getInitialState=()=>j;let y;const S=()=>{var m,g;if(!u)return;l=!1,c.forEach(v=>{var I;return v((I=n())!=null?I:j)});const C=((g=o.onRehydrateStorage)==null?void 0:g.call(o,(m=n())!=null?m:j))||void 0;return ce(u.getItem.bind(u))(o.name).then(v=>{if(v)if(typeof v.version=="number"&&v.version!==o.version){if(o.migrate)return[!0,o.migrate(v.state,v.version)];console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}else return[!1,v.state];return[!1,void 0]}).then(v=>{var I;const[z,k]=v;if(y=o.merge(k,(I=n())!=null?I:j),s(y,!0),z)return x()}).then(()=>{C==null||C(y,void 0),y=n(),l=!0,d.forEach(v=>v(y))}).catch(v=>{C==null||C(void 0,v)})};return r.persist={setOptions:m=>{o={...o,...m},m.storage&&(u=m.storage)},clearStorage:()=>{u==null||u.removeItem(o.name)},getOptions:()=>o,rehydrate:()=>S(),hasHydrated:()=>l,onHydrate:m=>(c.add(m),()=>{c.delete(m)}),onFinishHydration:m=>(d.add(m),()=>{d.delete(m)})},o.skipHydration||S(),y||j},rs=(t,a)=>"getStorage"in a||"serialize"in a||"deserialize"in a?((ts?"production":void 0)!=="production"&&console.warn("[DEPRECATED] `getStorage`, `serialize` and `deserialize` options are deprecated. Use `storage` option instead."),as(t,a)):ns(t,a),Te=rs,Ce="/api/v1";async function L(t,a){const s={...a==null?void 0:a.headers};a!=null&&a.body&&(s["Content-Type"]??(s["Content-Type"]="application/json"));const n=await fetch(`${Ce}${t}`,{...a,headers:s});if(!n.ok){const r=await n.json().catch(()=>({detail:n.statusText}));throw new Error(r.detail||`HTTP ${n.status}`)}if(n.status!==204)return n.json()}const A={getSessions:()=>L("/sessions"),createSession:t=>L("/sessions",{method:"POST",body:JSON.stringify(t)}),getSession:t=>L(`/sessions/${t}`),updateSession:(t,a)=>L(`/sessions/${t}`,{method:"PUT",body:JSON.stringify(a)}),deleteSession:t=>L(`/sessions/${t}`,{method:"DELETE"}),testSession:t=>L(`/sessions/${t}/test`,{method:"POST"}),probeConnection:t=>L("/sessions/probe",{method:"POST",body:JSON.stringify(t)}),getDatabases:t=>L(`/sessions/${t}/databases`),getTables:(t,a)=>L(`/sessions/${t}/databases/${a}/tables`),getColumns:(t,a,s)=>L(`/sessions/${t}/databases/${a}/tables/${s}/columns`),getIndexes:(t,a,s)=>L(`/sessions/${t}/databases/${a}/tables/${s}/indexes`),getCreateSql:(t,a,s)=>L(`/sessions/${t}/databases/${a}/tables/${s}/create_sql`),executeQuery:(t,a,s,n)=>L(`/sessions/${t}/query`,{method:"POST",body:JSON.stringify({sql:a,database:s,limit:n})}),cellUpdate:(t,a)=>L(`/sessions/${t}/cell-update`,{method:"POST",body:JSON.stringify(a)}),rowInsert:(t,a)=>L(`/sessions/${t}/row-insert`,{method:"POST",body:JSON.stringify(a)}),rowDelete:(t,a)=>L(`/sessions/${t}/rows`,{method:"DELETE",body:JSON.stringify(a)}),createTable:(t,a,s)=>L(`/sessions/${t}/databases/${a}/tables`,{method:"POST",body:JSON.stringify(s)}),dropTable:(t,a,s)=>L(`/sessions/${t}/databases/${a}/tables/${s}`,{method:"DELETE"}),truncateTable:(t,a,s)=>L(`/sessions/${t}/databases/${a}/tables/${s}/truncate`,{method:"POST"}),createIndex:(t,a,s,n)=>L(`/sessions/${t}/databases/${a}/tables/${s}/indexes`,{method:"POST",body:JSON.stringify(n)}),dropIndex:(t,a,s,n)=>L(`/sessions/${t}/databases/${a}/tables/${s}/indexes/${n}`,{method:"DELETE"}),setPrimaryKey:(t,a,s,n)=>L(`/sessions/${t}/databases/${a}/tables/${s}/primary-key`,{method:"POST",body:JSON.stringify({columns:n})}),dropPrimaryKey:(t,a,s)=>L(`/sessions/${t}/databases/${a}/tables/${s}/primary-key`,{method:"DELETE"}),addColumn:(t,a,s,n)=>L(`/sessions/${t}/databases/${a}/tables/${s}/columns`,{method:"POST",body:JSON.stringify(n)}),modifyColumn:(t,a,s,n,r)=>L(`/sessions/${t}/databases/${a}/tables/${s}/columns/${n}`,{method:"PUT",body:JSON.stringify(r)}),dropColumn:(t,a,s,n)=>L(`/sessions/${t}/databases/${a}/tables/${s}/columns/${n}`,{method:"DELETE"}),exportConfig:async t=>{const a=await fetch(`${Ce}/config/export`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({passphrase:t})});if(!a.ok){const d=await a.json().catch(()=>({detail:a.statusText}));throw new Error(d.detail||`HTTP ${a.status}`)}const s=await a.blob(),r=(a.headers.get("Content-Disposition")??"").match(/filename="([^"]+)"/),o=r?r[1]:"lagun_sessions.json",l=URL.createObjectURL(s),c=document.createElement("a");c.href=l,c.download=o,c.click(),URL.revokeObjectURL(l)},importConfig:async(t,a)=>{const s=new FormData;s.append("file",t),s.append("passphrase",a);const n=await fetch(`${Ce}/config/import`,{method:"POST",body:s});if(!n.ok){const r=await n.json().catch(()=>({detail:n.statusText}));throw new Error(r.detail||`HTTP ${n.status}`)}return n.json()}},ee=be()(Te((t,a)=>({sessions:[],activeSessionId:null,loading:!1,error:null,loadSessions:async()=>{t({loading:!0,error:null});try{const s=await A.getSessions();t({sessions:s,loading:!1})}catch(s){t({error:String(s),loading:!1})}},setActiveSession:s=>t({activeSessionId:s}),createSession:async s=>{const n=await A.createSession(s);return t(r=>({sessions:[...r.sessions,n]})),n},updateSession:async(s,n)=>{const r=await A.updateSession(s,n);return t(o=>({sessions:o.sessions.map(l=>l.id===s?r:l)})),r},deleteSession:async s=>{await A.deleteSession(s),t(n=>({sessions:n.sessions.filter(r=>r.id!==s),activeSessionId:n.activeSessionId===s?null:n.activeSessionId}))},testSession:async s=>A.testSession(s)}),{name:"lagun-session-ui",version:1,partialize:t=>({activeSessionId:t.activeSessionId})}));function Pe(){return`tab-${crypto.randomUUID()}`}const te=be()(Te((t,a)=>({tabs:[],activeTabId:null,openQueryTab:(s,n)=>{const r=Pe(),o={id:r,label:n?`Query — ${n}`:"Query",type:"query",sessionId:s,database:n};t(l=>({tabs:[...l.tabs,o],activeTabId:r}))},openTableTab:(s,n,r)=>{const o=a().tabs.find(d=>d.type==="table"&&d.sessionId===s&&d.database===n&&d.table===r);if(o){t({activeTabId:o.id});return}const l=Pe(),c={id:l,label:r,type:"table",sessionId:s,database:n,table:r};t(d=>({tabs:[...d.tabs,c],activeTabId:l}))},closeTab:s=>{t(n=>{var l;const r=n.tabs.filter(c=>c.id!==s);let o=n.activeTabId;if(o===s){const c=n.tabs.findIndex(d=>d.id===s);o=((l=r[Math.max(0,c-1)])==null?void 0:l.id)??null}return{tabs:r,activeTabId:o}})},setActiveTab:s=>t({activeTabId:s}),setSql:(s,n)=>t(r=>({tabs:r.tabs.map(o=>o.id===s?{...o,sql:n}:o)}))}),{name:"lagun-tabs",version:2,partialize:t=>({tabs:t.tabs,activeTabId:t.activeTabId})})),B=i.forwardRef(({variant:t="secondary",size:a="md",className:s,children:n,...r},o)=>e.jsx("button",{ref:o,className:ue("inline-flex items-center justify-center gap-1.5 font-medium rounded-md transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 disabled:opacity-50 disabled:cursor-not-allowed",{"bg-brand-600 hover:bg-brand-500 text-white":t==="primary","bg-surface-700 hover:bg-surface-600 text-slate-200 border border-surface-600":t==="secondary","hover:bg-surface-800 text-slate-400 hover:text-slate-200":t==="ghost","bg-red-700 hover:bg-red-600 text-white":t==="danger"},{"px-2 py-1 text-xs":a==="sm","px-3 py-1.5 text-sm":a==="md","px-4 py-2 text-base":a==="lg"},s),...r,children:n}));B.displayName="Button";function ge({open:t,onClose:a,title:s,children:n,footer:r,width:o="max-w-lg"}){return i.useEffect(()=>{if(!t)return;const l=c=>{c.key==="Escape"&&a()};return window.addEventListener("keydown",l),()=>window.removeEventListener("keydown",l)},[t,a]),t?e.jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center p-4",children:[e.jsx("div",{className:"absolute inset-0 bg-black/60 backdrop-blur-sm",onClick:a}),e.jsxs("div",{className:`relative bg-surface-900 border border-surface-700 rounded-lg shadow-2xl w-full ${o} flex flex-col max-h-[90vh]`,children:[e.jsxs("div",{className:"flex items-center justify-between px-4 py-3 border-b border-surface-700",children:[e.jsx("h2",{className:"text-sm font-semibold text-slate-100",children:s}),e.jsx(B,{variant:"ghost",size:"sm",onClick:a,className:"p-1",children:e.jsx(fe,{size:14})})]}),e.jsx("div",{className:"p-4 overflow-y-auto flex-1",children:n}),r&&e.jsx("div",{className:"px-4 py-3 border-t border-surface-700 flex justify-end gap-2",children:r})]})]}):null}const K=i.forwardRef(({label:t,error:a,className:s,...n},r)=>{const o=n.id??(t?`input-${t.toLowerCase().replace(/\s+/g,"-").replace(/[^a-z0-9-]/g,"")}`:void 0);return e.jsxs("div",{className:"flex flex-col gap-1",children:[t&&e.jsx("label",{htmlFor:o,className:"text-xs font-medium text-slate-400 uppercase tracking-wide",children:t}),e.jsx("input",{ref:r,id:o,className:ue("bg-surface-800 border border-surface-700 rounded-md px-3 py-1.5 text-sm text-slate-100 placeholder-slate-500","focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-brand-500","disabled:opacity-50 disabled:cursor-not-allowed",a&&"border-red-500",s),...n}),a&&e.jsx("p",{className:"text-xs text-red-400",children:a})]})});K.displayName="Input";const Oe={name:"",host:"localhost",port:"3306",username:"root",password:"",default_db:"",query_limit:"100",ssl_enabled:!1};function et({open:t,onClose:a,session:s}){const{createSession:n,updateSession:r,testSession:o}=ee(),[l,c]=i.useState(Oe),[d,u]=i.useState(!1),[x,b]=i.useState(!1),[j,y]=i.useState(null),[S,m]=i.useState([]),[g,C]=i.useState([]),[v,I]=i.useState(!1),[z,k]=i.useState(null),[h,_]=i.useState(null);i.useEffect(()=>{s?(c({name:s.name,host:s.host,port:String(s.port),username:s.username,password:"",default_db:s.default_db??"",query_limit:String(s.query_limit),ssl_enabled:s.ssl_enabled}),C(s.selected_databases??[])):(c(Oe),C([])),_(null),y(null),m([]),k(null)},[s,t]);const T=(f,D)=>c(J=>({...J,[f]:D})),M=async()=>{u(!0),_(null);try{const f={name:l.name,host:l.host,port:parseInt(l.port),username:l.username,...l.password?{password:l.password}:{},default_db:l.default_db||void 0,query_limit:parseInt(l.query_limit),ssl_enabled:l.ssl_enabled,selected_databases:g};s?await r(s.id,f):await n({...f,password:l.password}),a()}catch(f){_(String(f))}finally{u(!1)}},Q=async()=>{b(!0),y(null);try{let f;s?f=await o(s.id):f=await A.probeConnection({host:l.host,port:parseInt(l.port),username:l.username,password:l.password,ssl_enabled:l.ssl_enabled}),f.ok?y({ok:!0,msg:`Connected! MySQL ${f.server_version} — ${f.latency_ms}ms`}):y({ok:!1,msg:f.error??"Connection failed"})}finally{b(!1)}},F=async()=>{I(!0),k(null);try{let f;if(s?f=await o(s.id):f=await A.probeConnection({host:l.host,port:parseInt(l.port),username:l.username,password:l.password,ssl_enabled:l.ssl_enabled}),f.ok){const D=f.databases??[];m(D),C(J=>J.filter(se=>D.includes(se)))}else k(f.error??"Connection failed")}catch(f){k(String(f))}finally{I(!1)}},R=f=>{C(D=>D.includes(f)?D.filter(J=>J!==f):[...D,f])},G=()=>{C(f=>f.length===S.length?[]:[...S])};return e.jsx(ge,{open:t,onClose:a,title:s?"Edit Connection":"New Connection",footer:e.jsxs(e.Fragment,{children:[e.jsx(B,{variant:"ghost",onClick:a,children:"Cancel"}),e.jsxs(B,{variant:"secondary",onClick:Q,disabled:x,children:[x?e.jsx(re,{size:12,className:"animate-spin"}):null,"Test"]}),e.jsxs(B,{variant:"primary",onClick:M,disabled:d,children:[d?e.jsx(re,{size:12,className:"animate-spin"}):null,s?"Save":"Create"]})]}),children:e.jsxs("div",{className:"flex flex-col gap-3",children:[j&&e.jsxs("div",{className:`flex items-center gap-2 text-xs px-3 py-2 rounded ${j.ok?"bg-green-900/40 text-green-300":"bg-red-900/40 text-red-300"}`,children:[j.ok?e.jsx(Qe,{size:12}):e.jsx(xt,{size:12}),j.msg]}),h&&e.jsx("p",{className:"text-xs text-red-400",children:h}),e.jsx(K,{label:"Connection Name",value:l.name,onChange:f=>T("name",f.target.value),placeholder:"My Database"}),e.jsxs("div",{className:"grid grid-cols-3 gap-2",children:[e.jsx("div",{className:"col-span-2",children:e.jsx(K,{label:"Host",value:l.host,onChange:f=>T("host",f.target.value),placeholder:"localhost"})}),e.jsx(K,{label:"Port",type:"number",value:l.port,onChange:f=>T("port",f.target.value)})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsx(K,{label:"Username",value:l.username,onChange:f=>T("username",f.target.value),placeholder:"root"}),e.jsx(K,{label:"Password",type:"password",value:l.password,onChange:f=>T("password",f.target.value),placeholder:s?"(unchanged)":""})]}),e.jsx(K,{label:"Default Database (optional)",value:l.default_db,onChange:f=>T("default_db",f.target.value),placeholder:"my_db"}),e.jsx(K,{label:"Row Limit",type:"number",value:l.query_limit,onChange:f=>T("query_limit",f.target.value)}),e.jsxs("label",{className:"flex items-center gap-2 text-sm text-slate-300 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:l.ssl_enabled,onChange:f=>T("ssl_enabled",f.target.checked),className:"rounded"}),"Enable SSL"]}),e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs font-medium text-slate-400 uppercase tracking-wide",children:"Databases"}),e.jsxs("div",{className:"flex items-center gap-2",children:[S.length>0&&e.jsx("button",{type:"button",onClick:G,className:"text-xs text-brand-400 hover:text-brand-300",children:g.length===S.length?"Deselect all":"Select all"}),e.jsxs("button",{type:"button",onClick:F,disabled:v,title:"Fetch databases from server",className:"flex items-center gap-1 px-2 py-0.5 rounded text-xs bg-surface-700 hover:bg-surface-600 text-slate-300 disabled:opacity-50",children:[v?e.jsx(re,{size:11,className:"animate-spin"}):e.jsx(me,{size:11}),"Fetch"]})]})]}),z&&e.jsx("p",{className:"text-xs text-red-400",children:z}),S.length===0&&!v&&!z&&e.jsx("p",{className:"text-xs text-slate-500 italic",children:"Click Fetch to load available databases from the server."}),S.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"max-h-40 overflow-y-auto rounded border border-surface-700 bg-surface-950 divide-y divide-surface-800",children:S.map(f=>e.jsxs("label",{className:"flex items-center gap-2 px-3 py-1.5 cursor-pointer hover:bg-surface-800",children:[e.jsx("input",{type:"checkbox",checked:g.includes(f),onChange:()=>R(f),className:"rounded"}),e.jsx(Ue,{size:11,className:"text-yellow-400 flex-shrink-0"}),e.jsx("span",{className:"text-xs text-slate-300",children:f})]},f))}),e.jsx("p",{className:"text-xs text-slate-500",children:g.length===0?"No selection — all databases will be shown":`${g.length} of ${S.length} selected`})]})]})]})})}function os({onNew:t}){const{sessions:a,activeSessionId:s,setActiveSession:n,deleteSession:r}=ee(),{openQueryTab:o}=te(),[l,c]=i.useState(null),[d,u]=i.useState(null);return a.length===0?e.jsx("div",{className:"px-3 py-4 text-center text-xs text-slate-500",children:"No connections yet."}):e.jsxs("div",{className:"py-1",children:[a.map(x=>e.jsxs("div",{className:ue("flex items-center px-3 py-1.5 cursor-pointer group transition-colors",s===x.id?"bg-brand-600/20 text-brand-300":"hover:bg-surface-800 text-slate-300"),onClick:()=>n(x.id),children:[e.jsx(mt,{size:12,className:"flex-shrink-0 mr-2 text-green-400"}),e.jsx("span",{className:"flex-1 truncate text-xs",children:x.name}),e.jsx("span",{className:"text-slate-500 text-xs mr-1",children:x.host}),e.jsxs("div",{className:"relative",children:[e.jsx("button",{onClick:b=>{b.stopPropagation(),u(d===x.id?null:x.id)},className:"opacity-0 group-hover:opacity-100 p-0.5 rounded hover:bg-surface-700 text-slate-400 hover:text-slate-200",children:e.jsx(ft,{size:12})}),d===x.id&&e.jsxs("div",{className:"absolute right-0 top-6 bg-surface-800 border border-surface-700 rounded shadow-lg z-50 py-1 w-40",onMouseLeave:()=>u(null),children:[e.jsxs("button",{className:"flex items-center gap-2 w-full px-3 py-1.5 text-xs hover:bg-surface-700 text-slate-200",onClick:b=>{b.stopPropagation(),o(x.id),u(null)},children:[e.jsx(oe,{size:12})," New Query"]}),e.jsxs("button",{className:"flex items-center gap-2 w-full px-3 py-1.5 text-xs hover:bg-surface-700 text-slate-200",onClick:b=>{b.stopPropagation(),c(x),u(null)},children:[e.jsx(ht,{size:12})," Edit"]}),e.jsxs("button",{className:"flex items-center gap-2 w-full px-3 py-1.5 text-xs hover:bg-surface-700 text-red-400",onClick:b=>{b.stopPropagation(),r(x.id),u(null)},children:[e.jsx(ke,{size:12})," Delete"]})]})]})]},x.id)),l&&e.jsx(et,{open:!!l,onClose:()=>c(null),session:l})]})}function ls({open:t,onClose:a}){const[s,n]=i.useState(""),[r,o]=i.useState(""),[l,c]=i.useState(!1),[d,u]=i.useState(null),x=()=>{n(""),o(""),u(null),a()},b=async()=>{if(u(null),!s){u("Enter a passphrase to protect the exported passwords.");return}if(s!==r){u("Passphrases do not match.");return}c(!0);try{await A.exportConfig(s),x()}catch(j){u(String(j))}finally{c(!1)}};return e.jsx(ge,{open:t,onClose:x,title:"Export Connections",width:"max-w-md",footer:e.jsxs(e.Fragment,{children:[e.jsx(B,{variant:"ghost",onClick:x,children:"Cancel"}),e.jsxs(B,{variant:"primary",onClick:b,disabled:l,children:[l?e.jsx(re,{size:12,className:"animate-spin mr-1"}):e.jsx(he,{size:12,className:"mr-1"}),"Download"]})]}),children:e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx("p",{className:"text-xs text-slate-400",children:"Export all saved connections to an encrypted JSON file. You will need this passphrase to import the file on any Lagun instance."}),e.jsx(K,{label:"Passphrase",type:"password",value:s,onChange:j=>n(j.target.value),placeholder:"Strong passphrase",autoComplete:"new-password"}),e.jsx(K,{label:"Confirm passphrase",type:"password",value:r,onChange:j=>o(j.target.value),placeholder:"Repeat passphrase",autoComplete:"new-password",onKeyDown:j=>j.key==="Enter"&&b()}),d&&e.jsx("p",{className:"text-xs text-red-400",children:d})]})})}function is({open:t,onClose:a}){const{loadSessions:s}=ee(),[n,r]=i.useState(null),[o,l]=i.useState(""),[c,d]=i.useState(!1),[u,x]=i.useState(null),[b,j]=i.useState(null),y=()=>{r(null),l(""),x(null),j(null),a()},S=async()=>{if(!n){j("Select a file first.");return}if(!o){j("Enter the passphrase used during export.");return}d(!0),j(null);try{const m=await A.importConfig(n,o);x(m),await s()}catch(m){j(String(m))}finally{d(!1)}};return e.jsx(ge,{open:t,onClose:y,title:"Import Connections",width:"max-w-md",footer:u?e.jsx(B,{variant:"primary",onClick:y,children:"Done"}):e.jsxs(e.Fragment,{children:[e.jsx(B,{variant:"ghost",onClick:y,children:"Cancel"}),e.jsxs(B,{variant:"primary",onClick:S,disabled:c||!n,children:[c?e.jsx(re,{size:12,className:"animate-spin mr-1"}):e.jsx(le,{size:12,className:"mr-1"}),"Import"]})]}),children:u?e.jsxs("div",{className:"flex flex-col items-center gap-3 py-4",children:[e.jsx(Qe,{size:32,className:"text-green-400"}),e.jsx("p",{className:"text-sm text-slate-200 font-medium",children:"Import complete"}),e.jsxs("p",{className:"text-xs text-slate-400",children:[u.imported," connection",u.imported!==1?"s":""," imported",u.skipped>0?`, ${u.skipped} skipped`:"","."]})]}):e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx("p",{className:"text-xs text-slate-400",children:"Select a Lagun export file (.json) to restore saved connections."}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs font-medium text-slate-400 uppercase tracking-wide block mb-1",children:"Export file"}),e.jsx("input",{type:"file",accept:".json,application/json",onChange:m=>{var g;r(((g=m.target.files)==null?void 0:g[0])??null),j(null)},className:`text-sm text-slate-300 file:mr-3 file:py-1 file:px-3 file:rounded file:border-0
                         file:text-xs file:font-medium file:bg-surface-700 file:text-slate-200
                         hover:file:bg-surface-600 cursor-pointer`})]}),e.jsx(K,{label:"Passphrase",type:"password",value:o,onChange:m=>l(m.target.value),placeholder:"Passphrase used during export",autoComplete:"current-password",onKeyDown:m=>m.key==="Enter"&&S()}),b&&e.jsx("p",{className:"text-xs text-red-400",children:b})]})})}const de=be((t,a)=>({databases:{},tables:{},columns:{},loadingDbs:new Set,loadingTables:new Set,loadDatabases:async s=>{const{databases:n,loadingDbs:r}=a();if(n[s])return n[s];if(r.has(s))return[];t(o=>({loadingDbs:new Set([...o.loadingDbs,s])}));try{const o=await A.getDatabases(s);return t(l=>({databases:{...l.databases,[s]:o},loadingDbs:new Set([...l.loadingDbs].filter(c=>c!==s))})),o}catch{return t(o=>({loadingDbs:new Set([...o.loadingDbs].filter(l=>l!==s))})),[]}},loadTables:async(s,n)=>{const r=`${s}/${n}`,{tables:o,loadingTables:l}=a();if(o[r])return o[r];if(l.has(r))return[];t(c=>({loadingTables:new Set([...c.loadingTables,r])}));try{const c=await A.getTables(s,n);return t(d=>({tables:{...d.tables,[r]:c},loadingTables:new Set([...d.loadingTables].filter(u=>u!==r))})),c}catch{return t(c=>({loadingTables:new Set([...c.loadingTables].filter(d=>d!==r))})),[]}},loadColumns:async(s,n,r)=>{const o=`${s}/${n}/${r}`,{columns:l}=a();if(l[o])return l[o];const c=await A.getColumns(s,n,r);return t(d=>({columns:{...d.columns,[o]:c}})),c},invalidateSession:s=>{t(n=>{const r={...n.databases};delete r[s];const o=Object.fromEntries(Object.entries(n.tables).filter(([c])=>!c.startsWith(`${s}/`))),l=Object.fromEntries(Object.entries(n.columns).filter(([c])=>!c.startsWith(`${s}/`)));return{databases:r,tables:o,columns:l}})},invalidateTable:(s,n,r)=>{const o=`${s}/${n}/${r}`;t(l=>{const c={...l.columns};return delete c[o],{columns:c}})}})),Z=i.forwardRef(({label:t,error:a,className:s,children:n,...r},o)=>e.jsxs("div",{className:"flex flex-col gap-1",children:[t&&e.jsx("label",{className:"text-xs font-medium text-slate-400 uppercase tracking-wide",children:t}),e.jsx("select",{ref:o,className:ue("bg-surface-800 border border-surface-700 rounded-md px-3 py-1.5 text-sm text-slate-100","focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-brand-500","disabled:opacity-50 disabled:cursor-not-allowed",a&&"border-red-500",s),...r,children:n}),a&&e.jsx("p",{className:"text-xs text-red-400",children:a})]}));Z.displayName="Select";function tt({open:t,onClose:a,sessionId:s,database:n,table:r,onImportComplete:o}){const[l,c]=i.useState(null),[d,u]=i.useState(null),[x,b]=i.useState(null),[j,y]=i.useState(!1),[S,m]=i.useState(","),[g,C]=i.useState(""),[v,I]=i.useState('"'),[z,k]=i.useState('"'),[h,_]=i.useState("crlf"),[T,M]=i.useState("utf-8"),F={crlf:`\r
`,lf:`
`,cr:"\r"}[h]||`\r
`,[R,G]=i.useState(!0),[f,D]=i.useState(r??""),[J,se]=i.useState("insert"),[ae,w]=i.useState(!1),[$,P]=i.useState(!1),[E,W]=i.useState(null),X=i.useRef(null),ve=de(p=>p.tables[`${s}/${n}`]??[]),{loadTables:N}=de();i.useEffect(()=>{N(s,n)},[s,n,N]);const q=S==="custom"?g:S,O=i.useCallback(()=>JSON.stringify({database:n,table:f,delimiter:q,quotechar:v,escapechar:z,lineterminator:F,encoding:T,first_row_header:R,strategy:J}),[n,f,q,v,z,F,T,R,J]),U=i.useRef();i.useEffect(()=>{if(!l){u(null),b(null);return}return clearTimeout(U.current),U.current=setTimeout(async()=>{y(!0),b(null);try{const p=new FormData;p.append("file",l),p.append("config",O());const H=await fetch(`/api/v1/sessions/${s}/import/preview`,{method:"POST",body:p});H.ok?(u(await H.json()),b(null)):(b(await H.text()),u(null))}catch(p){b(String(p)),u(null)}finally{y(!1)}},300),()=>clearTimeout(U.current)},[l,q,v,z,h,T,R,s,O]);const V=p=>{p&&p.length>0&&(c(p[0]),W(null))},xe=p=>{p.preventDefault(),V(p.dataTransfer.files)},je=async()=>{if(!(!l||!f)){P(!0),W(null);try{const p=new FormData;p.append("file",l),p.append("config",O());const Y=await(await fetch(`/api/v1/sessions/${s}/import`,{method:"POST",body:p})).json();W(Y),Y.ok&&(o==null||o())}catch(p){W({ok:!1,rows_processed:0,rows_imported:0,method:"unknown",error:String(p)})}finally{P(!1)}}};return e.jsx(ge,{open:t,onClose:a,title:`Import into ${n}${f?"."+f:""}`,width:"max-w-2xl",footer:e.jsxs(e.Fragment,{children:[e.jsx(B,{variant:"ghost",onClick:a,children:"Cancel"}),e.jsx(B,{variant:"primary",onClick:je,disabled:$||!l||!f,children:$?"Importing…":"Import"})]}),children:e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("div",{className:"border-2 border-dashed border-surface-700 rounded-lg p-6 text-center cursor-pointer hover:border-surface-600 transition-colors",onClick:()=>{var p;return(p=X.current)==null?void 0:p.click()},onDragOver:p=>p.preventDefault(),onDrop:xe,children:[e.jsx("input",{ref:X,type:"file",accept:".csv,.tsv,.txt",className:"hidden",onChange:p=>V(p.target.files)}),l?e.jsxs("div",{className:"text-sm",children:[e.jsx(le,{size:20,className:"mx-auto mb-2 text-brand-400"}),e.jsx("p",{className:"text-slate-200",children:l.name}),e.jsxs("p",{className:"text-xs text-slate-500 mt-1",children:[(l.size/1024).toFixed(1)," KB"]})]}):e.jsxs("div",{className:"text-sm text-slate-500",children:[e.jsx(le,{size:20,className:"mx-auto mb-2"}),e.jsx("p",{children:"Drop a CSV file here or click to select"}),e.jsx("p",{className:"text-xs mt-1",children:".csv, .tsv, .txt"})]})]}),j&&e.jsx("p",{className:"text-xs text-slate-500",children:"Loading preview…"}),x&&e.jsx("p",{className:"text-xs text-red-400",children:x}),d&&e.jsxs("div",{className:"overflow-x-auto max-h-48 border border-surface-700 rounded",children:[e.jsxs("table",{className:"text-xs w-full",children:[e.jsx("thead",{children:e.jsx("tr",{className:"bg-surface-800",children:d.columns.map((p,H)=>e.jsx("th",{className:"px-2 py-1 text-left text-slate-300 font-medium whitespace-nowrap border-b border-surface-700",children:p},H))})}),e.jsx("tbody",{children:d.rows.map((p,H)=>e.jsx("tr",{className:"hover:bg-surface-800/50",children:p.map((Y,ne)=>e.jsx("td",{className:"px-2 py-1 text-slate-400 whitespace-nowrap border-b border-surface-800",children:Y},ne))},H))})]}),d.total_lines_sampled>d.rows.length&&e.jsxs("p",{className:"text-xs text-slate-500 px-2 py-1",children:["Showing ",d.rows.length," of ",d.total_lines_sampled,"+ rows"]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs(Z,{label:"Target Table",value:f,onChange:p=>D(p.target.value),children:[e.jsx("option",{value:"",children:"Select table…"}),ve.map(p=>e.jsx("option",{value:p.name,children:p.name},p.name))]}),e.jsxs(Z,{label:"Import Strategy",value:J,onChange:p=>se(p.target.value),children:[e.jsx("option",{value:"insert",children:"INSERT (fail on duplicate)"}),e.jsx("option",{value:"insert_ignore",children:"INSERT IGNORE (skip duplicates)"}),e.jsx("option",{value:"replace",children:"REPLACE INTO (overwrite)"})]})]}),e.jsxs("label",{className:"flex items-center gap-2 text-xs text-slate-300 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:R,onChange:p=>G(p.target.checked),className:"rounded border-surface-600 bg-surface-800 text-brand-500 focus:ring-brand-500"}),"First row contains column names"]}),e.jsxs("div",{children:[e.jsxs("button",{type:"button",className:"flex items-center gap-1 text-xs text-slate-400 hover:text-slate-200 transition-colors",onClick:()=>w(!ae),children:[ae?e.jsx(Ee,{size:12}):e.jsx(He,{size:12}),"CSV Format Options"]}),ae&&e.jsxs("div",{className:"mt-3 flex flex-col gap-3 pl-4 border-l border-surface-700",children:[e.jsxs("div",{className:"flex gap-3",children:[e.jsxs(Z,{label:"Delimiter",value:S,onChange:p=>m(p.target.value),children:[e.jsx("option",{value:",",children:"Comma (,)"}),e.jsx("option",{value:";",children:"Semicolon (;)"}),e.jsx("option",{value:"\\t",children:"Tab"}),e.jsx("option",{value:"|",children:"Pipe (|)"}),e.jsx("option",{value:"custom",children:"Custom"})]}),S==="custom"&&e.jsx(K,{label:"Custom",value:g,onChange:p=>C(p.target.value.slice(0,1)),className:"w-16"})]}),e.jsxs("div",{className:"flex gap-3",children:[e.jsxs(Z,{label:"Quote Character",value:v,onChange:p=>I(p.target.value),children:[e.jsx("option",{value:'"',children:'Double Quote (")'}),e.jsx("option",{value:"'",children:"Single Quote (')"}),e.jsx("option",{value:"",children:"None"})]}),e.jsxs(Z,{label:"Escape Character",value:z,onChange:p=>k(p.target.value),children:[e.jsx("option",{value:'"',children:'Double Quote (")'}),e.jsx("option",{value:"\\\\",children:"Backslash (\\)"}),e.jsx("option",{value:"",children:"None"})]})]}),e.jsxs("div",{className:"flex gap-3",children:[e.jsxs(Z,{label:"Line Ending",value:h,onChange:p=>_(p.target.value),children:[e.jsx("option",{value:"crlf",children:"CRLF (Windows)"}),e.jsx("option",{value:"lf",children:"LF (Unix/Mac)"}),e.jsx("option",{value:"cr",children:"CR (Legacy Mac)"})]}),e.jsxs(Z,{label:"Encoding",value:T,onChange:p=>M(p.target.value),children:[e.jsx("option",{value:"utf-8",children:"UTF-8"}),e.jsx("option",{value:"utf-8-sig",children:"UTF-8 with BOM"}),e.jsx("option",{value:"ascii",children:"ASCII"})]})]})]})]}),E&&e.jsx("div",{className:`p-3 rounded text-xs ${E.ok?"bg-green-900/30 border border-green-800 text-green-300":"bg-red-900/30 border border-red-800 text-red-300"}`,children:E.ok?e.jsxs(e.Fragment,{children:["Imported ",E.rows_imported," rows via ",E.method==="load_data"?"LOAD DATA":"batch insert",".",E.warnings&&E.warnings.length>0&&e.jsxs("ul",{className:"mt-1 list-disc list-inside text-yellow-400",children:[E.warnings.slice(0,5).map((p,H)=>e.jsx("li",{children:p},H)),E.warnings.length>5&&e.jsxs("li",{children:["…and ",E.warnings.length-5," more"]})]})]}):e.jsxs(e.Fragment,{children:["Import failed: ",E.error]})})]})})}const cs=Object.freeze(Object.defineProperty({__proto__:null,default:tt},Symbol.toStringTag,{value:"Module"}));function ds(t){const a=`lagun-bookmarks-${t}`,[s,n]=i.useState(()=>{try{const l=localStorage.getItem(a);return new Set(l?JSON.parse(l):[])}catch{return new Set}});return{bookmarks:s,toggle:(l,c)=>{const d=`${l}/${c}`;n(u=>{const x=new Set(u);return x.has(d)?x.delete(d):x.add(d),localStorage.setItem(a,JSON.stringify([...x])),x})},isBookmarked:(l,c)=>s.has(`${l}/${c}`)}}function us({sessionId:t,selectedDatabases:a}){const{databases:s,loadDatabases:n,loadTables:r,tables:o,invalidateSession:l}=de(),{openTableTab:c,openQueryTab:d}=te(),[u,x]=i.useState(new Set),[b,j]=i.useState(""),[y,S]=i.useState(!1),[m,g]=i.useState(null),[C,v]=i.useState(null),{bookmarks:I,toggle:z,isBookmarked:k}=ds(t);i.useEffect(()=>{n(t)},[t,n]),i.useEffect(()=>{S(!1),j("")},[t]);const h=()=>{l(t),n(t),x(new Set),j("")},_=w=>{j(w),w&&F.forEach($=>{x(P=>new Set([...P,$])),o[`${t}/${$}`]||r(t,$)})},T=async w=>{const $=new Set(u);$.has(w)?$.delete(w):($.add(w),await r(t,w)),x($)},M=()=>{const w=!y;S(w),w&&F.forEach($=>{[...I].some(E=>E.startsWith(`${$}/`))&&(x(E=>new Set([...E,$])),o[`${t}/${$}`]||r(t,$))})},Q=s[t]??[],F=a&&a.length>0?Q.filter(w=>a.includes(w)):Q,R=b.toLowerCase(),G=F.map(w=>{let P=o[`${t}/${w}`]??[];return y&&(P=P.filter(E=>k(w,E.name))),R&&(P=P.filter(E=>E.name.toLowerCase().includes(R))),{db:w,tbls:P}}).filter(({db:w,tbls:$})=>y?$.length>0:!R||$.length>0||w.toLowerCase().includes(R)),f=(w,$,P)=>{w.preventDefault(),w.stopPropagation(),g({x:w.clientX,y:w.clientY,db:$,table:P})},D=()=>g(null),J=async(w,$)=>{if(!confirm(`Drop table ${w}.${$}? This cannot be undone.`))return;await A.dropTable(t,w,$);const P=`${t}/${w}`;de.setState(E=>({tables:{...E.tables,[P]:(E.tables[P]??[]).filter(W=>W.name!==$)}})),D()},se=async(w,$)=>{confirm(`Truncate table ${w}.${$}? All rows will be deleted.`)&&(await A.truncateTable(t,w,$),D())},ae=y&&I.size===0;return e.jsxs("div",{className:"py-1",onClick:D,children:[e.jsxs("div",{className:"flex items-center justify-between px-3 py-1",children:[e.jsx("span",{className:"text-xs font-medium text-slate-500 uppercase tracking-wide",children:"Databases"}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("button",{onClick:M,title:y?"Show all tables":"Show bookmarks only",className:`p-0.5 transition-colors ${y?"text-yellow-400":"text-slate-500 hover:text-slate-300"}`,children:e.jsx(ye,{size:10,fill:y?"currentColor":"none"})}),e.jsx("button",{onClick:h,className:"p-0.5 text-slate-500 hover:text-slate-300 transition-colors",children:e.jsx(me,{size:10})})]})]}),e.jsx("div",{className:"px-2 pb-1",children:e.jsxs("div",{className:"flex items-center gap-1.5 bg-surface-800 rounded px-2 py-1",children:[e.jsx(Je,{size:10,className:"text-slate-500 flex-shrink-0"}),e.jsx("input",{type:"text",value:b,onChange:w=>_(w.target.value),placeholder:y?"Filter bookmarks…":"Filter tables…",className:"bg-transparent text-xs text-slate-300 placeholder-slate-600 flex-1 outline-none min-w-0"}),b&&e.jsx("button",{onClick:()=>j(""),className:"text-slate-500 hover:text-slate-300",children:e.jsx(fe,{size:10})})]})}),ae?e.jsxs("div",{className:"flex flex-col items-center gap-2 px-4 py-8 text-center",children:[e.jsx(ye,{size:18,className:"text-slate-700"}),e.jsxs("p",{className:"text-xs text-slate-600",children:["No bookmarks yet.",e.jsx("br",{}),"Hover a table and click ★ to add one."]})]}):G.map(({db:w,tbls:$})=>{const P=u.has(w);return e.jsxs("div",{children:[e.jsxs("button",{className:"flex items-center gap-1.5 w-full px-2 py-1 hover:bg-surface-800 text-slate-300 group",onClick:()=>T(w),onContextMenu:E=>f(E,w),children:[P?e.jsx(Ee,{size:12,className:"flex-shrink-0"}):e.jsx(He,{size:12,className:"flex-shrink-0"}),e.jsx(Ue,{size:12,className:"flex-shrink-0 text-yellow-400"}),e.jsx("span",{className:"text-xs truncate flex-1 text-left",children:w}),e.jsx("span",{role:"button",title:"New query on this database",onClick:E=>{E.stopPropagation(),d(t,w)},className:"opacity-0 group-hover:opacity-100 p-0.5 hover:text-brand-400",children:e.jsx(oe,{size:10})})]}),P&&$.map(E=>{const W=k(w,E.name);return e.jsxs("button",{className:"flex items-center gap-1.5 w-full pl-7 pr-2 py-0.5 hover:bg-surface-800 text-slate-400 hover:text-slate-200 group",onClick:()=>c(t,w,E.name),onContextMenu:X=>f(X,w,E.name),children:[e.jsx(De,{size:11,className:"flex-shrink-0 text-slate-500"}),e.jsx("span",{className:"text-xs truncate flex-1 text-left",children:E.name}),e.jsx("span",{role:"button",title:W?"Remove bookmark":"Bookmark table",onClick:X=>{X.stopPropagation(),z(w,E.name)},className:`p-0.5 transition-colors ${W?"text-yellow-400":"opacity-0 group-hover:opacity-100 text-slate-500 hover:text-yellow-400"}`,children:e.jsx(ye,{size:10,fill:W?"currentColor":"none"})})]},E.name)})]},w)}),m&&e.jsx("div",{className:"fixed bg-surface-800 border border-surface-700 rounded shadow-lg z-50 py-1 w-44",style:{top:m.y,left:m.x},onClick:w=>w.stopPropagation(),children:m.table?e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"flex items-center gap-2 w-full px-3 py-1.5 text-xs hover:bg-surface-700 text-slate-200",onClick:()=>{c(t,m.db,m.table),D()},children:[e.jsx(De,{size:12})," Open Table"]}),e.jsxs("button",{className:"flex items-center gap-2 w-full px-3 py-1.5 text-xs hover:bg-surface-700 text-slate-200",onClick:()=>{d(t,m.db),D()},children:[e.jsx(oe,{size:12})," New Query"]}),e.jsxs("button",{className:"flex items-center gap-2 w-full px-3 py-1.5 text-xs hover:bg-surface-700 text-slate-200",onClick:()=>{v({db:m.db,table:m.table}),D()},children:[e.jsx(le,{size:12})," Import CSV"]}),e.jsx("hr",{className:"border-surface-700 my-1"}),e.jsxs("button",{className:"flex items-center gap-2 w-full px-3 py-1.5 text-xs hover:bg-surface-700 text-yellow-400",onClick:()=>se(m.db,m.table),children:[e.jsx(pt,{size:12})," Truncate"]}),e.jsxs("button",{className:"flex items-center gap-2 w-full px-3 py-1.5 text-xs hover:bg-surface-700 text-red-400",onClick:()=>J(m.db,m.table),children:[e.jsx(ke,{size:12})," Drop Table"]})]}):e.jsxs("button",{className:"flex items-center gap-2 w-full px-3 py-1.5 text-xs hover:bg-surface-700 text-slate-200",onClick:()=>{d(t,m.db),D()},children:[e.jsx(oe,{size:12})," New Query"]})}),C&&e.jsx(tt,{open:!!C,onClose:()=>v(null),sessionId:t,database:C.db,table:C.table})]})}const xs={sm:"w-7 h-7",md:"w-9 h-9",lg:"w-14 h-14"},ms={sm:"text-sm",md:"text-base",lg:"text-xl"};function st({size:t="md",showText:a=!0,className:s=""}){return e.jsxs("div",{className:`flex items-center gap-2 ${s}`,children:[e.jsxs("svg",{viewBox:"0 0 128 128",xmlns:"http://www.w3.org/2000/svg",className:`${xs[t]} flex-shrink-0`,children:[e.jsx("rect",{x:"4",y:"4",width:"120",height:"120",rx:"24",fill:"#f0f9ff"}),e.jsxs("g",{fill:"none",stroke:"#2563eb",strokeWidth:"3",strokeLinecap:"round",children:[e.jsx("path",{d:"M 28 34 Q 38 26 48 34 T 68 34 T 88 34 T 100 34"}),e.jsx("path",{d:"M 28 50 Q 38 42 48 50 T 68 50 T 88 50 T 100 50"}),e.jsx("path",{d:"M 28 66 Q 38 58 48 66 T 68 66 T 88 66 T 100 66"})]}),e.jsxs("g",{fill:"none",stroke:"#0891b2",strokeWidth:"2.5",strokeLinecap:"round",children:[e.jsx("line",{x1:"28",y1:"82",x2:"100",y2:"82"}),e.jsx("line",{x1:"28",y1:"94",x2:"100",y2:"94"}),e.jsx("line",{x1:"52",y1:"82",x2:"52",y2:"94"}),e.jsx("line",{x1:"76",y1:"82",x2:"76",y2:"94"})]}),e.jsx("circle",{cx:"64",cy:"74",r:"3",fill:"#0284c7"})]}),a&&e.jsx("span",{className:`font-semibold text-slate-100 ${ms[t]} tracking-tight`,children:"Lagun"})]})}function fs(){const{sessions:t,activeSessionId:a}=ee(),[s,n]=i.useState(!1),[r,o]=i.useState(!1),[l,c]=i.useState(!1);return e.jsxs("aside",{className:"w-64 flex-shrink-0 bg-surface-900 border-r border-surface-800 flex flex-col overflow-hidden",children:[e.jsxs("div",{className:"flex items-center justify-between px-3 py-3 border-b border-surface-800",children:[e.jsx(st,{size:"sm",showText:!0}),e.jsxs("div",{className:"flex items-center gap-0.5",children:[e.jsx(B,{variant:"ghost",size:"sm",onClick:()=>c(!0),title:"Import connections",className:"p-1",children:e.jsx(le,{size:14})}),e.jsx(B,{variant:"ghost",size:"sm",onClick:()=>o(!0),title:"Export connections",className:"p-1",children:e.jsx(he,{size:14})}),e.jsx(B,{variant:"ghost",size:"sm",onClick:()=>n(!0),title:"New connection",className:"p-1",children:e.jsx(bt,{size:14})})]})]}),e.jsx("div",{className:"flex-shrink-0 border-b border-surface-800",children:e.jsx(os,{onNew:()=>n(!0)})}),e.jsx("div",{className:"flex-1 overflow-y-auto",children:a&&(()=>{const d=t.find(u=>u.id===a);return e.jsx(us,{sessionId:a,selectedDatabases:d==null?void 0:d.selected_databases})})()}),e.jsx(et,{open:s,onClose:()=>n(!1)}),e.jsx(ls,{open:r,onClose:()=>o(!1)}),e.jsx(is,{open:l,onClose:()=>c(!1)})]})}function hs(){const{tabs:t,activeTabId:a,setActiveTab:s,closeTab:n}=te();return t.length===0?null:e.jsx("div",{className:"flex items-center bg-surface-900 border-b border-surface-800 overflow-x-auto flex-shrink-0",children:t.map(r=>e.jsxs("button",{onClick:()=>s(r.id),className:ue("flex items-center gap-1.5 px-3 py-2 text-xs border-r border-surface-800 whitespace-nowrap min-w-0 group transition-colors",a===r.id?"bg-surface-950 text-slate-100 border-t-2 border-t-brand-500":"text-slate-400 hover:text-slate-200 hover:bg-surface-800"),children:[r.type==="query"?e.jsx(oe,{size:12,className:"flex-shrink-0"}):e.jsx(gt,{size:12,className:"flex-shrink-0"}),e.jsx("span",{className:"truncate max-w-[120px]",children:r.label}),e.jsx("span",{role:"button",onClick:o=>{o.stopPropagation(),n(r.id)},className:"ml-0.5 opacity-0 group-hover:opacity-100 hover:text-red-400 transition-opacity",children:e.jsx(fe,{size:10})})]},r.id))})}const ps="modulepreload",bs=function(t){return"/"+t},Me={},$e=function(a,s,n){let r=Promise.resolve();if(s&&s.length>0){document.getElementsByTagName("link");const l=document.querySelector("meta[property=csp-nonce]"),c=(l==null?void 0:l.nonce)||(l==null?void 0:l.getAttribute("nonce"));r=Promise.allSettled(s.map(d=>{if(d=bs(d),d in Me)return;Me[d]=!0;const u=d.endsWith(".css"),x=u?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${d}"]${x}`))return;const b=document.createElement("link");if(b.rel=u?"stylesheet":ps,u||(b.as="script"),b.crossOrigin="",b.href=d,c&&b.setAttribute("nonce",c),document.head.appendChild(b),u)return new Promise((j,y)=>{b.addEventListener("load",j),b.addEventListener("error",()=>y(new Error(`Unable to preload CSS for ${d}`)))})}))}function o(l){const c=new Event("vite:preloadError",{cancelable:!0});if(c.payload=l,window.dispatchEvent(c),!c.defaultPrevented)throw l}return r.then(l=>{for(const c of l||[])c.status==="rejected"&&o(c.reason);return a().catch(o)})},_e=be()(Te(t=>({entries:[],addEntry:a=>t(s=>({entries:[{...a,id:crypto.randomUUID(),timestamp:new Date().toISOString()},...s.entries].slice(0,200)})),clearLog:()=>t({entries:[]})}),{name:"lagun-query-log",version:1,partialize:t=>({entries:t.entries})})),gs=[100,500,1e3,5e3,1e4];function vs({value:t,onChange:a,onRun:s,running:n,database:r,schema:o,limit:l,onLimitChange:c}){const d=x=>{(x.ctrlKey||x.metaKey)&&x.key==="Enter"&&(x.preventDefault(),n||s())},u=i.useMemo(()=>Fe({dialect:Se,schema:o??{},defaultSchema:r}),[o,r]);return e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsxs("div",{className:"flex items-center justify-between px-3 py-1.5 bg-surface-900 border-b border-surface-800",children:[e.jsx("div",{className:"flex items-center gap-2",children:r&&e.jsx("span",{className:"text-xs text-slate-500 bg-surface-800 px-2 py-0.5 rounded",children:r})}),e.jsxs("div",{className:"flex items-center gap-2",children:[c&&e.jsxs("div",{className:"flex items-center gap-1 text-xs text-slate-500",children:[e.jsx("span",{children:"Limit"}),e.jsx("select",{value:l,onChange:x=>c(Number(x.target.value)),className:"bg-surface-800 border border-surface-700 rounded px-1.5 py-0.5 text-xs text-slate-300 focus:outline-none focus:ring-1 focus:ring-brand-500",children:gs.map(x=>e.jsx("option",{value:x,children:x.toLocaleString()},x))})]}),e.jsx("kbd",{className:"hidden sm:inline-flex items-center px-1.5 py-0.5 text-[10px] font-mono text-slate-500 bg-surface-800 border border-surface-700 rounded",children:"Ctrl+↵"}),e.jsxs(B,{variant:"primary",size:"sm",onClick:s,disabled:n||!t.trim(),title:"Run (Ctrl+Enter)",children:[n?e.jsx(re,{size:12,className:"animate-spin"}):e.jsx(vt,{size:12}),"Run"]})]})]}),e.jsx("div",{className:"flex-1 overflow-hidden",onKeyDown:d,children:e.jsx(qe,{value:t,onChange:a,extensions:[u],theme:Ae,className:"h-full text-sm",style:{height:"100%"},basicSetup:{lineNumbers:!0,highlightActiveLine:!0,autocompletion:!0,foldGutter:!0}})})]})}function js({x:t,y:a,items:s,onClose:n}){const r=i.useRef(null),[o,l]=i.useState({left:t,top:a});return i.useLayoutEffect(()=>{if(!r.current)return;const{width:c,height:d}=r.current.getBoundingClientRect();l({left:Math.min(t,window.innerWidth-c-8),top:Math.min(a,window.innerHeight-d-8)})},[t,a]),i.useEffect(()=>{const c=u=>{u.key==="Escape"&&n()},d=u=>{r.current&&!r.current.contains(u.target)&&n()};return window.addEventListener("keydown",c),window.addEventListener("mousedown",d),()=>{window.removeEventListener("keydown",c),window.removeEventListener("mousedown",d)}},[n]),Ke.createPortal(e.jsx("div",{ref:r,className:"fixed z-[9999] bg-surface-900 border border-surface-700 rounded-md shadow-2xl py-1 min-w-[180px]",style:{left:o.left,top:o.top},onContextMenu:c=>c.preventDefault(),children:s.map((c,d)=>c.type==="separator"?e.jsx("div",{className:"border-t border-surface-700 my-1"},d):e.jsxs("button",{className:`flex items-center gap-2 w-full px-3 py-1.5 text-xs text-left ${c.danger?"text-red-400 hover:bg-red-950/40":"text-slate-300 hover:bg-surface-800"}`,onClick:c.onClick,children:[c.icon,c.label]},d))}),document.body)}const ys=Et.withParams({backgroundColor:"#0f172a",foregroundColor:"#cbd5e1",headerBackgroundColor:"#1e293b",headerTextColor:"#94a3b8",borderColor:"#1e293b",rowHoverColor:"#1e293b",selectedRowBackgroundColor:"#1e3a5f",oddRowBackgroundColor:"#0f172a",fontFamily:"ui-monospace, monospace",fontSize:12,cellTextColor:"#cbd5e1",headerFontSize:12,headerFontWeight:600}),ws=new Set(["datetime","timestamp","date","time"]);function Ss(t){const a=o=>String(o).padStart(2,"0"),s=new Date,n=`${s.getFullYear()}-${a(s.getMonth()+1)}-${a(s.getDate())}`,r=`${a(s.getHours())}:${a(s.getMinutes())}:${a(s.getSeconds())}`;return t==="date"?n:t==="time"?r:`${n} ${r}`}function at({result:t,onCellEdit:a,primaryKeyColumns:s=[],editable:n=!1,selectable:r,onSelectionChange:o,columns:l,onDeleteRows:c}){const[d,u]=i.useState(null),x=i.useRef(null),b=i.useMemo(()=>t.columns.map(h=>({field:h,headerName:h,editable:n&&h!=="__rowIndex",resizable:!0,sortable:!0,filter:!0,cellStyle:{fontFamily:"ui-monospace, monospace",fontSize:"12px"},headerClass:"text-xs font-semibold"})),[t.columns,n]),j=i.useMemo(()=>t.rows.map((h,_)=>{const T={__ag_rowId:String(_)};return t.columns.forEach((M,Q)=>{T[M]=h[Q]}),T}),[t.rows,t.columns]),y=i.useCallback(h=>h.data.__ag_rowId,[]),S=i.useMemo(()=>r?{mode:"multiRow",checkboxes:!0,headerCheckbox:!0,enableClickSelection:!1}:void 0,[r]),m=i.useMemo(()=>({minWidth:80,flex:1}),[]),g=i.useCallback(h=>{!a||!h.colDef.field||a({column:h.colDef.field,newValue:h.newValue,data:h.data})},[a]),C=i.useCallback(h=>{o==null||o(h.api.getSelectedRows())},[o]),v=i.useCallback(h=>{const _=h.event;if(!(_!=null&&_.shiftKey)){x.current=h.rowIndex??null;return}const T=h.rowIndex??0,M=x.current??T,Q=Math.min(M,T),F=Math.max(M,T);h.api.deselectAll(),h.api.forEachNode(R=>{R.rowIndex!==null&&R.rowIndex>=Q&&R.rowIndex<=F&&R.setSelected(!0)})},[]),I=i.useCallback(h=>{const _=h.event;if(!_)return;_.preventDefault();const T=h.api.getSelectedRows();u({x:_.clientX,y:_.clientY,columnName:h.colDef.field??"",cellValue:h.value,rowData:h.data??{},selectedRows:T})},[]),z=i.useCallback(()=>u(null),[]),k=i.useMemo(()=>{if(!d)return[];const h=l==null?void 0:l.find(R=>R.name===d.columnName),_=h&&ws.has(h.data_type.toLowerCase()),T=d.selectedRows.length>0?d.selectedRows:[d.rowData],{__ag_rowId:M,...Q}=d.rowData,F=[{type:"item",label:"Copy cell",icon:e.jsx(yt,{size:12}),onClick:()=>{navigator.clipboard.writeText(String(d.cellValue??"")),z()}},{type:"item",label:"Copy row as JSON",icon:e.jsx(wt,{size:12}),onClick:()=>{navigator.clipboard.writeText(JSON.stringify(Q,null,2)),z()}}];if(n&&(h!=null&&h.is_nullable&&(F.push({type:"separator"}),F.push({type:"item",label:"Set to NULL",icon:e.jsx(jt,{size:12}),onClick:()=>{a==null||a({column:d.columnName,newValue:null,data:d.rowData}),z()}})),_)){const R=Ss(h.data_type.toLowerCase());F.push({type:"item",label:`Set to NOW()  ${R}`,icon:e.jsx(We,{size:12}),onClick:()=>{a==null||a({column:d.columnName,newValue:R,data:d.rowData}),z()}})}if(c&&s.length>0){const R=T.length>1?`Delete ${T.length} rows`:"Delete row";F.push({type:"separator"}),F.push({type:"item",label:R,danger:!0,icon:e.jsx(ke,{size:12}),onClick:()=>{c(T),z()}})}return F},[d,l,n,a,c,s,z]);return t.error?e.jsx("div",{className:"p-4 bg-red-950/50 border border-red-800 rounded m-3",children:e.jsx("p",{className:"text-xs font-mono text-red-300",children:t.error})}):e.jsxs("div",{className:"h-full",children:[e.jsx(Tt,{theme:ys,columnDefs:b,rowData:j,getRowId:y,onCellValueChanged:g,onSelectionChanged:C,onRowClicked:r?v:void 0,onCellContextMenu:I,onBodyScroll:z,defaultColDef:m,rowSelection:S,suppressContextMenu:!0,preventDefaultOnContextMenu:!0,singleClickEdit:!0,stopEditingWhenCellsLoseFocus:!0}),d&&e.jsx(js,{x:d.x,y:d.y,items:k,onClose:z})]})}function nt({result:t,running:a}){return a?e.jsx("div",{className:"flex items-center gap-3 px-3 py-1.5 bg-surface-900 border-t border-surface-800 text-xs text-slate-400",children:e.jsx("span",{className:"animate-pulse",children:"Executing..."})}):t?e.jsx("div",{className:"flex items-center gap-4 px-3 py-1.5 bg-surface-900 border-t border-surface-800 text-xs",children:t.error?e.jsxs("span",{className:"flex items-center gap-1 text-red-400",children:[e.jsx(St,{size:11})," Error"]}):e.jsxs(e.Fragment,{children:[e.jsxs("span",{className:"flex items-center gap-1 text-slate-400",children:[e.jsx(Nt,{size:11}),t.row_count.toLocaleString()," ",t.row_count===1?"row":"rows"]}),t.affected_rows!=null&&e.jsxs("span",{className:"text-slate-400",children:[t.affected_rows," affected"]}),e.jsxs("span",{className:"flex items-center gap-1 text-slate-500",children:[e.jsx(We,{size:11}),t.exec_time_ms,"ms"]}),t.insert_id?e.jsxs("span",{className:"text-slate-500",children:["insert_id=",t.insert_id]}):null]})}):null}const Ns=i.lazy(()=>$e(()=>import("./TableSchemaView-CyBnv8tU.js"),__vite__mapDeps([0,1,2,3]))),rt=i.lazy(()=>$e(()=>import("./ExportDialog-CWNmn9L4.js"),__vite__mapDeps([4,1,2,3]))),Cs=i.lazy(()=>$e(()=>Promise.resolve().then(()=>cs),void 0)),ks=[100,500,1e3,5e3,1e4];function Es({tab:t}){return t.type==="query"?e.jsx(Ts,{tab:t}):e.jsx($s,{tab:t})}function Ts({tab:t}){const a=te(k=>{var h;return((h=k.tabs.find(_=>_.id===t.id))==null?void 0:h.sql)??""}),s=te(k=>k.setSql),[n,r]=i.useState(a),o=i.useRef(n);o.current=n,i.useEffect(()=>{const k=setTimeout(()=>s(t.id,n),500);return()=>clearTimeout(k)},[n,t.id,s]),i.useEffect(()=>()=>{s(t.id,o.current)},[t.id,s]),i.useEffect(()=>{r(a)},[t.id]);const[l,c]=i.useState(null),[d,u]=i.useState(!1),[x,b]=i.useState(1e3),[j,y]=i.useState(!1),{tables:S,columns:m,loadTables:g,loadColumns:C}=de(),v=_e(k=>k.addEntry),I=i.useMemo(()=>{if(!t.database)return{};const k=S[`${t.sessionId}/${t.database}`]??[],h={};for(const _ of k){const T=`${t.sessionId}/${t.database}/${_.name}`;h[_.name]=(m[T]??[]).map(M=>M.name)}return h},[t.sessionId,t.database,S,m]);i.useEffect(()=>{t.database&&g(t.sessionId,t.database).then(k=>{for(const h of k)C(t.sessionId,t.database,h.name)})},[t.sessionId,t.database]);const z=async()=>{if(!n.trim())return;u(!0);const k=Date.now();try{const h=await A.executeQuery(t.sessionId,n,t.database,x);c(h),v({sql:n.trim(),sessionId:t.sessionId,database:t.database,rowCount:h.row_count??void 0,execTimeMs:h.exec_time_ms??Date.now()-k,error:h.error??void 0})}finally{u(!1)}};return e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("div",{className:"h-48 flex-shrink-0 border-b border-surface-800",children:e.jsx(vs,{value:n,onChange:r,onRun:z,running:d,database:t.database,schema:I,limit:x,onLimitChange:b})}),e.jsx("div",{className:"flex-1 overflow-hidden",children:l?e.jsx(at,{result:l}):e.jsx("div",{className:"flex items-center justify-center h-full text-slate-600 text-sm",children:"Press Ctrl+Enter to run a query"})}),e.jsxs("div",{className:"flex items-center border-t border-surface-800",children:[e.jsx("div",{className:"flex-1",children:e.jsx(nt,{result:l,running:d})}),l&&!l.error&&l.columns.length>0&&e.jsxs("button",{onClick:()=>y(!0),className:"flex items-center gap-1 px-3 py-1.5 text-xs text-slate-500 hover:text-slate-300 transition-colors",title:"Export result",children:[e.jsx(he,{size:11})," Export"]})]}),j&&t.database&&n.trim()&&e.jsx(i.Suspense,{fallback:null,children:e.jsx(rt,{open:j,onClose:()=>y(!1),sessionId:t.sessionId,database:t.database,table:"result",sql:n.trim()})})]})}function $s({tab:t}){const[a,s]=i.useState("schema"),[n,r]=i.useState(null),[o,l]=i.useState([]),[c,d]=i.useState(!1),[u,x]=i.useState(!1),[b,j]=i.useState(1e3),[y,S]=i.useState(null),[m,g]=i.useState([]),[C,v]=i.useState(!1),[I,z]=i.useState(!1),[k,h]=i.useState(""),[_,T]=i.useState(""),[M,Q]=i.useState(""),[F,R]=i.useState(!1),G=_e(N=>N.addEntry),f=o.filter(N=>N.is_primary_key).map(N=>N.name),D=async(N,q,O)=>{if(!t.database||!t.table)return;const U=N??b,V=q!==void 0?q:k,xe=O!==void 0?O:M;g([]),n===null?d(!0):x(!0);const je=Date.now();try{const p=await A.getColumns(t.sessionId,t.database,t.table);l(p);let H=`SELECT * FROM \`${t.database}\`.\`${t.table}\``;const Y=[];if(V.trim()&&p.length>0){const ot=V.replace(/\\/g,"\\\\").replace(/'/g,"''").replace(/%/g,"\\%").replace(/_/g,"\\_"),lt=p.map(it=>`\`${it.name}\` LIKE '%${ot}%'`);Y.push(`(${lt.join(" OR ")})`)}xe.trim()&&Y.push(`(${xe.trim()})`),Y.length>0&&(H+=` WHERE ${Y.join(" AND ")}`);const ne=await A.executeQuery(t.sessionId,H,void 0,U);r(ne),G({sql:H,sessionId:t.sessionId,database:t.database,rowCount:ne.row_count??void 0,execTimeMs:ne.exec_time_ms??Date.now()-je,error:ne.error??void 0})}finally{d(!1),x(!1)}};i.useEffect(()=>{a==="data"&&!n&&D()},[a]),i.useEffect(()=>{s("schema"),r(null),l([]),h(""),T(""),Q(""),R(!1)},[t.sessionId,t.database,t.table]),i.useEffect(()=>{if(a!=="data")return;const N=setTimeout(()=>{D(void 0,k,M)},400);return()=>clearTimeout(N)},[k]);const J=async N=>{if(!t.database||!t.table||f.length===0)return;const q={};f.forEach(V=>{q[V]=N.data[V]});const O=Date.now(),U=await A.cellUpdate(t.sessionId,{database:t.database,table:t.table,primary_key:q,column:N.column,new_value:N.newValue});U.ok?(S(`✓ ${U.sql_executed}`),G({sql:U.sql_executed,sessionId:t.sessionId,database:t.database,affectedRows:U.affected_rows??void 0,execTimeMs:Date.now()-O}),D()):(S(`✗ ${U.error}`),G({sql:U.sql_executed||`UPDATE ${t.database}.${t.table}`,sessionId:t.sessionId,database:t.database,execTimeMs:Date.now()-O,error:U.error??void 0})),setTimeout(()=>S(null),4e3)},se=async N=>{if(!t.database||!t.table||f.length===0)return;const q=N.map(U=>Object.fromEntries(f.map(V=>[V,U[V]]))),O=await A.rowDelete(t.sessionId,{database:t.database,table:t.table,primary_keys:q});O.ok?(S(`✓ Deleted ${O.affected_rows} row${O.affected_rows!==1?"s":""}`),G({sql:`DELETE FROM \`${t.database}\`.\`${t.table}\` (${O.affected_rows} row${O.affected_rows!==1?"s":""})`,sessionId:t.sessionId,database:t.database,affectedRows:O.affected_rows,execTimeMs:0}),D()):S(`✗ ${O.error}`),setTimeout(()=>S(null),4e3)},ae=N=>{j(N),n&&D(N)},w=i.useCallback(()=>{Q(_),D(void 0,k,_)},[_,k]),$=()=>{T(""),Q(""),D(void 0,k,"")},P=()=>{h("")},E=i.useRef(w);E.current=w;const W=i.useMemo(()=>Fe({dialect:Se}),[]),X=i.useMemo(()=>{const N=o.map(q=>({label:q.name,type:"property",boost:99}));return Se.language.data.of({autocomplete:q=>{const O=q.matchBefore(/\w+/);return!O&&!q.explicit?null:{from:O?O.from:q.pos,options:N,validFor:/^\w*$/}}})},[o]),ve=i.useMemo(()=>ct.highest(dt.of([{key:"Enter",run:()=>(E.current(),!0)},{key:"Mod-Enter",run:()=>(E.current(),!0)}])),[]);return e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsxs("div",{className:"flex items-center gap-2 px-3 py-1.5 bg-surface-900 border-b border-surface-800",children:[e.jsxs("span",{className:"text-xs text-slate-400",children:[t.database,".",t.table]}),e.jsx("div",{className:"flex-1"}),a==="data"&&e.jsxs("div",{className:"relative flex items-center",children:[e.jsx(Je,{size:11,className:"absolute left-2 text-slate-500 pointer-events-none"}),e.jsx("input",{type:"text",value:k,onChange:N=>h(N.target.value),placeholder:"Search all columns…",className:"bg-surface-800 border border-surface-700 rounded pl-6 pr-6 py-0.5 text-xs text-slate-300 placeholder-slate-600 focus:outline-none focus:ring-1 focus:ring-brand-500 w-44"}),k&&e.jsx("button",{onClick:P,className:"absolute right-1.5 text-slate-500 hover:text-slate-300",children:e.jsx(fe,{size:10})})]}),a==="data"&&e.jsxs("button",{onClick:()=>R(N=>!N),className:`flex items-center gap-1 px-2 py-0.5 text-xs rounded transition-colors ${F||M?"text-brand-400 bg-brand-950 border border-brand-800":"text-slate-500 hover:text-slate-300"}`,title:"Toggle WHERE filter",children:[e.jsx(Ct,{size:11}),M?"Filtered":"Filter"]}),a==="data"&&e.jsxs("div",{className:"flex items-center gap-1 text-xs text-slate-500",children:[e.jsx("span",{children:"Limit"}),e.jsx("select",{value:b,onChange:N=>ae(Number(N.target.value)),className:"bg-surface-800 border border-surface-700 rounded px-1.5 py-0.5 text-xs text-slate-300 focus:outline-none focus:ring-1 focus:ring-brand-500",children:ks.map(N=>e.jsx("option",{value:N,children:N.toLocaleString()},N))})]}),a==="data"&&u&&e.jsx(me,{size:12,className:"animate-spin text-slate-400"}),e.jsxs("div",{className:"flex rounded overflow-hidden border border-surface-700",children:[e.jsx("button",{className:`px-2.5 py-0.5 text-xs transition-colors ${a==="schema"?"bg-brand-600 text-white":"bg-surface-800 text-slate-400 hover:text-slate-200"}`,onClick:()=>s("schema"),children:"Schema"}),e.jsx("button",{className:`px-2.5 py-0.5 text-xs transition-colors ${a==="data"?"bg-brand-600 text-white":"bg-surface-800 text-slate-400 hover:text-slate-200"}`,onClick:()=>s("data"),children:"Data"})]}),a==="data"&&e.jsxs("button",{onClick:()=>z(!0),className:"flex items-center gap-1 px-2 py-0.5 text-xs text-slate-500 hover:text-slate-300 transition-colors",title:"Import data",children:[e.jsx(le,{size:11})," Import"]}),a==="data"&&n&&!n.error&&e.jsxs("button",{onClick:()=>v(!0),className:"flex items-center gap-1 px-2 py-0.5 text-xs text-slate-500 hover:text-slate-300 transition-colors",title:"Export data",children:[e.jsx(he,{size:11})," Export"]}),a==="data"&&e.jsx(B,{variant:"ghost",size:"sm",onClick:()=>D(),title:"Refresh",disabled:c||u,children:e.jsx(me,{size:12,className:c||u?"animate-spin":""})})]}),a==="data"&&F&&e.jsxs("div",{className:"flex items-center gap-2 px-3 py-1.5 bg-surface-900 border-b border-surface-700",children:[e.jsx("span",{className:"text-xs text-slate-500 font-mono shrink-0",children:"WHERE"}),e.jsx("div",{className:"flex-1 rounded overflow-hidden border border-surface-700 focus-within:ring-1 focus-within:ring-brand-500",children:e.jsx(qe,{value:_,onChange:N=>{T(N),!N.trim()&&M&&(Q(""),D(void 0,k,""))},extensions:[W,X,ve],theme:Ae,height:"28px",placeholder:"e.g. id = 5 AND name LIKE 'John%'",basicSetup:{lineNumbers:!1,foldGutter:!1,highlightActiveLine:!1,autocompletion:!0}})}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[e.jsx("kbd",{className:"hidden sm:inline-flex items-center px-1.5 py-0.5 text-[10px] font-mono text-slate-500 bg-surface-800 border border-surface-700 rounded",children:"Ctrl+↵"}),e.jsx("button",{onClick:w,className:"px-2.5 py-0.5 text-xs bg-brand-600 hover:bg-brand-500 text-white rounded transition-colors",children:"Apply"})]}),M&&e.jsx("button",{onClick:$,className:"px-2 py-0.5 text-xs text-slate-500 hover:text-slate-300 transition-colors shrink-0",children:"Clear"})]}),e.jsx("div",{className:"flex-1 overflow-hidden",children:a==="schema"&&t.database&&t.table?e.jsx(i.Suspense,{fallback:e.jsx("div",{className:"flex items-center justify-center h-full text-slate-500 text-sm",children:"Loading schema…"}),children:e.jsx(Ns,{sessionId:t.sessionId,database:t.database,table:t.table})}):a==="data"?c?e.jsxs("div",{className:"flex items-center justify-center h-full text-slate-500 text-sm",children:["Loading ",t.table,"…"]}):n?e.jsx(at,{result:n,editable:f.length>0,primaryKeyColumns:f,onCellEdit:J,onDeleteRows:se,selectable:!0,onSelectionChange:g,columns:o}):e.jsx("div",{className:"flex items-center justify-center h-full text-slate-600 text-sm",children:"No data loaded"}):null}),y&&e.jsx("div",{className:"px-3 py-1.5 bg-surface-900 border-t border-surface-800",children:e.jsx("p",{className:"text-xs font-mono text-slate-400 truncate",children:y})}),a==="data"&&n&&e.jsx(nt,{result:n,running:!1}),C&&t.database&&t.table&&e.jsx(i.Suspense,{fallback:null,children:e.jsx(rt,{open:C,onClose:()=>v(!1),sessionId:t.sessionId,database:t.database,table:t.table,pkValues:m.length>0?m.map(N=>Object.fromEntries(f.map(q=>[q,N[q]]))):void 0})}),I&&t.database&&e.jsx(i.Suspense,{fallback:null,children:e.jsx(Cs,{open:I,onClose:()=>z(!1),sessionId:t.sessionId,database:t.database,table:t.table,onImportComplete:()=>D()})})]})}function _s(t){const a=new Date(t),s=String(a.getHours()).padStart(2,"0"),n=String(a.getMinutes()).padStart(2,"0"),r=String(a.getSeconds()).padStart(2,"0");return`${s}:${n}:${r}`}function Ds(t){return t.affectedRows!=null?`${t.affectedRows} affected`:t.rowCount!=null?`${t.rowCount} rows`:"—"}function Is(){const[t,a]=i.useState(!1),{entries:s,clearLog:n}=_e();return e.jsxs("div",{className:"flex-shrink-0 border-t border-surface-800 bg-surface-950",children:[e.jsxs("div",{className:"flex items-center gap-2 px-3 h-7 cursor-pointer select-none",onClick:()=>a(r=>!r),children:[e.jsx(oe,{size:12,className:"text-slate-500"}),e.jsx("span",{className:"text-xs text-slate-400 font-medium",children:"Query Log"}),s.length>0&&e.jsx("span",{className:"text-xs bg-surface-800 text-slate-400 rounded px-1 py-0.5 leading-none",children:s.length}),e.jsx("div",{className:"flex-1"}),t&&s.length>0&&e.jsx("button",{onClick:r=>{r.stopPropagation(),n()},className:"text-xs text-slate-500 hover:text-slate-300 transition-colors px-1",children:"Clear"}),t?e.jsx(Ee,{size:12,className:"text-slate-500"}):e.jsx(kt,{size:12,className:"text-slate-500"})]}),t&&e.jsx("div",{className:"h-[180px] overflow-y-auto",children:s.length===0?e.jsx("div",{className:"flex items-center justify-center h-full text-slate-600 text-xs",children:"No queries logged yet"}):e.jsxs("table",{className:"w-full text-xs border-collapse",children:[e.jsx("thead",{className:"sticky top-0 bg-surface-900",children:e.jsxs("tr",{className:"text-slate-500",children:[e.jsx("th",{className:"text-left px-2 py-1 font-medium w-16",children:"Time"}),e.jsx("th",{className:"text-left px-2 py-1 font-medium",children:"SQL"}),e.jsx("th",{className:"text-left px-2 py-1 font-medium w-24",children:"Rows"}),e.jsx("th",{className:"text-left px-2 py-1 font-medium w-16",children:"ms"}),e.jsx("th",{className:"text-left px-2 py-1 font-medium w-12",children:"Status"})]})}),e.jsx("tbody",{children:s.map(r=>e.jsxs("tr",{className:`border-t border-surface-800 ${r.error?"bg-red-950/30":""}`,children:[e.jsx("td",{className:"px-2 py-0.5 text-slate-500 tabular-nums",children:_s(r.timestamp)}),e.jsx("td",{className:"px-2 py-0.5 font-mono text-slate-300 max-w-0 w-full truncate",title:r.sql,children:r.sql.length>80?r.sql.slice(0,80)+"…":r.sql}),e.jsx("td",{className:"px-2 py-0.5 text-slate-400 tabular-nums",children:Ds(r)}),e.jsx("td",{className:"px-2 py-0.5 text-slate-400 tabular-nums",children:r.execTimeMs}),e.jsx("td",{className:"px-2 py-0.5",children:r.error?e.jsx("span",{className:"text-red-400",title:r.error,children:"✗"}):e.jsx("span",{className:"text-green-400",children:"✓"})})]},r.id))})]})})]})}function zs(){const{tabs:t,activeTabId:a}=te();return e.jsxs("div",{className:"flex h-screen overflow-hidden bg-surface-950 text-slate-100",children:[e.jsx(fs,{}),e.jsxs("div",{className:"flex flex-col flex-1 min-w-0 overflow-hidden",children:[e.jsx(hs,{}),e.jsx("div",{className:"flex-1 overflow-hidden",children:t.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center h-full text-slate-500 gap-4",children:[e.jsx(st,{size:"lg",showText:!1,className:"opacity-40"}),e.jsx("p",{className:"text-sm",children:"Select a table from the sidebar or open a query tab"})]}):t.map(s=>e.jsx("div",{className:`h-full ${a===s.id?"":"hidden"}`,children:e.jsx(Es,{tab:s})},s.id))}),e.jsx(Is,{})]})]})}function Rs(){const t=ee(a=>a.loadSessions);return i.useEffect(()=>{t().then(()=>{const a=new Set(ee.getState().sessions.map(r=>r.id)),{activeSessionId:s}=ee.getState();s&&!a.has(s)&&ee.getState().setActiveSession(null);const{tabs:n}=te.getState();for(const r of n)a.has(r.sessionId)||te.getState().closeTab(r.id)})},[t]),e.jsx(zs,{})}Ne.createRoot(document.getElementById("root")).render(e.jsx(Be.StrictMode,{children:e.jsx(Rs,{})}));export{B,K as I,ge as M,Z as S,A as a,de as u};
