@dataramen/cli 0.0.71 → 0.0.72-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/app.js +3 -3
- package/dist/code/cli.js +3 -3
- package/dist/code/server.js +1 -1
- package/dist/code/web/assets/index-D2A-ae-t.css +1 -0
- package/dist/code/web/assets/{index-VGcygI3P.js → index-DMm8a2KY.js} +10 -10
- package/dist/code/web/assets/main-Brv3iq8M.css +1 -0
- package/dist/code/web/assets/main-CDCzK-ke.js +4 -0
- package/dist/code/web/assets/{setup-XBuZP5zl.js → setup-el13-XvO.js} +1 -1
- package/dist/code/web/index.html +4 -4
- package/dist/code/web/setup.html +3 -3
- package/dist/package.json +1 -1
- package/package.json +1 -1
- package/dist/code/web/assets/index-CuM5yTKj.css +0 -1
- package/dist/code/web/assets/main-Bhe6PtBh.js +0 -4
- package/dist/code/web/assets/main-DSZwBUKr.css +0 -1
package/bin/app.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var se=Object.create;var R=Object.defineProperty;var ie=Object.getOwnPropertyDescriptor;var ae=Object.getOwnPropertyNames;var me=Object.getPrototypeOf,ce=Object.prototype.hasOwnProperty;var le=(e,t,o,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let
|
|
3
|
-
`);for(let
|
|
2
|
+
var se=Object.create;var R=Object.defineProperty;var ie=Object.getOwnPropertyDescriptor;var ae=Object.getOwnPropertyNames;var me=Object.getPrototypeOf,ce=Object.prototype.hasOwnProperty;var le=(e,t,o,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ae(t))!ce.call(e,n)&&n!==o&&R(e,n,{get:()=>t[n],enumerable:!(s=ie(t,n))||s.enumerable});return e};var c=(e,t,o)=>(o=e!=null?se(me(e)):{},le(t||!e||!e.__esModule?R(o,"default",{value:e,enumerable:!0}):o,e));var b=require("commander"),C=(e,t)=>{t.commands.forEach(o=>{e.command(o.command).description(o.description).action(o.handler)})};function P(){let e=new b.Command,t={id:"commander",setMetadata:o=>(e.name(o.name).description(o.description).version(o.version,"-v, --version","Show version"),t),setDefaultCommand:o=>(e.command("default",{hidden:!0,isDefault:!0}).action(o.handler),t),setModules:o=>(o.forEach(s=>{if(s.name==="root")C(e,s);else{let n=e.command(s.name).description(`(Module) ${s.description}`);C(n,s)}}),t),start:()=>(e.parse(),t),getHandler:()=>e};return t}var V=c(require("fs-extra")),y=require("node:path");var _=require("node:os"),M=require("node:path"),pe=(0,_.homedir)(),m="@dataramen/server",a=(0,M.join)(pe,".dataramen",".runtime","server");function A(e){let t;function o(){try{return t||(t=V.readJsonSync(e)),t}catch{return}}return o}var N=A((0,y.join)(__dirname,"..","package.json")),k=A((0,y.join)(a,"package.json"));var u=c(require("fs-extra")),p=require("node:path"),H=require("node:child_process"),O=require("node:util"),g=c(require("yocto-spinner")),f=(0,O.promisify)(H.exec);function W(){try{let e=k();if(!e)return!0;let t=u.readJsonSync((0,p.join)(__dirname,"..","dist","package.json"));return e.buildToken!==t.buildToken}catch{return!0}}async function $(){let e=(0,g.default)({text:"Checking if PM2 is installed"}).start();try{return await f("pm2 -v"),e.success("PM2 already installed"),!0}catch{return e.warning("PM2 not installed"),!1}}async function j(){let e=(0,g.default)({text:"Installing PM2"}).start();try{await f("npm i -g pm2"),e.success("Installed PM2")}catch{e.error("Failed to install PM2"),process.exit(1)}}async function v(){let e=(0,g.default)({text:"Stop running instances of "+m}).start();try{await f(`pm2 stop "${m}"`),e.warning("Stopped "+m)}catch{e.success("No running instances of "+m+" found")}}async function I(){let e=(0,g.default)({text:"Create local server"}).start();u.removeSync((0,p.join)(a,"code")),u.copySync((0,p.join)(__dirname,"..","dist","code"),(0,p.join)(a,"code")),u.copySync((0,p.join)(__dirname,"..","dist","package.json"),(0,p.join)(a,"package.json")),e.text="Install local server dependencies",await f("npm i",{cwd:a}),e.success("Local server installed")}var S=c(require("node:crypto"));var E=require("fs-extra"),w=require("node:path");function ue(e){try{return(0,E.readFileSync)((0,w.join)(a,e),"utf-8")}catch{return}}function de(e){let t={},o=ue(e);if(o){let s=o.split(`
|
|
3
|
+
`);for(let n of s){let i=n.trim();if(!i||i.startsWith("#"))continue;let d=i.indexOf("=");if(d===-1)continue;let T=i.slice(0,d).trim(),l=i.slice(d+1).trim();(l.startsWith('"')&&l.endsWith('"')||l.startsWith("'")&&l.endsWith("'"))&&(l=l.slice(1,-1)),t[T]=l}}return t}function fe(){let e={customValues:{},fileName:".env"};function t(){e.customValues=de(e.fileName)}function o(){let i=Object.entries(e.customValues).map(([d,T])=>`${d}=${T}`).join(`
|
|
4
4
|
`)+`
|
|
5
|
-
`;(0,E.writeFileSync)((0,w.join)(a,e.fileName),i,{encoding:"utf8"})}function s(
|
|
5
|
+
`;(0,E.writeFileSync)((0,w.join)(a,e.fileName),i,{encoding:"utf8"})}function s(n){if(e.customValues[n])return e.customValues[n]}return t(),{getNumber:n=>ge(s(n)),getString:n=>ve(s(n)),getBoolean:n=>Ee(s(n)),flush:o,set:(n,i)=>{e.customValues[n]=i.toString()},unset:n=>{delete e.customValues[n]},values:()=>({...e.customValues})}}function ge(e){if(!e)return;let t=Number(e);if(!isNaN(t)&&e.trim()!=="")return t;throw new Error("Wrong env value type")}function ve(e){if(e){if(typeof e=="string")return e;throw new Error("Wrong env value type")}}function Ee(e){if(!e)return;let t=e.toLowerCase();if(t==="true"||t==="1")return!0;if(t==="false"||t==="0")return!1;throw new Error("Wrong env value type")}var r=fe();function J(){let e=!1;if(!r.getString("SYMM_ENCRYPTION_KEY")){let t=S.randomBytes(32).toString("hex");r.set("SYMM_ENCRYPTION_KEY",t),console.log("Generated random SYMM_ENCRYPTION_KEY"),e=!0}if(!r.getString("JWT_SECRET")){let t=S.randomBytes(32).toString("hex");r.set("JWT_SECRET",t),console.log("Generated random JWT_SECRET"),e=!0}if(!r.getString("JWT_REFRESH_SECRET")){let t=S.randomBytes(32).toString("hex");r.set("JWT_REFRESH_SECRET",t),console.log("Generated random JWT_REFRESH_SECRET"),e=!0}e&&r.flush()}var F=require("node:net");async function L(e){return new Promise(t=>{let o=(0,F.createServer)().once("error",()=>{t(!1)}).once("listening",()=>{o.close()}).once("close",()=>t(!0)).listen(e,"127.0.0.1")})}var x=c(require("yocto-spinner"));var D=c(require("fs-extra")),K=require("node:path");var Se=async e=>{try{return(await fetch(e,{method:"GET",signal:AbortSignal.timeout(5e3)})).status===200}catch{return!1}},Y=async(e,t,o)=>{let s=Date.now();for(;Date.now()-s<t;){if(await Se(e))return!0;await new Promise(i=>setTimeout(i,o))}return!1};var B=c(require("open")),ye={command:"start",description:"Start local server, restarts if already running",handler:async()=>{await $()||await j(),await v();try{W()&&await I(),J();let t=r.getNumber("PORT")||4466;if(!t)throw new Error("PORT env variable not found");if(!await L(t))throw new Error(`Port ${t} is occupied by another process`);let s=(0,x.default)({text:"Starting new instance of "+m}).start(),n=D.readJsonSync((0,K.join)(a,"package.json"));await f(`pm2 start "${n.main}" --name "${m}" --no-autorestart -- --mode=cli --env="${a}/.env"`,{cwd:a}),s.success("Local server will be available in a couple of seconds");let i=(0,x.default)({text:"Waiting for the server to become available"}).start();await Y(`http://localhost:${t}/api/status`,3e4,1e3)?(await(0,B.default)(`http://localhost:${t}`),i.success(`App is running at http://localhost:${t}`)):i.error("Server failed to become available in time")}catch(t){console.error("Failed to start local server",t)}}},h=ye;var G=require("node:child_process");var we={command:"logs",description:"Listen for logs",handler:async()=>{(0,G.execSync)(`pm2 logs ${m}`,{stdio:"inherit"})}},U=we;var xe={command:"stop",description:"Stop the server",handler:v},Q=xe;var q=c(require("open")),Re={command:"open",description:"Open webapp",handler:async()=>{let e=r.getNumber("PORT");await(0,q.default)(`http://localhost:${e}`)}},z=Re;var X={name:"root",description:"Root module has no description",commands:[h,U,Q,z]};var Ce={command:"set <prop> <value>",description:"Set env value",module:"env",handler:async(e,t)=>{r.set(e,t),r.flush(),console.log(`Environment property set: ${e}`)}},Z=Ce;var be={command:"unset <prop>",description:"Remove env value",module:"env",handler:async e=>{r.unset(e),r.flush(),console.log(`Environment property unset: ${e}`)}},ee=be;var Pe={command:"list",description:"List env values",module:"env",handler:async()=>{console.table(r.values())}},te=Pe;var oe={name:"env",description:"Handle env variables",commands:[Z,ee,te]};var ne=[X,oe],re=h;var _e=P();_e.setMetadata({name:"dataramen",description:"A cozy web GUI for MySQL and PostgreSQL - built for developers who like to move fast and stay focused.",version:N().version}).setDefaultCommand(re).setModules(ne).start();
|
package/dist/code/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var se=Object.create;var R=Object.defineProperty;var ie=Object.getOwnPropertyDescriptor;var ae=Object.getOwnPropertyNames;var me=Object.getPrototypeOf,ce=Object.prototype.hasOwnProperty;var le=(e,t,o,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let
|
|
3
|
-
`);for(let
|
|
2
|
+
var se=Object.create;var R=Object.defineProperty;var ie=Object.getOwnPropertyDescriptor;var ae=Object.getOwnPropertyNames;var me=Object.getPrototypeOf,ce=Object.prototype.hasOwnProperty;var le=(e,t,o,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ae(t))!ce.call(e,n)&&n!==o&&R(e,n,{get:()=>t[n],enumerable:!(s=ie(t,n))||s.enumerable});return e};var c=(e,t,o)=>(o=e!=null?se(me(e)):{},le(t||!e||!e.__esModule?R(o,"default",{value:e,enumerable:!0}):o,e));var b=require("commander"),C=(e,t)=>{t.commands.forEach(o=>{e.command(o.command).description(o.description).action(o.handler)})};function P(){let e=new b.Command,t={id:"commander",setMetadata:o=>(e.name(o.name).description(o.description).version(o.version,"-v, --version","Show version"),t),setDefaultCommand:o=>(e.command("default",{hidden:!0,isDefault:!0}).action(o.handler),t),setModules:o=>(o.forEach(s=>{if(s.name==="root")C(e,s);else{let n=e.command(s.name).description(`(Module) ${s.description}`);C(n,s)}}),t),start:()=>(e.parse(),t),getHandler:()=>e};return t}var V=c(require("fs-extra")),y=require("node:path");var _=require("node:os"),M=require("node:path"),pe=(0,_.homedir)(),m="@dataramen/server",a=(0,M.join)(pe,".dataramen",".runtime","server");function A(e){let t;function o(){try{return t||(t=V.readJsonSync(e)),t}catch{return}}return o}var N=A((0,y.join)(__dirname,"..","package.json")),k=A((0,y.join)(a,"package.json"));var u=c(require("fs-extra")),p=require("node:path"),H=require("node:child_process"),O=require("node:util"),g=c(require("yocto-spinner")),f=(0,O.promisify)(H.exec);function W(){try{let e=k();if(!e)return!0;let t=u.readJsonSync((0,p.join)(__dirname,"..","dist","package.json"));return e.buildToken!==t.buildToken}catch{return!0}}async function $(){let e=(0,g.default)({text:"Checking if PM2 is installed"}).start();try{return await f("pm2 -v"),e.success("PM2 already installed"),!0}catch{return e.warning("PM2 not installed"),!1}}async function j(){let e=(0,g.default)({text:"Installing PM2"}).start();try{await f("npm i -g pm2"),e.success("Installed PM2")}catch{e.error("Failed to install PM2"),process.exit(1)}}async function v(){let e=(0,g.default)({text:"Stop running instances of "+m}).start();try{await f(`pm2 stop "${m}"`),e.warning("Stopped "+m)}catch{e.success("No running instances of "+m+" found")}}async function I(){let e=(0,g.default)({text:"Create local server"}).start();u.removeSync((0,p.join)(a,"code")),u.copySync((0,p.join)(__dirname,"..","dist","code"),(0,p.join)(a,"code")),u.copySync((0,p.join)(__dirname,"..","dist","package.json"),(0,p.join)(a,"package.json")),e.text="Install local server dependencies",await f("npm i",{cwd:a}),e.success("Local server installed")}var S=c(require("node:crypto"));var E=require("fs-extra"),w=require("node:path");function ue(e){try{return(0,E.readFileSync)((0,w.join)(a,e),"utf-8")}catch{return}}function de(e){let t={},o=ue(e);if(o){let s=o.split(`
|
|
3
|
+
`);for(let n of s){let i=n.trim();if(!i||i.startsWith("#"))continue;let d=i.indexOf("=");if(d===-1)continue;let T=i.slice(0,d).trim(),l=i.slice(d+1).trim();(l.startsWith('"')&&l.endsWith('"')||l.startsWith("'")&&l.endsWith("'"))&&(l=l.slice(1,-1)),t[T]=l}}return t}function fe(){let e={customValues:{},fileName:".env"};function t(){e.customValues=de(e.fileName)}function o(){let i=Object.entries(e.customValues).map(([d,T])=>`${d}=${T}`).join(`
|
|
4
4
|
`)+`
|
|
5
|
-
`;(0,E.writeFileSync)((0,w.join)(a,e.fileName),i,{encoding:"utf8"})}function s(
|
|
5
|
+
`;(0,E.writeFileSync)((0,w.join)(a,e.fileName),i,{encoding:"utf8"})}function s(n){if(e.customValues[n])return e.customValues[n]}return t(),{getNumber:n=>ge(s(n)),getString:n=>ve(s(n)),getBoolean:n=>Ee(s(n)),flush:o,set:(n,i)=>{e.customValues[n]=i.toString()},unset:n=>{delete e.customValues[n]},values:()=>({...e.customValues})}}function ge(e){if(!e)return;let t=Number(e);if(!isNaN(t)&&e.trim()!=="")return t;throw new Error("Wrong env value type")}function ve(e){if(e){if(typeof e=="string")return e;throw new Error("Wrong env value type")}}function Ee(e){if(!e)return;let t=e.toLowerCase();if(t==="true"||t==="1")return!0;if(t==="false"||t==="0")return!1;throw new Error("Wrong env value type")}var r=fe();function J(){let e=!1;if(!r.getString("SYMM_ENCRYPTION_KEY")){let t=S.randomBytes(32).toString("hex");r.set("SYMM_ENCRYPTION_KEY",t),console.log("Generated random SYMM_ENCRYPTION_KEY"),e=!0}if(!r.getString("JWT_SECRET")){let t=S.randomBytes(32).toString("hex");r.set("JWT_SECRET",t),console.log("Generated random JWT_SECRET"),e=!0}if(!r.getString("JWT_REFRESH_SECRET")){let t=S.randomBytes(32).toString("hex");r.set("JWT_REFRESH_SECRET",t),console.log("Generated random JWT_REFRESH_SECRET"),e=!0}e&&r.flush()}var F=require("node:net");async function L(e){return new Promise(t=>{let o=(0,F.createServer)().once("error",()=>{t(!1)}).once("listening",()=>{o.close()}).once("close",()=>t(!0)).listen(e,"127.0.0.1")})}var x=c(require("yocto-spinner"));var D=c(require("fs-extra")),K=require("node:path");var Se=async e=>{try{return(await fetch(e,{method:"GET",signal:AbortSignal.timeout(5e3)})).status===200}catch{return!1}},Y=async(e,t,o)=>{let s=Date.now();for(;Date.now()-s<t;){if(await Se(e))return!0;await new Promise(i=>setTimeout(i,o))}return!1};var B=c(require("open")),ye={command:"start",description:"Start local server, restarts if already running",handler:async()=>{await $()||await j(),await v();try{W()&&await I(),J();let t=r.getNumber("PORT")||4466;if(!t)throw new Error("PORT env variable not found");if(!await L(t))throw new Error(`Port ${t} is occupied by another process`);let s=(0,x.default)({text:"Starting new instance of "+m}).start(),n=D.readJsonSync((0,K.join)(a,"package.json"));await f(`pm2 start "${n.main}" --name "${m}" --no-autorestart -- --mode=cli --env="${a}/.env"`,{cwd:a}),s.success("Local server will be available in a couple of seconds");let i=(0,x.default)({text:"Waiting for the server to become available"}).start();await Y(`http://localhost:${t}/api/status`,3e4,1e3)?(await(0,B.default)(`http://localhost:${t}`),i.success(`App is running at http://localhost:${t}`)):i.error("Server failed to become available in time")}catch(t){console.error("Failed to start local server",t)}}},h=ye;var G=require("node:child_process");var we={command:"logs",description:"Listen for logs",handler:async()=>{(0,G.execSync)(`pm2 logs ${m}`,{stdio:"inherit"})}},U=we;var xe={command:"stop",description:"Stop the server",handler:v},Q=xe;var q=c(require("open")),Re={command:"open",description:"Open webapp",handler:async()=>{let e=r.getNumber("PORT");await(0,q.default)(`http://localhost:${e}`)}},z=Re;var X={name:"root",description:"Root module has no description",commands:[h,U,Q,z]};var Ce={command:"set <prop> <value>",description:"Set env value",module:"env",handler:async(e,t)=>{r.set(e,t),r.flush(),console.log(`Environment property set: ${e}`)}},Z=Ce;var be={command:"unset <prop>",description:"Remove env value",module:"env",handler:async e=>{r.unset(e),r.flush(),console.log(`Environment property unset: ${e}`)}},ee=be;var Pe={command:"list",description:"List env values",module:"env",handler:async()=>{console.table(r.values())}},te=Pe;var oe={name:"env",description:"Handle env variables",commands:[Z,ee,te]};var ne=[X,oe],re=h;var _e=P();_e.setMetadata({name:"dataramen",description:"A cozy web GUI for MySQL and PostgreSQL - built for developers who like to move fast and stay focused.",version:N().version}).setDefaultCommand(re).setModules(ne).start();
|
package/dist/code/server.js
CHANGED
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
left join pg_class on pg_attribute.attrelid = pg_class.oid
|
|
55
55
|
where
|
|
56
56
|
concat(pg_class.oid, '-', attnum) IN (${e.join(", ")})
|
|
57
|
-
limit 75;`;return(await t.query(r)).rows.reduce((a,n)=>(a[n.row_key]={table:n.relname,column:n.attname},a),{})},yt=async(e,t,r,o)=>{try{console.log(`[PG CONN] Query: ${e}`),console.log(`[PG CONN] Params: ${JSON.stringify(t,null,2)}`);let{rows:a,fields:n,command:s,rowCount:u}=await r.query({text:e,rowMode:"array",values:t});if(s==="UPDATE"||s==="INSERT"||s==="DELETE"){if(u!=null&&u>1&&o.allowBulkUpdate!==!0)throw new Error("[PG CONN] Bulk update performed without permission.");return{columns:[{column:"affectedRows",alias:"Affected rows",full:"affectedRows"}],rows:[[u]],query:e}}if(s==="SELECT"){let m=n.map(S=>`'${S.tableID}-${S.columnID}'`),c=await ho(m,r);return{columns:n.map(S=>{let p=c[`${S.tableID}-${S.columnID}`];return{column:p?.column||S.name,alias:S.name,table:p?.table||"",full:p?p.table+"."+p.column:S.name}}),rows:a,query:e}}throw new Error(`[PG CONN] Unsupported command: ${s}`)}catch(a){throw a instanceof i?a:new i(400,a.message)}},wo=async(e,t)=>{await e.query("BEGIN");try{let r=await t();return await e.query("COMMIT"),console.log("[PG CONN] Commit"),r}catch(r){throw await e.query("ROLLBACK"),console.log("[PG CONN] Rollback"),r}},So=async(e,t)=>{await e.query("BEGIN READ ONLY");try{let r=await t();return console.log("[PG CONN] Read only rollback"),await e.query("ROLLBACK"),r}catch(r){throw console.log("[PG CONN] Rollback"),await e.query("ROLLBACK"),r}},gt=async e=>{let t=await fo(e),r=!1,o=!1,a=async n=>(o||await t.query(`SET search_path TO ${e.schema}`),n());return{dbType:"postgres",dataSource:e,inspectSchema:()=>go(e,t),executeQuery:n=>a(()=>n.type==="SELECT"?So(t,()=>yt(n.sql,n.params,t,n)):wo(t,()=>yt(n.sql,n.params,t,n))),checkConnection:async()=>{},isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.end()}}};var M=async(e,t,r)=>{try{let o;if(t==="mysql")o=await ft(e);else if(t==="postgres")o=await gt(e);else throw new i(500,`Connection manager for ${t} not found`);return r.__connections?r.__connections.push(o):r.__connections=[o],o}catch(o){throw console.error(o),o instanceof i?o:o?.code==="ECONNREFUSED"?new i(500,"Failed to connect to the database"):new i(500,o.message)}};var ae=O(require("node:crypto"));var ht="aes-256-gcm",Eo=12,wt=()=>{let e=y.str("SYMM_ENCRYPTION_KEY");if(!e)throw new Error("Missing ENCRYPTION_KEY in environment variables.");let t=Buffer.from(e,"hex");if(t.length!==32)throw new Error("ENCRYPTION_KEY must be a 64-character hex string (256 bits).");return t},bo=e=>{let t=ae.default.randomBytes(Eo),r=wt(),o=ae.default.createCipheriv(ht,r,t),a=o.update(e,"utf8","hex");a+=o.final("hex");let n=o.getAuthTag();return{encrypted:a,iv:t.toString("hex"),tag:n.toString("hex")}},Io=({encrypted:e,iv:t,tag:r})=>{let o=wt(),a=ae.default.createDecipheriv(ht,o,Buffer.from(t,"hex"));a.setAuthTag(Buffer.from(r,"hex"));let n=a.update(e,"hex","utf8");return n+=a.final("utf8"),n},ne={encrypt:bo,decrypt:Io};var k=(e,t=!1)=>{if(t){let r=ne.decrypt({encrypted:e.dbPassword,tag:e.dbPasswordTag,iv:e.dbPasswordIv});return{url:e.dbUrl,user:e.dbUser,database:e.dbDatabase,password:r,port:e.dbPort,schema:e.dbSchema}}return{url:e.dbUrl,user:e.dbUser,database:e.dbDatabase,password:e.dbPassword,port:e.dbPort,schema:e.dbSchema}};var St=[{value:"=",label:"equals"},{value:"<>",label:"not equal"},{value:">",label:"greater than"},{value:">=",label:"greater than or equal"},{value:"<",label:"less than"},{value:"<=",label:"less than or equal"},{value:"LIKE",label:"like"},{value:"NOT LIKE",label:"not like"},{value:"CONTAINS",label:"contains"},{value:"NOT CONTAINS",label:"not contains"},{value:"IN",label:"in list"},{value:"NOT IN",label:"not in list"},{value:"IS NULL",label:"is null"},{value:"IS NOT NULL",label:"is not null"}],Ro=St.reduce((e,t)=>(e[t.value]=t.label,e),{}),jn=St.reduce((e,t)=>(e[t.label]=t.value,e),{}),W=e=>e.map(t=>({label:Ro[t],value:t})),Kn=W(["=","<>",">",">=","<","<=","IN","NOT IN","IS NULL","IS NOT NULL"]),Vn=W(["=","<>","LIKE","NOT LIKE","IN","NOT IN","IS NULL","IS NOT NULL","CONTAINS","NOT CONTAINS"]),zn=W(["=","<>","IS NULL","IS NOT NULL"]),Jn=W(["=","<>",">",">=","<","<=","IS NULL","IS NOT NULL"]),Xn=W(["IS NULL","IS NOT NULL"]),Zn=W(["IN","NOT IN"]),Co=["char","varchar","binary","varbinary","blob","text","enum","set","character","character varying","text","citext","uuid","xml","json","jsonb"],No=new Set(Co),se=e=>No.has(e),Ao=["integer","smallint","decimal","numeric","float","real","double precision","int","smallint","integer","bigint","decimal","numeric","real","double precision","serial","bigserial","money"],Po=new Set(Ao),Et=e=>Po.has(e);var es=["date","datetime","timestamp","timestamptz"].reduce((e,t)=>(e[t]=!0,e),{});var Ae={read_only:10,editor:20,admin:30,owner:40};var P=e=>e.startsWith("'")&&e.endsWith("'")||e.startsWith('"')&&e.endsWith('"')?e.slice(1,-1):e;var bt={operator:"LIKE",parse:e=>{let t=e.match(/^LIKE\s*["'](.*)["']$/i);if(t)return[{value:P(t[1])}]},stringify:e=>`LIKE "%${e[0]?.value}%"`},It={operator:"NOT LIKE",parse:e=>{let t=e.match(/^NOT LIKE\s*["'](.*)["']$/i);if(t)return[{value:P(t[1])}]},stringify:e=>`NOT LIKE "%${e[0]?.value}%"`},Rt={operator:"CONTAINS",parse:e=>{let t=e.match(/^CONTAINS\s*["'](.*)["']$/i);if(t)return[{value:P(t[1])}]},stringify:(e,t)=>se(t)?`${e[0]?.value}`:`CONTAINS "%${e[0]?.value}%"`},Ct={operator:"NOT CONTAINS",parse:e=>{let t=e.match(/^NOT CONTAINS\s*["'](.*)["']$/i);if(t)return[{value:P(t[1])}]},stringify:e=>`NOT CONTAINS "%${e[0]?.value}%"`};function At(e){return e===""?[]:Oo(e).map(_o)}function Oo(e){let t=[],r=0,o="",a=!1,n=!1;for(;r<e.length;){let s=e[r];if((a||n)&&s==="\\"){o+=e[r+1],r+=2;continue}if(s==="'"&&!n){a=!a,o+=s,r++;continue}if(s==='"'&&!a){n=!n,o+=s,r++;continue}if(s===","&&!a&&!n){t.push(o.trim()),o="",r++;continue}o+=s,r++}if(o.trim()!==""&&t.push(o.trim()),a||n)throw new Error("Unterminated string literal");return t}function _o(e){if(e.startsWith("'")&&e.endsWith("'"))return{value:Nt(e.slice(1,-1),"'")};if(e.startsWith('"')&&e.endsWith('"'))return{value:Nt(e.slice(1,-1),'"')};let t=Number(e);if(!Number.isNaN(t))return{value:t};throw new Error(`Invalid literal: ${e}`)}function Nt(e,t){return e.replace(/\\(.)/g,(r,o)=>o)}var Pt={operator:"IN",parse:e=>{let t=e.match(/^in\s*\((.*)\)$/i);if(t)return At(t[1])},stringify:e=>`IN (${e?.map(t=>`"${t.value}"`).join(", ")})`},Ot={operator:"NOT IN",parse:e=>{let t=e.match(/^not\s+in\s*\((.*)\)$/i);if(t)return At(t[1])},stringify:e=>`NOT IN (${e?.map(t=>`"${t.value}"`).join(", ")})`};var _t={operator:"=",parse:e=>{let t=e.match(/^=\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:(e,t)=>Et(t)?`${e[0]?.value}`:`= ${e[0]?.value}`},xt={operator:"!=",parse:e=>{let t=e.match(/^!=\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`!= ${e[0]?.value}`},vt={operator:"<>",parse:e=>{let t=e.match(/^<>\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`<> ${e[0]?.value}`},Dt={operator:">",parse:e=>{let t=e.match(/^>\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`> ${e[0]?.value}`},Ut={operator:">=",parse:e=>{let t=e.match(/^>=\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`>= ${e[0]?.value}`},Lt={operator:"<",parse:e=>{let t=e.match(/^<\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`< ${e[0]?.value}`},qt={operator:"<=",parse:e=>{let t=e.match(/^<=\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`<= ${e[0]?.value}`};var Mt={operator:"IS NULL",parse:e=>{if(/^is\s+null$/i.test(e))return[]},stringify:()=>"IS NULL"},kt={operator:"IS NOT NULL",parse:e=>{if(/^is\s+not\s+null$/i.test(e))return[]},stringify:()=>"IS NOT NULL"};var xo=[bt,Rt,It,Ct,Pt,Ot,_t,xt,vt,Ut,Dt,qt,Lt,Mt,kt];function vo(e){let t=e.trim();for(let r of xo){let o=r.parse(t);if(o)return{operator:r.operator,value:o}}}var Qt={parse:vo};var E=e=>{let t=Ae[e];return r=>Ae[r.currentTeamRole]>=t},Bt=async e=>{let t=e.routeOptions.config.requireRole;if(t&&!t(e.user))throw new i(403,"You are not authorized to perform this action")};var Ft=T(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=d(t),o=await b.findOne({where:{id:r}});if(!o)throw new i(404,"Data source not found");return{data:o}}}),e.route({method:"get",url:"/",handler:async t=>{let{teamId:r}=U(t);return{data:await b.find({where:{team:{id:r}},order:{createdAt:"DESC"}})}}}),e.route({url:"/",method:"post",config:{requireRole:E("admin")},handler:async t=>{let{teamId:r,ownerId:o,...a}=f(t,mt),n=b.create({...a,allowUpdate:!!a.allowUpdate,allowInsert:!!a.allowInsert,team:{id:r},owner:{id:o}}),s=await M(k(n),n.dbType,t);try{await s.checkConnection()}catch{throw new i(400,"Cannot connect to the database, please check datasource configuration")}let{tag:u,iv:m,encrypted:c}=ne.encrypt(n.dbPassword);return n.dbPassword=c,n.dbPasswordIv=m,n.dbPasswordTag=u,{data:await b.save(n)}}}),e.route({method:"put",url:"/:id",config:{requireRole:E("admin")},handler:async t=>{let{id:r}=d(t),o=f(t),a=await b.findOneBy({id:r});if(!a)throw new i(404,"Data source not found");let n=b.merge(a,o);return await b.save(n),{data:n}}}),e.route({method:"delete",url:"/:id",config:{requireRole:E("admin")},handler:async(t,r)=>h.transaction(async()=>{let{id:o}=d(t);await Promise.all([v.delete({datasource:{id:o}}),I.delete({dataSource:{id:o}})]),await b.delete({id:o})})}),e.route({method:"post",url:"/:id/inspect",handler:async(t,r)=>{let{id:o}=d(t),a=await b.findOne({where:{id:o},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser"]});if(!a)throw new Error("Data source not found");a.status="INSPECTING",await b.save(a);let s=await(await M(k(a,!0),a.dbType,t)).inspectSchema();await v.delete({datasource:{id:o}}),await v.insert(s.sort().map(u=>v.create({tableName:u.tableName,columns:u.columns,datasource:{id:o}}))),a.status="READY",a.lastInspected=new Date,await b.save(a)}}),e.route({method:"get",url:"/:id/inspections",handler:async t=>{let{id:r}=d(t);return{data:await v.find({where:{datasource:{id:r}}})}}})});var B=require("typeorm"),$t=T(e=>{e.route({method:"get",url:"/team/:teamId/datasources",handler:async t=>{let{teamId:r}=d(t);return{data:await b.find({where:{team:{id:r}},order:{name:"ASC"},select:{id:!0,name:!0,updatedAt:!0,dbType:!0,description:!0,allowInsert:!0,allowUpdate:!0}})}}}),e.route({method:"get",url:"/team/:teamId/queries",handler:async t=>{let r=d(t),o=U(t),a=r.teamId||t.user.currentTeamId,n=Number(o.size)||20,s=Number(o.page)||0,u=o.nameFilter?.length?{name:(0,B.Raw)(p=>`LOWER(${p}) LIKE :search`,{search:`%${o.nameFilter.toLowerCase()}%`})}:void 0,m=await D.find({where:[{isPersonal:!1,team:{id:a},query:u},{isPersonal:!0,team:{id:a},query:u,user:{id:t.user.id}}],relations:{query:{dataSource:!0}},take:n+1,skip:s*n,select:{id:!0,query:{id:!0,name:!0,updatedAt:!0,dataSource:{name:!0,dbType:!0}}},order:{query:{updatedAt:"DESC"}}}),c=m.length>n;return c&&m.pop(),{data:m.map(p=>({name:p.query.name,id:p.query.id,updatedAt:p.query.updatedAt,savedQueryId:p.id,datasourceName:p.query.dataSource.name,datasourceType:p.query.dataSource.dbType})),hasMore:c}}}),e.route({method:"get",url:"/team/:teamId/count-saved-queries",handler:async t=>{let o=d(t).teamId||t.user.currentTeamId;return{data:await D.count({where:[{isPersonal:!1,team:{id:o}},{isPersonal:!0,team:{id:o},user:{id:t.user.id}}],select:{id:!0}})}}}),e.route({method:"get",url:"/team/:teamId/query",handler:async t=>{let{teamId:r}=d(t),{search:o,size:a,selectedDataSources:n}=U(t),s=o.length>3?parseInt(a)||20:8,u={};n?.length&&(u.id=(0,B.In)(n));let[m,c,S]=await Promise.all([v.find({where:{tableName:(0,B.Raw)(l=>`LOWER(${l}) LIKE :search`,{search:`%${o.toLowerCase()}%`}),datasource:u},relations:{datasource:!0},select:{id:!0,tableName:!0,datasource:{name:!0,id:!0}},order:{tableName:"ASC"},take:s}),A.find({where:{searchString:(0,B.Like)(`%${o.toLowerCase()}%`),team:{id:r},user:{id:t.user.id},dataSource:u},relations:{dataSource:!0},select:{id:!0,name:!0,updatedAt:!0,dataSource:{id:!0,name:!0}},order:{updatedAt:"ASC"},take:s}),D.find({where:{searchString:(0,B.Like)(`%${o.toLowerCase()}%`),team:{id:r},query:{dataSource:u}},relations:{query:{dataSource:!0}},select:{id:!0,updatedAt:!0,query:{id:!0,name:!0,dataSource:{name:!0}}},order:{updatedAt:"ASC"},take:s})]),p=[];return m.forEach(l=>{p.push({name:l.tableName,id:l.id,dataSourceName:l.datasource?.name||"--",dataSourceId:l.datasource?.id||"--",type:"table"})}),c.forEach(l=>{p.push({name:l.name,id:l.id,dataSourceName:l.dataSource?.name||"--",dataSourceId:l.dataSource?.id||"--",type:"tab"})}),S.forEach(l=>{p.push({name:l.query.name,id:l.query.id,dataSourceName:l.query.dataSource?.name||"--",dataSourceId:l.query.dataSource?.id||"--",type:"query"})}),{data:p}}}),e.route({method:"get",url:"/team/:teamId/tabs-history",handler:async t=>{let{teamId:r}=d(t),o=U(t),a=Number(o.page),n=Number(o.size),s=t.user.id,u=await A.find({where:{team:{id:r},user:{id:s},archived:o.archived?o.archived==="true":void 0},relations:{dataSource:!0},order:{updatedAt:"DESC"},take:n+1,skip:a*n}),m=!1;return u.length>n&&(u.pop(),m=!0),{data:u.map(c=>({name:c.name,id:c.id,updatedAt:c.updatedAt,archived:c.archived,createdAt:c.createdAt,dataSourceId:c.dataSource?.id,dataSourceName:c.dataSource?.name,dataSourceType:c.dataSource?.dbType})),hasMore:m}}})});var Wt=T(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=d(t),o=await I.findOne({where:{id:r},select:{dataSource:{id:!0}},relations:{dataSource:!0}});return o?{data:o}:{status:404,data:"Query not found"}}}),e.route({method:"post",url:"/",config:{requireRole:E("editor")},handler:async t=>{let r=f(t),o=await b.findOne({where:{id:r.dataSourceId},relations:{team:!0}});return{data:await I.save(I.create({name:r.name,opts:r.opts,team:{id:o?.team.id},dataSource:{id:r.dataSourceId},user:{id:t.user.id}}))}}}),e.route({method:"patch",url:"/:id",config:{requireRole:E("editor")},handler:async t=>{let{id:r}=d(t),o=f(t);if(!(await I.update(r,o)).affected)throw new i(404,"Query not found");return{data:await I.findOneBy({id:r})}}}),e.route({method:"delete",url:"/:id",config:{requireRole:E("editor")},handler:async t=>h.transaction(async()=>{let{id:r}=d(t);if(!(await I.delete({id:r})).affected)return{status:404,data:"Query not found"}})})});var Ht=e=>se(e)?"CONTAINS":"=",Oe=(e,t)=>{let r=[];for(let o of e)if(!(!o.column?.length||!o.value?.length||o.isEnabled===!1))if(o.isAdvanced){let a=Qt.parse(o.value);if(!a)throw new i(400,`Invalid value for '${o.column}': ${o.value}`);r.push({value:a.value,column:o.column,operator:a.operator||Ht(t(o.column)),fn:o.fn})}else r.push({value:o.value?[{value:o.value}]:[],column:o.column,operator:Ht(t(o.column)),fn:o.fn});return r},Yt=e=>{let t=[e.table];return e.joins&&e.joins.forEach(({table:r})=>t.push(r)),t},Pe=e=>({column:e.value,fn:e.fn,distinct:e.distinct}),Gt=(e,t,r)=>{let o=[];return t.length>0||r.length>0?o.push(...t.map(Pe),...r.map(Pe)):e.length>0&&o.push(...e.map(Pe)),o},jt=(e,t,r)=>t.map((o,a)=>({...o,full:e[a].fn?e[a].column:o.full,type:r(o.full),fn:e[a].fn}));var _e=require("typeorm"),Kt=new _e.DataSource({type:"mysql"}),Vt=new _e.DataSource({type:"postgres"}),H=e=>{switch(e){case"postgres":return Vt.createQueryBuilder();case"mysql":return Kt.createQueryBuilder();default:throw new Error("Unsupported database connection")}},ie={postgres:Vt.driver,mysql:Kt.driver};var V=(e,t,r)=>{let{column:o,operator:a,value:n}=e,s="_"+t;switch(a){case"IS NULL":case"IS NOT NULL":return[`${o} ${a}`,{value:void 0}];case"IN":case"NOT IN":return[`${o} ${a} (:...${s})`,{[s]:n?.map(c=>c.value)}];case"LIKE":case"CONTAINS":return[`${o} ${r==="postgres"?"ILIKE":"LIKE"} :${s}`,{[s]:a==="CONTAINS"?`%${n?.[0].value}%`:n?.[0].value}];case"NOT LIKE":case"NOT CONTAINS":return[`${o} ${r==="postgres"?"NOT ILIKE":"NOT LIKE"} :${s}`,{[s]:a==="NOT CONTAINS"?`%${n?.[0].value}%`:n?.[0].value}];default:return[`${o} ${a} :${s}`,{[s]:n?.[0]?.value}]}};var zt=e=>{let t=ie[e];return r=>{if(r.includes(".")){let[o,a]=r.split(".");return t.escape(o)+"."+t.escape(a)}return r==="*"?r:t.escape(r)}};var Jt=["SUM","COUNT","AVG","MAX","MIN"],Do=["YEAR","MONTH","DAY",...Jt],Uo=Do.reduce((e,t)=>(e[t]=!0,e),{}),Lo=Jt.reduce((e,t)=>(e[t]=!0,e),{}),Xt=e=>Uo[e],Zt=e=>Lo[e];var ue=(e,t,r=!1)=>r?`${t}(distinct ${e})`:`${t}(${e})`,er={YEAR:e=>`EXTRACT(YEAR FROM ${e})`,MONTH:e=>`EXTRACT(MONTH FROM ${e})`,DAY:e=>`EXTRACT(DAY FROM ${e})`,SUM:(e,t,r)=>r?`COALESCE(SUM(distinct ${e}), 0)`:`COALESCE(SUM(${e}), 0)`,AVG:ue,MAX:ue,MIN:ue,COUNT:ue};var ce=(e,t,r=!1)=>r?`${t}(distinct ${e})`:`${t}(${e})`,tr={YEAR:e=>`YEAR(${e})`,MONTH:e=>`MONTH(${e})`,DAY:e=>`DAY(${e})`,SUM:(e,t,r)=>r?`coalesce(${t}(distinct ${e}), 0)`:`coalesce(${t}(${e}), 0)`,AVG:ce,MAX:ce,MIN:ce,COUNT:ce};var qo=e=>{let t=[];return e.fn&&t.push(e.fn),e.distinct&&t.push("distinct"),t.push(e.column),t.join(" ")},Mo=e=>{let t=zt(e),r=e==="postgres"?er:tr;return o=>o.fn&&Xt(o.fn)?r[o.fn](t(o.column),o.fn,o.distinct):t(o.column)};function rr(e,t){let r=H(t.dbType).from(e,e),o=!1,a=0,n=Mo(t.dbType),s={};return{setColumns(u){u.forEach(m=>{let c=qo(m);s[c]=c,r.addSelect(n(m),c)})},setLimit:u=>{r.limit(u),o=!0},setOffset(u){r.skip(u)},addOrderBy(u,m){r.addOrderBy(u,m)},addJoin({table:u,alias:m,on:c}){r.leftJoin(u,m||u,c)},addWhere(u){let[m,c]=V({...u,operator:u.operator||"=",column:n(u)},++a,t.dbType);r.andWhere(m,c)},addHaving(u){let[m,c]=V({...u,operator:u.operator||"=",column:n(u)},++a,t.dbType);r.andHaving(m,c)},addGroupBy(u){r.addGroupBy(n(u))},hasAlias(u){return!!s[u]},build(){o||r.limit(50);let[u,m]=r.getQueryAndParameters();return{sql:u,params:m}}}}var or=(e,t)=>{let r=H(t.dbType).update(e),o=0;return{addWhere(a){let[n,s]=V(a,++o,t.dbType);r.andWhere(n,s)},setParams(a){let n={};for(let[s,u]of Object.entries(a)){let m=`${u}`;m.startsWith("=")?n[s]=()=>m.substring(1):n[s]=m}r.set(a)},build(){let[a,n]=r.getQueryAndParameters();return{sql:a,params:n}}}};var ar=(e,t)=>{let r=H(t.dbType).insert().into(e);return{setValues(o){let a={};for(let[n,s]of Object.entries(o)){let u=`${s}`;u.startsWith("=")?a[n]=()=>u.substring(1):a[n]=u}r.values([a])},build(){let[o,a]=r.getQueryAndParameters();return{sql:o,params:a}}}};var xe=rr,nr=or,sr=ar;var ir=require("typeorm"),ur=async(e,t)=>{let r=await v.find({where:{tableName:(0,ir.In)(t),datasource:{id:e}}}),o=[];for(let s of r)if(s.columns)for(let u of s.columns)o.push({column:u.name,table:s.tableName||"",full:`${s.tableName}.${u.name}`,type:u.type});let a=o.reduce((s,u)=>(s[u.full]=u.type,s),{});return{getAllColumns(){return o},getColumnType:s=>a[s],hasColumn(s){return!!a[s]||s==="*"}}};async function ko(e,t,r){return I.save(I.create({user:{id:e},team:{id:t},dataSource:{id:r.datasourceId},name:r.name,opts:r.opts}))}var me=async(e,t)=>{let{datasourceId:r,size:o=20,page:a}=t,{table:n,joins:s,groupBy:u,orderBy:m}=t.opts,c=await le(r);if(!c)throw new i(404,"Datasource not found");let S=Gt(t.opts.columns,t.opts.groupBy,t.opts.aggregations),p=Yt(t.opts),l=await ur(r,p),C=l.getAllColumns(),L;S&&S.length>0?L=S:L=C.map(R=>({column:R.full})),L.forEach(R=>{if(!l.hasColumn(R.column))throw new i(400,`Invalid column ${R.column}`)});let Hr=ko(e.user.id,e.user.currentTeamId,t),x=xe(n,c);x.setLimit(o+1),x.setOffset(o*a),x.setColumns(L),s&&s.forEach(x.addJoin),m.length>0&&m.forEach(({column:R,direction:Kr})=>{x.hasAlias(R)&&x.addOrderBy(ie[c.dbType].escape(R),Kr)}),u&&u.length>0&&u.forEach(R=>{l.hasColumn(R.value)&&x.addGroupBy({column:R.value,fn:R.fn,distinct:R.distinct})}),Oe(t.opts.filters,l.getColumnType).forEach(R=>{R.fn&&Zt(R.fn)?x.addHaving(R):x.addWhere(R)});let{sql:Yr,params:Gr}=x.build(),J=await(await M(k(c,!0),c.dbType,e)).executeQuery({sql:Yr,params:Gr,type:"SELECT",allowBulkUpdate:!1}),De=J.rows.length>o;De&&J.rows.pop();let{id:jr}=await Hr;return{...J,queryHistoryId:jr,tables:p,allColumns:C,columns:jt(L,J.columns,l.getColumnType),hasMore:De}},cr=async(e,t)=>{let r=await le(t.dataSourceId);if(!r)throw new i(400,"Invalid datasource");let o=await M(k(r,!0),r.dbType,e),a=xe(t.table,r);a.setLimit(2);for(let[m,c]of Object.entries(t.props))a.addWhere({value:[{value:c}],column:m});let{sql:n,params:s}=a.build(),u=await o.executeQuery({sql:n,params:s,type:"SELECT",allowBulkUpdate:!1});if(u.rows.length>1)throw new i(400,"Found multiple rows for given query");if(u.rows.length<1)throw new i(404,"Entity not found");return{entity:u.rows[0],columns:u.columns,sql:n}},mr=async(e,t)=>{let r=await le(t.datasourceId);if(!r)throw new i(404,"Data source not found");if(!r.allowUpdate)throw new i(403,"This datasource does not allow update operations");let o=nr(t.table,r);o.setParams(t.values),Oe(t.filters,()=>"=").forEach(u=>{o.addWhere(u)});let{sql:a,params:n}=o.build();return(await M(k(r,!0),r.dbType,e)).executeQuery({sql:a,params:n,type:"UPDATE",allowBulkUpdate:!1})},lr=async(e,t)=>{let r=await le(t.datasourceId);if(!r)throw new i(404,"Data source not found");if(!r.allowInsert)throw new i(403,"This datasource does not allow insert operations");let o=sr(t.table,r);o.setValues(t.values);let{sql:a,params:n}=o.build();return(await M(k(r,!0),r.dbType,e)).executeQuery({sql:a,type:"INSERT",params:n,allowBulkUpdate:!1})};async function le(e){return b.findOne({where:{id:e},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser","allowUpdate","allowInsert"]})}var dr=e=>{},Qo=["--",";","DROP","drop"],pr=([e,t])=>{if(typeof t=="string"&&t.startsWith("=")){let r=t;Qo.forEach(o=>{if(r.includes(o))throw new i(400,"Invalid input value for "+e)})}},fr=e=>{if(!e.table)throw new i(400,"Table is required");Object.entries(e.values).forEach(pr)},yr=e=>{if(!e.table)throw new i(400,"Table is required");Object.entries(e.values).forEach(pr)};var Tr=T(e=>{e.route({method:"post",url:"/:dsId/select",handler:async t=>{let r=f(t,dr);return{data:await me(t,r)}}}),e.route({method:"get",url:"/:dsId/entity/:table",handler:async t=>{let{dsId:r,table:o}=d(t),a=U(t);return{data:await cr(t,{table:o,dataSourceId:r,props:a})}}}),e.route({method:"post",url:"/:dsId/insert",config:{requireRole:E("editor")},handler:async t=>{let r=f(t,fr);return{data:await lr(t,r)}}}),e.route({method:"post",url:"/:dsId/update",config:{requireRole:E("editor")},handler:async t=>{let r=f(t,yr);return{data:await mr(t,r)}}})});var gr=T(e=>{e.get("/",{config:{isPublic:!0}},async()=>({data:{active:!0,version:y.str("SERVER_VERSION")}}))});var hr=T(e=>{e.route({method:"get",url:"/:id/users",handler:async t=>{let{id:r}=d(t),o=await q.findOne({where:{id:r},relations:{users:{user:!0}}});if(!o)throw new i(404,"Team not found");return{data:o.users.map(a=>({role:a.role,id:a.user.id,name:a.user.username}))}}}),e.route({method:"post",url:"/",config:{requireRole:E("editor")},handler:async t=>h.transaction(async()=>{let r=t.user.id,o=f(t),a=w.create();a.id=r;let n=q.create(o);await q.save(n);let s=N.create({user:a,team:n});return await N.save(s),{data:n}})}),e.route({method:"patch",url:"/:id/user-role",config:{requireRole:E("admin")},handler:async t=>{let{id:r}=d(t),{role:o,userId:a}=f(t,({role:s})=>{if(s==="owner")throw new i(400,"Only one owner is allowed")});if((await N.findOneBy({user:{id:a},team:{id:r}}))?.role==="owner")throw new i(400,"Cannot change owner role");await N.update({user:{id:a},team:{id:r}},{role:o})}}),e.route({method:"delete",url:"/:id",config:{requireRole:E("admin")},handler:async t=>h.transaction(async()=>{let{id:r}=d(t),{userId:o}=U(t);if((await N.findOneBy({user:{id:o},team:{id:r}}))?.role==="owner")throw new i(400,"Cannot delete team owner");await w.update(o,{currentTeam:null}),await N.delete({user:{id:o},team:{id:r}}),await w.delete({id:o})})})});var ve=O(require("bcryptjs")),z=async e=>{let t=await ve.default.genSalt(10);return ve.default.hash(e,t)};var wr=T(e=>{e.route({method:"get",url:"/",handler:async t=>{let r=await w.findOne({where:{id:t.user.id},relations:{currentTeam:{team:!0}}});if(!r)throw new i(404,"User not found");return{data:{id:r.id,teamId:r.currentTeam?.team.id,teamName:r.currentTeam?.team.name,teamRole:r.currentTeam?.role,username:r.username}}}}),e.route({method:"patch",url:"/",handler:async t=>{let r=t.user.id,o=f(t);if(o.password&&(o.password=await z(o.password)),!(await w.update(r,o)).affected)throw new i(404,"User not found");let n=await w.findOne({where:{id:r},relations:{currentTeam:{team:!0}}});return{data:{id:n?.id,teamId:n?.currentTeam?.team.id,teamName:n?.currentTeam?.team.name,teamRole:n?.currentTeam?.role,username:n?.username}}}}),e.route({method:"post",url:"/",config:{requireRole:E("admin")},handler:async t=>h.transaction(async()=>{let r=f(t),o=await z(r.password),a=await w.save(w.create({username:r.username,password:o})),n=await N.save(N.create({role:"read_only",team:{id:r.teamId},user:{id:a.id}}));await w.update(a.id,{currentTeam:{id:n.id}})})})});var Sr=T(e=>{e.route({method:"get",url:"/",handler:async t=>{let r=t.user.id,o=await $.findOneBy({user:{id:r}});return o||(o=await $.save($.create({user:{id:r}}))),{data:o}}}),e.route({method:"patch",url:"/",handler:async t=>{let{settings:r}=f(t);if(!r.id)throw new i(400,"Settings id is required!");if(!(await $.update(r.id,r)).affected)throw new i(404,"You do not own these settings!");return{data:await $.findOneBy({id:r.id})}}})});function Y(e,...t){let r=[...t];if(e.searchAll&&r.push(e.searchAll),e.filters)for(let o of e.filters)o.value&&r.push(o.value);return r.map(o=>o.toLowerCase()).join(",")}var Er=T(e=>{e.route({method:"post",url:"/",config:{requireRole:E("editor")},handler:async t=>{let r=f(t),o=await I.findOne({where:{id:r.queryId}});if(!o)throw new i(400,"Query not found");let a=await D.save(D.create({isPersonal:!1,team:{id:t.user.currentTeamId},user:{id:t.user.id},query:{id:r.queryId},searchString:Y(o.opts,r.name)}));return await I.update(r.queryId,{name:r.name}),{data:a}}}),e.route({method:"delete",url:"/:id",config:{requireRole:E("editor")},handler:async t=>{let{id:r}=d(t);if(!(await D.delete({id:r})).affected)return{status:404,data:"Query not found"}}}),e.route({method:"patch",url:"/:id",handler:async t=>await h.transaction(async()=>{let{id:r}=d(t),o=f(t,s=>{if(!s.name)throw new i(400,"Name is required")}),a=await D.findOne({where:{id:r},relations:{query:!0}});if(!a)throw new i(400,"Query not found");let n=Y(a.query.opts,o.name);return await Promise.all([D.update({id:r},{searchString:n}),I.update({id:a.query.id},{name:o.name})]),{data:!0}})})});var br=e=>{if(!e.queryId&&!(e.opts&&e.name))throw new i(400,"Either queryId or name and opts are required")};var Ir=T(e=>{e.route({method:"get",url:"/",handler:async t=>{let{currentTeamId:r,id:o}=t.user;return{data:(await A.find({where:{team:{id:r},user:{id:o},archived:!1},select:["id","name"]})).map(n=>({name:n.name,id:n.id}))}}}),e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=d(t),{currentTeamId:o,id:a}=t.user,n=await A.findOne({where:{id:r,team:{id:o},user:{id:a}}});if(!n)throw new i(404,"Not Found");return{data:n}}}),e.route({method:"post",url:"/",handler:async t=>{let{opts:r,name:o,queryId:a}=f(t,br),n,s,u=o;if(r)s=r.dataSourceId,n=r;else{let c=await I.findOne({where:{id:a},relations:{dataSource:!0}});if(!c)throw new i(404,"Query not Found");s=c.dataSource.id,n={table:c.opts.table,filters:c.opts.filters,joins:c.opts.joins,orderBy:c.opts.orderBy,columns:c.opts.columns,groupBy:c.opts.groupBy,searchAll:c.opts.searchAll,aggregations:c.opts.aggregations,dataSourceId:c.dataSource.id,page:0,size:50},o||(u=c.name)}return{data:await A.save(A.create({name:u||new Date().toISOString(),opts:n,dataSource:{id:s},user:{id:t.user.id},team:{id:t.user.currentTeamId}}))}}}),e.route({method:"post",url:"/:id/run",handler:async t=>{let{id:r}=d(t),o=f(t),a=await A.findOne({where:{id:r},relations:{user:!0}});if(!a)throw new i(404,"Not found");if(a.user?.id!==t.user.id)throw new i(404,"Not found");return o&&A.update(r,{opts:o,searchString:Y(o,a.name),updatedAt:new Date}),{data:{result:await me(t,{datasourceId:o.dataSourceId,size:o.size,name:a.name,page:o.page,opts:{table:o.table,filters:o.filters,joins:o.joins,orderBy:o.orderBy,columns:o.columns,groupBy:o.groupBy,searchAll:o.searchAll,aggregations:o.aggregations}})}}}}),e.route({method:"patch",url:"/:id",handler:async t=>{let{id:r}=d(t),o=f(t),a=await A.findOne({where:{id:r,user:{id:t.user.id}}});if(!a)throw new i(404,"Not Found");let n=a.searchString;return o.name&&(n=Y(a.opts,o.name)),await A.update(r,{...o,searchString:n}),{data:{id:r}}}}),e.route({method:"delete",url:"/:id",handler:async t=>{let{id:r}=d(t),o=t.user.id;return await A.delete({id:r,user:{id:o}}),{data:!0}}})});var Nr=require("node:crypto");var Rr=require("node:crypto"),Cr={teamName:"Default Team",username:"admin"},Bo=async()=>{let e=await q.findOneBy({});return e||q.save(q.create({name:Cr.teamName}))},de=async e=>{let t=await N.findOne({where:{role:"owner"},relations:{user:!0}});if(t)return t.user;let r=await Bo(),o=await z(e?.password||(0,Rr.randomBytes)(32).toString("hex")),a=await w.save(w.create({username:e?.name||Cr.username,password:o})),n=await N.save(N.create({user:a,team:r,role:"owner"}));return await w.update(a.id,{currentTeam:n}),a};var pe={setupAccessToken:void 0},Ar=()=>(pe.setupAccessToken=(0,Nr.randomBytes)(32).toString("hex"),pe.setupAccessToken),Fo=e=>{if(!pe.setupAccessToken)throw new i(400,"Setup already performed");if(!e||e!==pe.setupAccessToken)throw new i(400,"Invalid setup access token")},F=async()=>_.skipAuth?!1:await w.count()<1,Pr=async e=>{Fo(e.setupAccessToken),await de({name:e.userName,password:e.userPassword})};var Or=T(e=>{e.route({method:"get",url:"/client.config.js",handler:(t,r)=>{let o={skipAuth:_.skipAuth,modeName:_.name,usesCustomDb:Qe(),serverVersion:y.str("SERVER_VERSION","--")};return r.type("application/javascript").send(`window.__CLIENT_CONFIG__ = ${JSON.stringify(o)};`)}}),e.route({method:"get",url:"/",handler:async(t,r)=>await F()?r.redirect("/setup"):r.sendFile("index.html")}),e.route({method:"get",url:"/setup",handler:async(t,r)=>await F()?r.sendFile("setup.html"):r.redirect("/")})});var _r=e=>{if(!e.setupAccessToken)throw new i(400,"Invalid setup access token");if(!e.userPassword||e.userPassword.length<8)throw new i(400,"Password should be at least 8 chars long");if(!e.userName)throw new i(400,"User name is required")};var xr=T(e=>{e.route({method:"post",url:"/",config:{isPublic:!0},handler:async t=>{if(!await F())throw new i(400,"Setup has already been completed");let o=f(t,_r);return await Pr(o),{data:!0}}})});var $o=[[Or,"/"],[ct,"/api/auth"],[Ft,"/api/data-sources"],[$t,"/api/project"],[Wt,"/api/queries"],[Tr,"/api/runner"],[gr,"/api/status"],[hr,"/api/teams"],[wr,"/api/users"],[Sr,"/api/user-settings"],[Er,"/api/saved-queries"],[Ir,"/api/workbench-tabs"],[xr,"/api/setup"]],vr=e=>{for(let[t,r]of $o)e.register(t,{prefix:r}),console.log("Registered "+r)};var Wo=e=>e.routeOptions.config.isPublic?!0:!e.url.startsWith("/api/"),Ho=async()=>N.findOne({where:{role:"owner"},relations:{user:!0,team:!0}}),Yo=async e=>{let t=await Ho();if(!t)throw new i(401,"User is not part of a team");e.user={id:t.user.id,currentTeamId:t.team.id,currentTeamRole:t.role}},Go=async e=>{let t=e.headers.authorization;if(!t)throw new i(401,"Missing auth token");let[r,o]=t.split(" "),{userId:a}=await nt(o),n=await w.findOne({where:{id:a},select:{id:!0,currentTeam:{role:!0,team:{id:!0}}},relations:{currentTeam:{team:!0}}});if(!n)throw new i(401,"Unauthorized");e.user={id:a,currentTeamId:n.currentTeam.team.id,currentTeamRole:n.currentTeam.role}},Dr=async e=>{Wo(e)||(_.skipAuth?await Yo(e):await Go(e))};var Ur=(e,t)=>{e.__connections&&e.__connections.forEach(r=>{r.close()})};var Lr=e=>{e.addHook("onRequest",Dr),e.addHook("onRequest",Bt),e.addHook("onResponse",Ur)};var qr=e=>{e.setNotFoundHandler((t,r)=>{if(t.raw.url?.startsWith("/api/")){r.code(404).send({error:"API route not found"});return}r.sendFile("index.html")}),e.setErrorHandler((t,r,o)=>{console.error(t),t instanceof i?o.status(t.status).send({error:t.message}):o.status(500).send({error:"Internal Server Error"})})};var Mr=O(require("@fastify/cookie")),kr=O(require("@fastify/cors"));var Qr=O(require("@fastify/static")),Br=require("node:path"),Fr=e=>{e.register(Mr.default,{}),e.register(kr.default,{origin:G.allowedOrigins,methods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],credentials:!0}),e.register(Qr.default,{root:(0,Br.join)(__dirname,"web")})};(async function(){let t=(0,$r.default)({querystringParser:o=>Wr.default.parse(o)});if(ke(),Fr(t),Lr(t),vr(t),qr(t),await t.after(),await Xe(),t.listen({port:G.port,host:G.host},(o,a)=>{o&&(console.error(o),process.exit(1)),console.log(`Server listening at ${a}`)}),await F()){let o=Ar();console.log(`Setup access token:
|
|
57
|
+
limit 75;`;return(await t.query(r)).rows.reduce((a,n)=>(a[n.row_key]={table:n.relname,column:n.attname},a),{})},yt=async(e,t,r,o)=>{try{console.log(`[PG CONN] Query: ${e}`),console.log(`[PG CONN] Params: ${JSON.stringify(t,null,2)}`);let{rows:a,fields:n,command:s,rowCount:u}=await r.query({text:e,rowMode:"array",values:t});if(s==="UPDATE"||s==="INSERT"||s==="DELETE"){if(u!=null&&u>1&&o.allowBulkUpdate!==!0)throw new Error("[PG CONN] Bulk update performed without permission.");return{columns:[{column:"affectedRows",alias:"Affected rows",full:"affectedRows"}],rows:[[u]],query:e}}if(s==="SELECT"){let m=n.map(S=>`'${S.tableID}-${S.columnID}'`),c=await ho(m,r);return{columns:n.map(S=>{let p=c[`${S.tableID}-${S.columnID}`];return{column:p?.column||S.name,alias:S.name,table:p?.table||"",full:p?p.table+"."+p.column:S.name}}),rows:a,query:e}}throw new Error(`[PG CONN] Unsupported command: ${s}`)}catch(a){throw a instanceof i?a:new i(400,a.message)}},wo=async(e,t)=>{await e.query("BEGIN");try{let r=await t();return await e.query("COMMIT"),console.log("[PG CONN] Commit"),r}catch(r){throw await e.query("ROLLBACK"),console.log("[PG CONN] Rollback"),r}},So=async(e,t)=>{await e.query("BEGIN READ ONLY");try{let r=await t();return console.log("[PG CONN] Read only rollback"),await e.query("ROLLBACK"),r}catch(r){throw console.log("[PG CONN] Rollback"),await e.query("ROLLBACK"),r}},gt=async e=>{let t=await fo(e),r=!1,o=!1,a=async n=>(o||await t.query(`SET search_path TO ${e.schema}`),n());return{dbType:"postgres",dataSource:e,inspectSchema:()=>go(e,t),executeQuery:n=>a(()=>n.type==="SELECT"?So(t,()=>yt(n.sql,n.params,t,n)):wo(t,()=>yt(n.sql,n.params,t,n))),checkConnection:async()=>{},isClosed:()=>r,close:async()=>{if(!r)return r=!0,t.end()}}};var M=async(e,t,r)=>{try{let o;if(t==="mysql")o=await ft(e);else if(t==="postgres")o=await gt(e);else throw new i(500,`Connection manager for ${t} not found`);return r.__connections?r.__connections.push(o):r.__connections=[o],o}catch(o){throw console.error(o),o instanceof i?o:o?.code==="ECONNREFUSED"?new i(500,"Failed to connect to the database"):new i(500,o.message)}};var ae=O(require("node:crypto"));var ht="aes-256-gcm",Eo=12,wt=()=>{let e=y.str("SYMM_ENCRYPTION_KEY");if(!e)throw new Error("Missing ENCRYPTION_KEY in environment variables.");let t=Buffer.from(e,"hex");if(t.length!==32)throw new Error("ENCRYPTION_KEY must be a 64-character hex string (256 bits).");return t},bo=e=>{let t=ae.default.randomBytes(Eo),r=wt(),o=ae.default.createCipheriv(ht,r,t),a=o.update(e,"utf8","hex");a+=o.final("hex");let n=o.getAuthTag();return{encrypted:a,iv:t.toString("hex"),tag:n.toString("hex")}},Io=({encrypted:e,iv:t,tag:r})=>{let o=wt(),a=ae.default.createDecipheriv(ht,o,Buffer.from(t,"hex"));a.setAuthTag(Buffer.from(r,"hex"));let n=a.update(e,"hex","utf8");return n+=a.final("utf8"),n},ne={encrypt:bo,decrypt:Io};var k=(e,t=!1)=>{if(t){let r=ne.decrypt({encrypted:e.dbPassword,tag:e.dbPasswordTag,iv:e.dbPasswordIv});return{url:e.dbUrl,user:e.dbUser,database:e.dbDatabase,password:r,port:e.dbPort,schema:e.dbSchema}}return{url:e.dbUrl,user:e.dbUser,database:e.dbDatabase,password:e.dbPassword,port:e.dbPort,schema:e.dbSchema}};var St=[{value:"=",label:"equals"},{value:"<>",label:"not equal"},{value:">",label:"greater than"},{value:">=",label:"greater than or equal"},{value:"<",label:"less than"},{value:"<=",label:"less than or equal"},{value:"LIKE",label:"like"},{value:"NOT LIKE",label:"not like"},{value:"CONTAINS",label:"contains"},{value:"NOT CONTAINS",label:"not contains"},{value:"IN",label:"in list"},{value:"NOT IN",label:"not in list"},{value:"IS NULL",label:"is null"},{value:"IS NOT NULL",label:"is not null"}],Ro=St.reduce((e,t)=>(e[t.value]=t.label,e),{}),jn=St.reduce((e,t)=>(e[t.label]=t.value,e),{}),W=e=>e.map(t=>({label:Ro[t],value:t})),Kn=W(["=","<>",">",">=","<","<=","IN","NOT IN","IS NULL","IS NOT NULL"]),Vn=W(["=","<>","LIKE","NOT LIKE","IN","NOT IN","IS NULL","IS NOT NULL","CONTAINS","NOT CONTAINS"]),zn=W(["=","<>","IS NULL","IS NOT NULL"]),Jn=W(["=","<>",">",">=","<","<=","IS NULL","IS NOT NULL"]),Xn=W(["IS NULL","IS NOT NULL"]),Zn=W(["IN","NOT IN"]),Co=["char","varchar","binary","varbinary","blob","text","enum","set","character","character varying","text","citext","uuid","xml","json","jsonb"],No=new Set(Co),se=e=>No.has(e),Ao=["integer","smallint","decimal","numeric","float","real","double precision","int","smallint","integer","bigint","decimal","numeric","real","double precision","serial","bigserial","money"],Po=new Set(Ao),Et=e=>Po.has(e);var es=["date","datetime","timestamp","timestamptz"].reduce((e,t)=>(e[t]=!0,e),{});var Ae={read_only:10,editor:20,admin:30,owner:40};var P=e=>e.startsWith("'")&&e.endsWith("'")||e.startsWith('"')&&e.endsWith('"')?e.slice(1,-1):e;var bt={operator:"LIKE",parse:e=>{let t=e.match(/^LIKE\s*["'](.*)["']$/i);if(t)return[{value:P(t[1])}]},stringify:e=>`LIKE "%${e[0]?.value}%"`},It={operator:"NOT LIKE",parse:e=>{let t=e.match(/^NOT LIKE\s*["'](.*)["']$/i);if(t)return[{value:P(t[1])}]},stringify:e=>`NOT LIKE "%${e[0]?.value}%"`},Rt={operator:"CONTAINS",parse:e=>{let t=e.match(/^CONTAINS\s*["'](.*)["']$/i);if(t)return[{value:P(t[1])}]},stringify:(e,t)=>se(t)?`${e[0]?.value}`:`CONTAINS "%${e[0]?.value}%"`},Ct={operator:"NOT CONTAINS",parse:e=>{let t=e.match(/^NOT CONTAINS\s*["'](.*)["']$/i);if(t)return[{value:P(t[1])}]},stringify:e=>`NOT CONTAINS "%${e[0]?.value}%"`};function At(e){return e===""?[]:Oo(e).map(_o)}function Oo(e){let t=[],r=0,o="",a=!1,n=!1;for(;r<e.length;){let s=e[r];if((a||n)&&s==="\\"){o+=e[r+1],r+=2;continue}if(s==="'"&&!n){a=!a,o+=s,r++;continue}if(s==='"'&&!a){n=!n,o+=s,r++;continue}if(s===","&&!a&&!n){t.push(o.trim()),o="",r++;continue}o+=s,r++}if(o.trim()!==""&&t.push(o.trim()),a||n)throw new Error("Unterminated string literal");return t}function _o(e){if(e.startsWith("'")&&e.endsWith("'"))return{value:Nt(e.slice(1,-1),"'")};if(e.startsWith('"')&&e.endsWith('"'))return{value:Nt(e.slice(1,-1),'"')};let t=Number(e);if(!Number.isNaN(t))return{value:t};throw new Error(`Invalid literal: ${e}`)}function Nt(e,t){return e.replace(/\\(.)/g,(r,o)=>o)}var Pt={operator:"IN",parse:e=>{let t=e.match(/^in\s*\((.*)\)$/i);if(t)return At(t[1])},stringify:e=>`IN (${e?.map(t=>`"${t.value}"`).join(", ")})`},Ot={operator:"NOT IN",parse:e=>{let t=e.match(/^not\s+in\s*\((.*)\)$/i);if(t)return At(t[1])},stringify:e=>`NOT IN (${e?.map(t=>`"${t.value}"`).join(", ")})`};var _t={operator:"=",parse:e=>{let t=e.match(/^=\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:(e,t)=>Et(t)?`${e[0]?.value}`:`= ${e[0]?.value}`},xt={operator:"!=",parse:e=>{let t=e.match(/^!=\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`!= ${e[0]?.value}`},vt={operator:"<>",parse:e=>{let t=e.match(/^<>\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`<> ${e[0]?.value}`},Dt={operator:">",parse:e=>{let t=e.match(/^>\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`> ${e[0]?.value}`},Ut={operator:">=",parse:e=>{let t=e.match(/^>=\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`>= ${e[0]?.value}`},Lt={operator:"<",parse:e=>{let t=e.match(/^<\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`< ${e[0]?.value}`},qt={operator:"<=",parse:e=>{let t=e.match(/^<=\s*(.*)$/);if(t)return[{value:P(t[1])}]},stringify:e=>`<= ${e[0]?.value}`};var Mt={operator:"IS NULL",parse:e=>{if(/^is\s+null$/i.test(e))return[]},stringify:()=>"IS NULL"},kt={operator:"IS NOT NULL",parse:e=>{if(/^is\s+not\s+null$/i.test(e))return[]},stringify:()=>"IS NOT NULL"};var xo=[bt,Rt,It,Ct,Pt,Ot,_t,xt,vt,Ut,Dt,qt,Lt,Mt,kt];function vo(e){let t=e.trim();for(let r of xo){let o=r.parse(t);if(o)return{operator:r.operator,value:o}}}var Qt={parse:vo};var E=e=>{let t=Ae[e];return r=>Ae[r.currentTeamRole]>=t},Bt=async e=>{let t=e.routeOptions.config.requireRole;if(t&&!t(e.user))throw new i(403,"You are not authorized to perform this action")};var Ft=T(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=d(t),o=await b.findOne({where:{id:r}});if(!o)throw new i(404,"Data source not found");return{data:o}}}),e.route({method:"get",url:"/",handler:async t=>{let{teamId:r}=U(t);return{data:await b.find({where:{team:{id:r}},order:{createdAt:"DESC"}})}}}),e.route({url:"/",method:"post",config:{requireRole:E("admin")},handler:async t=>{let{teamId:r,ownerId:o,...a}=f(t,mt),n=b.create({...a,allowUpdate:!!a.allowUpdate,allowInsert:!!a.allowInsert,team:{id:r},owner:{id:o}}),s=await M(k(n),n.dbType,t);try{await s.checkConnection()}catch{throw new i(400,"Cannot connect to the database, please check datasource configuration")}let{tag:u,iv:m,encrypted:c}=ne.encrypt(n.dbPassword);return n.dbPassword=c,n.dbPasswordIv=m,n.dbPasswordTag=u,{data:await b.save(n)}}}),e.route({method:"put",url:"/:id",config:{requireRole:E("admin")},handler:async t=>{let{id:r}=d(t),o=f(t),a=await b.findOneBy({id:r});if(!a)throw new i(404,"Data source not found");let n=b.merge(a,o);return await b.save(n),{data:n}}}),e.route({method:"delete",url:"/:id",config:{requireRole:E("admin")},handler:async(t,r)=>h.transaction(async()=>{let{id:o}=d(t);await Promise.all([v.delete({datasource:{id:o}}),I.delete({dataSource:{id:o}})]),await b.delete({id:o})})}),e.route({method:"post",url:"/:id/inspect",handler:async(t,r)=>{let{id:o}=d(t),a=await b.findOne({where:{id:o},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser"]});if(!a)throw new Error("Data source not found");a.status="INSPECTING",await b.save(a);let s=await(await M(k(a,!0),a.dbType,t)).inspectSchema();await v.delete({datasource:{id:o}}),await v.insert(s.sort().map(u=>v.create({tableName:u.tableName,columns:u.columns,datasource:{id:o}}))),a.status="READY",a.lastInspected=new Date,await b.save(a)}}),e.route({method:"get",url:"/:id/inspections",handler:async t=>{let{id:r}=d(t);return{data:await v.find({where:{datasource:{id:r}}})}}})});var B=require("typeorm"),$t=T(e=>{e.route({method:"get",url:"/team/:teamId/datasources",handler:async t=>{let{teamId:r}=d(t);return{data:await b.find({where:{team:{id:r}},order:{name:"ASC"},select:{id:!0,name:!0,updatedAt:!0,dbType:!0,description:!0,allowInsert:!0,allowUpdate:!0}})}}}),e.route({method:"get",url:"/team/:teamId/queries",handler:async t=>{let r=d(t),o=U(t),a=r.teamId||t.user.currentTeamId,n=Number(o.size)||20,s=Number(o.page)||0,u=o.nameFilter?.length?{name:(0,B.Raw)(p=>`LOWER(${p}) LIKE :search`,{search:`%${o.nameFilter.toLowerCase()}%`})}:void 0,m=await D.find({where:[{isPersonal:!1,team:{id:a},query:u},{isPersonal:!0,team:{id:a},query:u,user:{id:t.user.id}}],relations:{query:{dataSource:!0}},take:n+1,skip:s*n,select:{id:!0,query:{id:!0,name:!0,updatedAt:!0,dataSource:{name:!0,dbType:!0}}},order:{query:{updatedAt:"DESC"}}}),c=m.length>n;return c&&m.pop(),{data:m.map(p=>({name:p.query.name,id:p.query.id,updatedAt:p.query.updatedAt,savedQueryId:p.id,datasourceName:p.query.dataSource.name,datasourceType:p.query.dataSource.dbType})),hasMore:c}}}),e.route({method:"get",url:"/team/:teamId/count-saved-queries",handler:async t=>{let o=d(t).teamId||t.user.currentTeamId;return{data:await D.count({where:[{isPersonal:!1,team:{id:o}},{isPersonal:!0,team:{id:o},user:{id:t.user.id}}],select:{id:!0}})}}}),e.route({method:"get",url:"/team/:teamId/query",handler:async t=>{let{teamId:r}=d(t),{search:o,size:a,selectedDataSources:n}=U(t),s=o.length>3?parseInt(a)||20:8,u={};n?.length&&(u.id=(0,B.In)(n));let[m,c,S]=await Promise.all([v.find({where:{tableName:(0,B.Raw)(l=>`LOWER(${l}) LIKE :search`,{search:`%${o.toLowerCase()}%`}),datasource:u},relations:{datasource:!0},select:{id:!0,tableName:!0,datasource:{name:!0,id:!0}},order:{tableName:"ASC"},take:s}),A.find({where:{searchString:(0,B.Like)(`%${o.toLowerCase()}%`),team:{id:r},user:{id:t.user.id},dataSource:u},relations:{dataSource:!0},select:{id:!0,name:!0,updatedAt:!0,dataSource:{id:!0,name:!0}},order:{updatedAt:"ASC"},take:s}),D.find({where:{searchString:(0,B.Like)(`%${o.toLowerCase()}%`),team:{id:r},query:{dataSource:u}},relations:{query:{dataSource:!0}},select:{id:!0,updatedAt:!0,query:{id:!0,name:!0,dataSource:{name:!0}}},order:{updatedAt:"ASC"},take:s})]),p=[];return m.forEach(l=>{p.push({name:l.tableName,id:l.id,dataSourceName:l.datasource?.name||"--",dataSourceId:l.datasource?.id||"--",type:"table"})}),c.forEach(l=>{p.push({name:l.name,id:l.id,dataSourceName:l.dataSource?.name||"--",dataSourceId:l.dataSource?.id||"--",type:"tab"})}),S.forEach(l=>{p.push({name:l.query.name,id:l.query.id,dataSourceName:l.query.dataSource?.name||"--",dataSourceId:l.query.dataSource?.id||"--",type:"query"})}),{data:p}}}),e.route({method:"get",url:"/team/:teamId/tabs-history",handler:async t=>{let{teamId:r}=d(t),o=U(t),a=Number(o.page),n=Number(o.size),s=t.user.id,u=await A.find({where:{team:{id:r},user:{id:s},archived:o.archived?o.archived==="true":void 0},relations:{dataSource:!0},order:{updatedAt:"DESC"},take:n+1,skip:a*n}),m=!1;return u.length>n&&(u.pop(),m=!0),{data:u.map(c=>({name:c.name,id:c.id,updatedAt:c.updatedAt,archived:c.archived,createdAt:c.createdAt,dataSourceId:c.dataSource?.id,dataSourceName:c.dataSource?.name,dataSourceType:c.dataSource?.dbType})),hasMore:m}}})});var Wt=T(e=>{e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=d(t),o=await I.findOne({where:{id:r},select:{dataSource:{id:!0}},relations:{dataSource:!0}});return o?{data:o}:{status:404,data:"Query not found"}}}),e.route({method:"post",url:"/",config:{requireRole:E("editor")},handler:async t=>{let r=f(t),o=await b.findOne({where:{id:r.dataSourceId},relations:{team:!0}});return{data:await I.save(I.create({name:r.name,opts:r.opts,team:{id:o?.team.id},dataSource:{id:r.dataSourceId},user:{id:t.user.id}}))}}}),e.route({method:"patch",url:"/:id",config:{requireRole:E("editor")},handler:async t=>{let{id:r}=d(t),o=f(t);if(!(await I.update(r,o)).affected)throw new i(404,"Query not found");return{data:await I.findOneBy({id:r})}}}),e.route({method:"delete",url:"/:id",config:{requireRole:E("editor")},handler:async t=>h.transaction(async()=>{let{id:r}=d(t);if(!(await I.delete({id:r})).affected)return{status:404,data:"Query not found"}})})});var Ht=e=>se(e)?"CONTAINS":"=",Oe=(e,t)=>{let r=[];for(let o of e)if(!(!o.column?.length||!o.value?.length||o.isEnabled===!1))if(o.isAdvanced){let a=Qt.parse(o.value);if(!a)throw new i(400,`Invalid value for '${o.column}': ${o.value}`);r.push({value:a.value,column:o.column,operator:a.operator||Ht(t(o.column)),fn:o.fn})}else r.push({value:o.value?[{value:o.value}]:[],column:o.column,operator:Ht(t(o.column)),fn:o.fn});return r},Yt=e=>{let t=[e.table];return e.joins&&e.joins.forEach(({table:r})=>t.push(r)),t},Pe=e=>({column:e.value,fn:e.fn,distinct:e.distinct}),Gt=(e,t,r)=>{let o=[];return t.length>0||r.length>0?o.push(...t.map(Pe),...r.map(Pe)):e.length>0&&o.push(...e.map(Pe)),o},jt=(e,t,r)=>t.map((o,a)=>({...o,full:e[a].fn?e[a].column:o.full,type:r(o.full),fn:e[a].fn}));var _e=require("typeorm"),Kt=new _e.DataSource({type:"mysql"}),Vt=new _e.DataSource({type:"postgres"}),H=e=>{switch(e){case"postgres":return Vt.createQueryBuilder();case"mysql":return Kt.createQueryBuilder();default:throw new Error("Unsupported database connection")}},ie={postgres:Vt.driver,mysql:Kt.driver};var V=(e,t,r)=>{let{column:o,operator:a,value:n}=e,s="_"+t;switch(a){case"IS NULL":case"IS NOT NULL":return[`${o} ${a}`,{value:void 0}];case"IN":case"NOT IN":return[`${o} ${a} (:...${s})`,{[s]:n?.map(c=>c.value)}];case"LIKE":case"CONTAINS":return[`${o} ${r==="postgres"?"ILIKE":"LIKE"} :${s}`,{[s]:a==="CONTAINS"?`%${n?.[0].value}%`:n?.[0].value}];case"NOT LIKE":case"NOT CONTAINS":return[`${o} ${r==="postgres"?"NOT ILIKE":"NOT LIKE"} :${s}`,{[s]:a==="NOT CONTAINS"?`%${n?.[0].value}%`:n?.[0].value}];default:return[`${o} ${a} :${s}`,{[s]:n?.[0]?.value}]}};var zt=e=>{let t=ie[e];return r=>{if(r.includes(".")){let[o,a]=r.split(".");return t.escape(o)+"."+t.escape(a)}return r==="*"?r:t.escape(r)}};var Jt=["SUM","COUNT","AVG","MAX","MIN"],Do=["YEAR","MONTH","DAY",...Jt],Uo=Do.reduce((e,t)=>(e[t]=!0,e),{}),Lo=Jt.reduce((e,t)=>(e[t]=!0,e),{}),Xt=e=>Uo[e],Zt=e=>Lo[e];var ue=(e,t,r=!1)=>r?`${t}(distinct ${e})`:`${t}(${e})`,er={YEAR:e=>`EXTRACT(YEAR FROM ${e})`,MONTH:e=>`EXTRACT(MONTH FROM ${e})`,DAY:e=>`EXTRACT(DAY FROM ${e})`,SUM:(e,t,r)=>r?`COALESCE(SUM(distinct ${e}), 0)`:`COALESCE(SUM(${e}), 0)`,AVG:ue,MAX:ue,MIN:ue,COUNT:ue};var ce=(e,t,r=!1)=>r?`${t}(distinct ${e})`:`${t}(${e})`,tr={YEAR:e=>`YEAR(${e})`,MONTH:e=>`MONTH(${e})`,DAY:e=>`DAY(${e})`,SUM:(e,t,r)=>r?`coalesce(${t}(distinct ${e}), 0)`:`coalesce(${t}(${e}), 0)`,AVG:ce,MAX:ce,MIN:ce,COUNT:ce};var qo=e=>{let t=[];return e.fn&&t.push(e.fn),e.distinct&&t.push("distinct"),t.push(e.column),t.join(" ")},Mo=e=>{let t=zt(e),r=e==="postgres"?er:tr;return o=>o.fn&&Xt(o.fn)?r[o.fn](t(o.column),o.fn,o.distinct):t(o.column)};function rr(e,t){let r=H(t.dbType).from(e,e),o=!1,a=0,n=Mo(t.dbType),s={};return{setColumns(u){u.forEach(m=>{let c=qo(m);s[c]=c,r.addSelect(n(m),c)})},setLimit:u=>{r.limit(u),o=!0},setOffset(u){r.skip(u)},addOrderBy(u,m){r.addOrderBy(u,m)},addJoin({table:u,alias:m,on:c}){r.leftJoin(u,m||u,c)},addWhere(u){let[m,c]=V({...u,operator:u.operator||"=",column:n(u)},++a,t.dbType);r.andWhere(m,c)},addHaving(u){let[m,c]=V({...u,operator:u.operator||"=",column:n(u)},++a,t.dbType);r.andHaving(m,c)},addGroupBy(u){r.addGroupBy(n(u))},hasAlias(u){return!!s[u]},build(){o||r.limit(50);let[u,m]=r.getQueryAndParameters();return{sql:u,params:m}}}}var or=(e,t)=>{let r=H(t.dbType).update(e),o=0;return{addWhere(a){let[n,s]=V(a,++o,t.dbType);r.andWhere(n,s)},setParams(a){let n={};for(let[s,u]of Object.entries(a)){let m=`${u}`;m.startsWith("=")?n[s]=()=>m.substring(1):n[s]=m}r.set(n)},build(){let[a,n]=r.getQueryAndParameters();return{sql:a,params:n}}}};var ar=(e,t)=>{let r=H(t.dbType).insert().into(e);return{setValues(o){let a={};for(let[n,s]of Object.entries(o)){let u=`${s}`;u.startsWith("=")?a[n]=()=>u.substring(1):a[n]=u}r.values([a])},build(){let[o,a]=r.getQueryAndParameters();return{sql:o,params:a}}}};var xe=rr,nr=or,sr=ar;var ir=require("typeorm"),ur=async(e,t)=>{let r=await v.find({where:{tableName:(0,ir.In)(t),datasource:{id:e}}}),o=[];for(let s of r)if(s.columns)for(let u of s.columns)o.push({column:u.name,table:s.tableName||"",full:`${s.tableName}.${u.name}`,type:u.type});let a=o.reduce((s,u)=>(s[u.full]=u.type,s),{});return{getAllColumns(){return o},getColumnType:s=>a[s],hasColumn(s){return!!a[s]||s==="*"}}};async function ko(e,t,r){return I.save(I.create({user:{id:e},team:{id:t},dataSource:{id:r.datasourceId},name:r.name,opts:r.opts}))}var me=async(e,t)=>{let{datasourceId:r,size:o=20,page:a}=t,{table:n,joins:s,groupBy:u,orderBy:m}=t.opts,c=await le(r);if(!c)throw new i(404,"Datasource not found");let S=Gt(t.opts.columns,t.opts.groupBy,t.opts.aggregations),p=Yt(t.opts),l=await ur(r,p),C=l.getAllColumns(),L;S&&S.length>0?L=S:L=C.map(R=>({column:R.full})),L.forEach(R=>{if(!l.hasColumn(R.column))throw new i(400,`Invalid column ${R.column}`)});let Hr=ko(e.user.id,e.user.currentTeamId,t),x=xe(n,c);x.setLimit(o+1),x.setOffset(o*a),x.setColumns(L),s&&s.forEach(x.addJoin),m.length>0&&m.forEach(({column:R,direction:Kr})=>{x.hasAlias(R)&&x.addOrderBy(ie[c.dbType].escape(R),Kr)}),u&&u.length>0&&u.forEach(R=>{l.hasColumn(R.value)&&x.addGroupBy({column:R.value,fn:R.fn,distinct:R.distinct})}),Oe(t.opts.filters,l.getColumnType).forEach(R=>{R.fn&&Zt(R.fn)?x.addHaving(R):x.addWhere(R)});let{sql:Yr,params:Gr}=x.build(),J=await(await M(k(c,!0),c.dbType,e)).executeQuery({sql:Yr,params:Gr,type:"SELECT",allowBulkUpdate:!1}),De=J.rows.length>o;De&&J.rows.pop();let{id:jr}=await Hr;return{...J,queryHistoryId:jr,tables:p,allColumns:C,columns:jt(L,J.columns,l.getColumnType),hasMore:De}},cr=async(e,t)=>{let r=await le(t.dataSourceId);if(!r)throw new i(400,"Invalid datasource");let o=await M(k(r,!0),r.dbType,e),a=xe(t.table,r);a.setLimit(2);for(let[m,c]of Object.entries(t.props))a.addWhere({value:[{value:c}],column:m});let{sql:n,params:s}=a.build(),u=await o.executeQuery({sql:n,params:s,type:"SELECT",allowBulkUpdate:!1});if(u.rows.length>1)throw new i(400,"Found multiple rows for given query");if(u.rows.length<1)throw new i(404,"Entity not found");return{entity:u.rows[0],columns:u.columns,sql:n}},mr=async(e,t)=>{let r=await le(t.datasourceId);if(!r)throw new i(404,"Data source not found");if(!r.allowUpdate)throw new i(403,"This datasource does not allow update operations");let o=nr(t.table,r);o.setParams(t.values),Oe(t.filters,()=>"=").forEach(u=>{o.addWhere(u)});let{sql:a,params:n}=o.build();return(await M(k(r,!0),r.dbType,e)).executeQuery({sql:a,params:n,type:"UPDATE",allowBulkUpdate:!1})},lr=async(e,t)=>{let r=await le(t.datasourceId);if(!r)throw new i(404,"Data source not found");if(!r.allowInsert)throw new i(403,"This datasource does not allow insert operations");let o=sr(t.table,r);o.setValues(t.values);let{sql:a,params:n}=o.build();return(await M(k(r,!0),r.dbType,e)).executeQuery({sql:a,type:"INSERT",params:n,allowBulkUpdate:!1})};async function le(e){return b.findOne({where:{id:e},select:["id","dbType","dbDatabase","dbPassword","dbPasswordTag","dbPasswordIv","dbPort","dbUrl","dbSchema","dbUser","allowUpdate","allowInsert"]})}var dr=e=>{},Qo=["--",";","DROP","drop"],pr=([e,t])=>{if(typeof t=="string"&&t.startsWith("=")){let r=t;Qo.forEach(o=>{if(r.includes(o))throw new i(400,"Invalid input value for "+e)})}},fr=e=>{if(!e.table)throw new i(400,"Table is required");Object.entries(e.values).forEach(pr)},yr=e=>{if(!e.table)throw new i(400,"Table is required");Object.entries(e.values).forEach(pr)};var Tr=T(e=>{e.route({method:"post",url:"/:dsId/select",handler:async t=>{let r=f(t,dr);return{data:await me(t,r)}}}),e.route({method:"get",url:"/:dsId/entity/:table",handler:async t=>{let{dsId:r,table:o}=d(t),a=U(t);return{data:await cr(t,{table:o,dataSourceId:r,props:a})}}}),e.route({method:"post",url:"/:dsId/insert",config:{requireRole:E("editor")},handler:async t=>{let r=f(t,fr);return{data:await lr(t,r)}}}),e.route({method:"post",url:"/:dsId/update",config:{requireRole:E("editor")},handler:async t=>{let r=f(t,yr);return{data:await mr(t,r)}}})});var gr=T(e=>{e.get("/",{config:{isPublic:!0}},async()=>({data:{active:!0,version:y.str("SERVER_VERSION")}}))});var hr=T(e=>{e.route({method:"get",url:"/:id/users",handler:async t=>{let{id:r}=d(t),o=await q.findOne({where:{id:r},relations:{users:{user:!0}}});if(!o)throw new i(404,"Team not found");return{data:o.users.map(a=>({role:a.role,id:a.user.id,name:a.user.username}))}}}),e.route({method:"post",url:"/",config:{requireRole:E("editor")},handler:async t=>h.transaction(async()=>{let r=t.user.id,o=f(t),a=w.create();a.id=r;let n=q.create(o);await q.save(n);let s=N.create({user:a,team:n});return await N.save(s),{data:n}})}),e.route({method:"patch",url:"/:id/user-role",config:{requireRole:E("admin")},handler:async t=>{let{id:r}=d(t),{role:o,userId:a}=f(t,({role:s})=>{if(s==="owner")throw new i(400,"Only one owner is allowed")});if((await N.findOneBy({user:{id:a},team:{id:r}}))?.role==="owner")throw new i(400,"Cannot change owner role");await N.update({user:{id:a},team:{id:r}},{role:o})}}),e.route({method:"delete",url:"/:id",config:{requireRole:E("admin")},handler:async t=>h.transaction(async()=>{let{id:r}=d(t),{userId:o}=U(t);if((await N.findOneBy({user:{id:o},team:{id:r}}))?.role==="owner")throw new i(400,"Cannot delete team owner");await w.update(o,{currentTeam:null}),await N.delete({user:{id:o},team:{id:r}}),await w.delete({id:o})})})});var ve=O(require("bcryptjs")),z=async e=>{let t=await ve.default.genSalt(10);return ve.default.hash(e,t)};var wr=T(e=>{e.route({method:"get",url:"/",handler:async t=>{let r=await w.findOne({where:{id:t.user.id},relations:{currentTeam:{team:!0}}});if(!r)throw new i(404,"User not found");return{data:{id:r.id,teamId:r.currentTeam?.team.id,teamName:r.currentTeam?.team.name,teamRole:r.currentTeam?.role,username:r.username}}}}),e.route({method:"patch",url:"/",handler:async t=>{let r=t.user.id,o=f(t);if(o.password&&(o.password=await z(o.password)),!(await w.update(r,o)).affected)throw new i(404,"User not found");let n=await w.findOne({where:{id:r},relations:{currentTeam:{team:!0}}});return{data:{id:n?.id,teamId:n?.currentTeam?.team.id,teamName:n?.currentTeam?.team.name,teamRole:n?.currentTeam?.role,username:n?.username}}}}),e.route({method:"post",url:"/",config:{requireRole:E("admin")},handler:async t=>h.transaction(async()=>{let r=f(t),o=await z(r.password),a=await w.save(w.create({username:r.username,password:o})),n=await N.save(N.create({role:"read_only",team:{id:r.teamId},user:{id:a.id}}));await w.update(a.id,{currentTeam:{id:n.id}})})})});var Sr=T(e=>{e.route({method:"get",url:"/",handler:async t=>{let r=t.user.id,o=await $.findOneBy({user:{id:r}});return o||(o=await $.save($.create({user:{id:r}}))),{data:o}}}),e.route({method:"patch",url:"/",handler:async t=>{let{settings:r}=f(t);if(!r.id)throw new i(400,"Settings id is required!");if(!(await $.update(r.id,r)).affected)throw new i(404,"You do not own these settings!");return{data:await $.findOneBy({id:r.id})}}})});function Y(e,...t){let r=[...t];if(e.searchAll&&r.push(e.searchAll),e.filters)for(let o of e.filters)o.value&&r.push(o.value);return r.map(o=>o.toLowerCase()).join(",")}var Er=T(e=>{e.route({method:"post",url:"/",config:{requireRole:E("editor")},handler:async t=>{let r=f(t),o=await I.findOne({where:{id:r.queryId}});if(!o)throw new i(400,"Query not found");let a=await D.save(D.create({isPersonal:!1,team:{id:t.user.currentTeamId},user:{id:t.user.id},query:{id:r.queryId},searchString:Y(o.opts,r.name)}));return await I.update(r.queryId,{name:r.name}),{data:a}}}),e.route({method:"delete",url:"/:id",config:{requireRole:E("editor")},handler:async t=>{let{id:r}=d(t);if(!(await D.delete({id:r})).affected)return{status:404,data:"Query not found"}}}),e.route({method:"patch",url:"/:id",handler:async t=>await h.transaction(async()=>{let{id:r}=d(t),o=f(t,s=>{if(!s.name)throw new i(400,"Name is required")}),a=await D.findOne({where:{id:r},relations:{query:!0}});if(!a)throw new i(400,"Query not found");let n=Y(a.query.opts,o.name);return await Promise.all([D.update({id:r},{searchString:n}),I.update({id:a.query.id},{name:o.name})]),{data:!0}})})});var br=e=>{if(!e.queryId&&!(e.opts&&e.name))throw new i(400,"Either queryId or name and opts are required")};var Ir=T(e=>{e.route({method:"get",url:"/",handler:async t=>{let{currentTeamId:r,id:o}=t.user;return{data:(await A.find({where:{team:{id:r},user:{id:o},archived:!1},select:["id","name"]})).map(n=>({name:n.name,id:n.id}))}}}),e.route({method:"get",url:"/:id",handler:async t=>{let{id:r}=d(t),{currentTeamId:o,id:a}=t.user,n=await A.findOne({where:{id:r,team:{id:o},user:{id:a}}});if(!n)throw new i(404,"Not Found");return{data:n}}}),e.route({method:"post",url:"/",handler:async t=>{let{opts:r,name:o,queryId:a}=f(t,br),n,s,u=o;if(r)s=r.dataSourceId,n=r;else{let c=await I.findOne({where:{id:a},relations:{dataSource:!0}});if(!c)throw new i(404,"Query not Found");s=c.dataSource.id,n={table:c.opts.table,filters:c.opts.filters,joins:c.opts.joins,orderBy:c.opts.orderBy,columns:c.opts.columns,groupBy:c.opts.groupBy,searchAll:c.opts.searchAll,aggregations:c.opts.aggregations,dataSourceId:c.dataSource.id,page:0,size:50},o||(u=c.name)}return{data:await A.save(A.create({name:u||new Date().toISOString(),opts:n,dataSource:{id:s},user:{id:t.user.id},team:{id:t.user.currentTeamId}}))}}}),e.route({method:"post",url:"/:id/run",handler:async t=>{let{id:r}=d(t),o=f(t),a=await A.findOne({where:{id:r},relations:{user:!0}});if(!a)throw new i(404,"Not found");if(a.user?.id!==t.user.id)throw new i(404,"Not found");return o&&A.update(r,{opts:o,searchString:Y(o,a.name),updatedAt:new Date}),{data:{result:await me(t,{datasourceId:o.dataSourceId,size:o.size,name:a.name,page:o.page,opts:{table:o.table,filters:o.filters,joins:o.joins,orderBy:o.orderBy,columns:o.columns,groupBy:o.groupBy,searchAll:o.searchAll,aggregations:o.aggregations}})}}}}),e.route({method:"patch",url:"/:id",handler:async t=>{let{id:r}=d(t),o=f(t),a=await A.findOne({where:{id:r,user:{id:t.user.id}}});if(!a)throw new i(404,"Not Found");let n=a.searchString;return o.name&&(n=Y(a.opts,o.name)),await A.update(r,{...o,searchString:n}),{data:{id:r}}}}),e.route({method:"delete",url:"/:id",handler:async t=>{let{id:r}=d(t),o=t.user.id;return await A.delete({id:r,user:{id:o}}),{data:!0}}})});var Nr=require("node:crypto");var Rr=require("node:crypto"),Cr={teamName:"Default Team",username:"admin"},Bo=async()=>{let e=await q.findOneBy({});return e||q.save(q.create({name:Cr.teamName}))},de=async e=>{let t=await N.findOne({where:{role:"owner"},relations:{user:!0}});if(t)return t.user;let r=await Bo(),o=await z(e?.password||(0,Rr.randomBytes)(32).toString("hex")),a=await w.save(w.create({username:e?.name||Cr.username,password:o})),n=await N.save(N.create({user:a,team:r,role:"owner"}));return await w.update(a.id,{currentTeam:n}),a};var pe={setupAccessToken:void 0},Ar=()=>(pe.setupAccessToken=(0,Nr.randomBytes)(32).toString("hex"),pe.setupAccessToken),Fo=e=>{if(!pe.setupAccessToken)throw new i(400,"Setup already performed");if(!e||e!==pe.setupAccessToken)throw new i(400,"Invalid setup access token")},F=async()=>_.skipAuth?!1:await w.count()<1,Pr=async e=>{Fo(e.setupAccessToken),await de({name:e.userName,password:e.userPassword})};var Or=T(e=>{e.route({method:"get",url:"/client.config.js",handler:(t,r)=>{let o={skipAuth:_.skipAuth,modeName:_.name,usesCustomDb:Qe(),serverVersion:y.str("SERVER_VERSION","--")};return r.type("application/javascript").send(`window.__CLIENT_CONFIG__ = ${JSON.stringify(o)};`)}}),e.route({method:"get",url:"/",handler:async(t,r)=>await F()?r.redirect("/setup"):r.sendFile("index.html")}),e.route({method:"get",url:"/setup",handler:async(t,r)=>await F()?r.sendFile("setup.html"):r.redirect("/")})});var _r=e=>{if(!e.setupAccessToken)throw new i(400,"Invalid setup access token");if(!e.userPassword||e.userPassword.length<8)throw new i(400,"Password should be at least 8 chars long");if(!e.userName)throw new i(400,"User name is required")};var xr=T(e=>{e.route({method:"post",url:"/",config:{isPublic:!0},handler:async t=>{if(!await F())throw new i(400,"Setup has already been completed");let o=f(t,_r);return await Pr(o),{data:!0}}})});var $o=[[Or,"/"],[ct,"/api/auth"],[Ft,"/api/data-sources"],[$t,"/api/project"],[Wt,"/api/queries"],[Tr,"/api/runner"],[gr,"/api/status"],[hr,"/api/teams"],[wr,"/api/users"],[Sr,"/api/user-settings"],[Er,"/api/saved-queries"],[Ir,"/api/workbench-tabs"],[xr,"/api/setup"]],vr=e=>{for(let[t,r]of $o)e.register(t,{prefix:r}),console.log("Registered "+r)};var Wo=e=>e.routeOptions.config.isPublic?!0:!e.url.startsWith("/api/"),Ho=async()=>N.findOne({where:{role:"owner"},relations:{user:!0,team:!0}}),Yo=async e=>{let t=await Ho();if(!t)throw new i(401,"User is not part of a team");e.user={id:t.user.id,currentTeamId:t.team.id,currentTeamRole:t.role}},Go=async e=>{let t=e.headers.authorization;if(!t)throw new i(401,"Missing auth token");let[r,o]=t.split(" "),{userId:a}=await nt(o),n=await w.findOne({where:{id:a},select:{id:!0,currentTeam:{role:!0,team:{id:!0}}},relations:{currentTeam:{team:!0}}});if(!n)throw new i(401,"Unauthorized");e.user={id:a,currentTeamId:n.currentTeam.team.id,currentTeamRole:n.currentTeam.role}},Dr=async e=>{Wo(e)||(_.skipAuth?await Yo(e):await Go(e))};var Ur=(e,t)=>{e.__connections&&e.__connections.forEach(r=>{r.close()})};var Lr=e=>{e.addHook("onRequest",Dr),e.addHook("onRequest",Bt),e.addHook("onResponse",Ur)};var qr=e=>{e.setNotFoundHandler((t,r)=>{if(t.raw.url?.startsWith("/api/")){r.code(404).send({error:"API route not found"});return}r.sendFile("index.html")}),e.setErrorHandler((t,r,o)=>{console.error(t),t instanceof i?o.status(t.status).send({error:t.message}):o.status(500).send({error:"Internal Server Error"})})};var Mr=O(require("@fastify/cookie")),kr=O(require("@fastify/cors"));var Qr=O(require("@fastify/static")),Br=require("node:path"),Fr=e=>{e.register(Mr.default,{}),e.register(kr.default,{origin:G.allowedOrigins,methods:["GET","POST","PUT","PATCH","DELETE","OPTIONS"],credentials:!0}),e.register(Qr.default,{root:(0,Br.join)(__dirname,"web")})};(async function(){let t=(0,$r.default)({querystringParser:o=>Wr.default.parse(o)});if(ke(),Fr(t),Lr(t),vr(t),qr(t),await t.after(),await Xe(),t.listen({port:G.port,host:G.host},(o,a)=>{o&&(console.error(o),process.exit(1)),console.log(`Server listening at ${a}`)}),await F()){let o=Ar();console.log(`Setup access token:
|
|
58
58
|
${o}`),console.log("Use the above token to finish the setup process when opening the app for the first time.")}else await de()})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import"https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap";@import"https://fonts.googleapis.com/css2?family=Comfortaa:wght@300..700&display=swap";@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-800:oklch(44.4% .177 26.899);--color-yellow-50:oklch(98.7% .026 102.212);--color-yellow-200:oklch(94.5% .129 101.54);--color-yellow-800:oklch(47.6% .114 61.907);--color-green-50:oklch(98.2% .018 155.826);--color-green-200:oklch(92.5% .084 155.995);--color-green-800:oklch(44.8% .119 151.328);--color-blue-50:oklch(97% .014 254.604);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-800:oklch(42.4% .199 265.638);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-semibold:600;--radius-md:.375rem;--radius-lg:.5rem;--animate-spin:spin 1s linear infinite;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{._pointer-events-none_1pedq_2{pointer-events:none}._visible_1pedq_2{visibility:visible}._sr-only_1pedq_2{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}._absolute_1pedq_2{position:absolute}._relative_1pedq_2{position:relative}._sticky_1pedq_2{position:sticky}._top-0_1pedq_2{top:calc(var(--spacing)*0)}._top-2_1pedq_2{top:calc(var(--spacing)*2)}._right-2_1pedq_2{right:calc(var(--spacing)*2)}._z-0_1pedq_2{z-index:0}._z-1_1pedq_2{z-index:1}._z-10_1pedq_2{z-index:10}._z-100_1pedq_2{z-index:100}._col-span-2_1pedq_2{grid-column:span 2/span 2}._m-2_1pedq_2{margin:calc(var(--spacing)*2)}._mx-1_1pedq_2{margin-inline:calc(var(--spacing)*1)}._mx-2_1pedq_2{margin-inline:calc(var(--spacing)*2)}._mx-auto_1pedq_2{margin-inline:auto}._my-2_1pedq_2{margin-block:calc(var(--spacing)*2)}._my-10_1pedq_2{margin-block:calc(var(--spacing)*10)}._mt-1_1pedq_2{margin-top:calc(var(--spacing)*1)}._mt-2_1pedq_2{margin-top:calc(var(--spacing)*2)}._mt-4_1pedq_2{margin-top:calc(var(--spacing)*4)}._mt-8_1pedq_2{margin-top:calc(var(--spacing)*8)}._mt-10_1pedq_2{margin-top:calc(var(--spacing)*10)}._mr-1_1pedq_2{margin-right:calc(var(--spacing)*1)}._mr-2_1pedq_2{margin-right:calc(var(--spacing)*2)}._mb-0\.5_1pedq_2{margin-bottom:calc(var(--spacing)*.5)}._mb-1_1pedq_2{margin-bottom:calc(var(--spacing)*1)}._mb-2_1pedq_2{margin-bottom:calc(var(--spacing)*2)}._mb-4_1pedq_2{margin-bottom:calc(var(--spacing)*4)}._mb-10_1pedq_2{margin-bottom:calc(var(--spacing)*10)}._ml-1_1pedq_2{margin-left:calc(var(--spacing)*1)}._block_1pedq_2{display:block}._flex_1pedq_2{display:flex}._grid_1pedq_2{display:grid}._hidden_1pedq_2{display:none}._table_1pedq_2{display:table}._h-0\.5_1pedq_2{height:calc(var(--spacing)*.5)}._h-1_1pedq_2{height:calc(var(--spacing)*1)}._h-8_1pedq_2{height:calc(var(--spacing)*8)}._h-screen_1pedq_2{height:100vh}._max-h-full_1pedq_2{max-height:100%}._max-h-screen_1pedq_2{max-height:100vh}._min-h-screen_1pedq_2{min-height:100vh}._w-8_1pedq_2{width:calc(var(--spacing)*8)}._w-full_1pedq_2{width:100%}._max-w-none_1pedq_2{max-width:none}._max-w-xl_1pedq_2{max-width:var(--container-xl)}._flex-1_1pedq_2{flex:1}._rotate-180_1pedq_2{rotate:180deg}._transform_1pedq_2{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}._animate-spin_1pedq_2{animation:var(--animate-spin)}._cursor-auto\!_1pedq_2{cursor:auto!important}._cursor-pointer_1pedq_2{cursor:pointer}._grid-cols-2_1pedq_2{grid-template-columns:repeat(2,minmax(0,1fr))}._grid-cols-4_1pedq_2{grid-template-columns:repeat(4,minmax(0,1fr))}._flex-col_1pedq_2{flex-direction:column}._items-center_1pedq_2{align-items:center}._justify-between_1pedq_2{justify-content:space-between}._justify-center_1pedq_2{justify-content:center}._justify-end_1pedq_2{justify-content:flex-end}._gap-1_1pedq_2{gap:calc(var(--spacing)*1)}._gap-2_1pedq_2{gap:calc(var(--spacing)*2)}._gap-8_1pedq_2{gap:calc(var(--spacing)*8)}._justify-self-center_1pedq_2{justify-self:center}._justify-self-end_1pedq_2{justify-self:flex-end}._truncate_1pedq_2{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}._overflow-auto_1pedq_2{overflow:auto}._overflow-hidden_1pedq_2{overflow:hidden}._overflow-x-auto_1pedq_2{overflow-x:auto}._overflow-y-auto_1pedq_2{overflow-y:auto}._rounded_1pedq_2{border-radius:.25rem}._rounded-lg_1pedq_2{border-radius:var(--radius-lg)}._rounded-md_1pedq_2{border-radius:var(--radius-md)}._rounded-t-md_1pedq_2{border-top-left-radius:var(--radius-md);border-top-right-radius:var(--radius-md)}._rounded-r-none\!_1pedq_2{border-top-right-radius:0!important;border-bottom-right-radius:0!important}._rounded-b-lg_1pedq_2{border-bottom-right-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}._rounded-b-md_1pedq_2{border-bottom-right-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}._border_1pedq_2{border-style:var(--tw-border-style);border-width:1px}._border-t_1pedq_2{border-top-style:var(--tw-border-style);border-top-width:1px}._border-b_1pedq_2{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}._border-gray-200_1pedq_2{border-color:var(--color-gray-200)}._border-red-600_1pedq_2{border-color:var(--color-red-600)}._border-t-gray-200_1pedq_2{border-top-color:var(--color-gray-200)}._bg-\(--bg\)_1pedq_2{background-color:var(--bg)}._bg-gray-50_1pedq_2{background-color:var(--color-gray-50)}._bg-gray-100_1pedq_2{background-color:var(--color-gray-100)}._bg-gray-800_1pedq_2{background-color:var(--color-gray-800)}._bg-gray-900_1pedq_2{background-color:var(--color-gray-900)}._bg-green-200_1pedq_2{background-color:var(--color-green-200)}._bg-white_1pedq_2{background-color:var(--color-white)}._bg-yellow-200_1pedq_2{background-color:var(--color-yellow-200)}._fill-blue-600_1pedq_2{fill:var(--color-blue-600)}._p-0\.5_1pedq_2{padding:calc(var(--spacing)*.5)}._p-1_1pedq_2{padding:calc(var(--spacing)*1)}._p-2_1pedq_2{padding:calc(var(--spacing)*2)}._p-4_1pedq_2{padding:calc(var(--spacing)*4)}._px-1\.5_1pedq_2{padding-inline:calc(var(--spacing)*1.5)}._px-2_1pedq_2{padding-inline:calc(var(--spacing)*2)}._px-4_1pedq_2{padding-inline:calc(var(--spacing)*4)}._py-0\.5_1pedq_2{padding-block:calc(var(--spacing)*.5)}._py-1_1pedq_2{padding-block:calc(var(--spacing)*1)}._py-2_1pedq_2{padding-block:calc(var(--spacing)*2)}._py-4_1pedq_2{padding-block:calc(var(--spacing)*4)}._py-10_1pedq_2{padding-block:calc(var(--spacing)*10)}._pb-24_1pedq_2{padding-bottom:calc(var(--spacing)*24)}._pl-5\!_1pedq_2{padding-left:calc(var(--spacing)*5)!important}._text-center_1pedq_2{text-align:center}._text-left_1pedq_2{text-align:left}._font-mono_1pedq_2{font-family:var(--font-mono)}._text-3xl_1pedq_2{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}._text-lg_1pedq_2{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}._text-sm_1pedq_2{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}._text-xl_1pedq_2{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}._text-xs_1pedq_2{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}._text-xs\!_1pedq_2{font-size:var(--text-xs)!important;line-height:var(--tw-leading,var(--text-xs--line-height))!important}._font-semibold_1pedq_2{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}._whitespace-nowrap_1pedq_2{white-space:nowrap}._text-\(--text-color-primary\)_1pedq_2{color:var(--text-color-primary)}._text-\(--text-color-secondary\)_1pedq_2{color:var(--text-color-secondary)}._text-black\/30_1pedq_2{color:#0000004d}@supports (color:color-mix(in lab,red,red)){._text-black\/30_1pedq_2{color:color-mix(in oklab,var(--color-black)30%,transparent)}}._text-blue-600_1pedq_2{color:var(--color-blue-600)}._text-blue-800_1pedq_2{color:var(--color-blue-800)}._text-gray-100_1pedq_2{color:var(--color-gray-100)}._text-gray-200_1pedq_2{color:var(--color-gray-200)}._text-gray-300_1pedq_2{color:var(--color-gray-300)}._text-gray-600_1pedq_2{color:var(--color-gray-600)}._text-green-800_1pedq_2{color:var(--color-green-800)}._text-red-500_1pedq_2{color:var(--color-red-500)}._text-red-600_1pedq_2{color:var(--color-red-600)}._text-white_1pedq_2{color:var(--color-white)}._text-yellow-800_1pedq_2{color:var(--color-yellow-800)}._capitalize_1pedq_2{text-transform:capitalize}._italic_1pedq_2{font-style:italic}._underline_1pedq_2{text-decoration-line:underline}._opacity-30_1pedq_2{opacity:.3}._opacity-40_1pedq_2{opacity:.4}._shadow-md_1pedq_2{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}._blur_1pedq_2{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}._filter_1pedq_2{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}._outline-none_1pedq_2{--tw-outline-style:none;outline-style:none}@media(hover:hover){._hover\:bg-gray-100_1pedq_2:hover{background-color:var(--color-gray-100)}._hover\:bg-gray-600_1pedq_2:hover{background-color:var(--color-gray-600)}}@media(min-width:48rem){._md\:grid_1pedq_2{display:grid}._md\:w-2xl_1pedq_2{width:var(--container-2xl)}._md\:grid-cols-3_1pedq_2{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(min-width:64rem){._lg\:w-lg_1pedq_2{width:var(--container-lg)}._lg\:w-sm_1pedq_2{width:var(--container-sm)}._lg\:flex-row_1pedq_2{flex-direction:row}._lg\:items-center_1pedq_2{align-items:center}._lg\:pb-12_1pedq_2{padding-bottom:calc(var(--spacing)*12)}}@media(prefers-color-scheme:dark){._dark\:text-gray-600_1pedq_2{color:var(--color-gray-600)}}}._alert_1pedq_2{padding:calc(var(--spacing)*4);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}._info_1pedq_2{background-color:var(--color-blue-50);color:var(--color-blue-800)}._danger_1pedq_2{background-color:var(--color-red-50);color:var(--color-red-800)}._success_1pedq_2{background-color:var(--color-green-50);color:var(--color-green-800)}._warning_1pedq_2{background-color:var(--color-yellow-50);color:var(--color-yellow-800)}._dark_1pedq_2{background-color:var(--color-gray-50);color:var(--color-gray-800)}@keyframes _spin_1pedq_1{to{transform:rotate(360deg)}}@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-outline-style:solid}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-yellow-200:oklch(94.5% .129 101.54);--color-yellow-800:oklch(47.6% .114 61.907);--color-green-200:oklch(92.5% .084 155.995);--color-green-800:oklch(44.8% .119 151.328);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-semibold:600;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--animate-spin:spin 1s linear infinite;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--bg:#fff;--bg-sec:#f9f9f9;--bg-ter:#f2f2f2;--bg-quat:#e9e9e9;--text-color-primary:#212121;--text-color-secondary:#6b6b6b}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components{.hotkey{cursor:pointer;border-radius:var(--radius-sm);text-align:center;min-width:26px;max-width:26px;min-height:22px;max-height:22px;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);justify-content:center;align-items:center;display:none}@media(min-width:64rem){.hotkey{display:flex}}.hotkey.secondary{border:1px solid var(--bg-ter);background-color:var(--bg)}.hotkey:not(.secondary){border:1px solid var(--bg-ter);background-color:var(--bg-sec)}.comfortaa{font-family:Comfortaa,sans-serif}}@layer utilities{.pointer-events-none{pointer-events:none}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.top-0{top:calc(var(--spacing)*0)}.top-2{top:calc(var(--spacing)*2)}.right-2{right:calc(var(--spacing)*2)}.z-0{z-index:0}.z-1{z-index:1}.z-10{z-index:10}.z-100{z-index:100}.col-span-2{grid-column:span 2/span 2}.m-2{margin:calc(var(--spacing)*2)}.mx-1{margin-inline:calc(var(--spacing)*1)}.mx-2{margin-inline:calc(var(--spacing)*2)}.mx-auto{margin-inline:auto}.my-2{margin-block:calc(var(--spacing)*2)}.my-10{margin-block:calc(var(--spacing)*10)}.prose{color:var(--tw-prose-body);max-width:65ch}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);margin-top:1.2em;margin-bottom:1.2em;font-size:1.25em;line-height:1.6}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);font-weight:500;text-decoration:underline}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:decimal}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:disc}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-counters);font-weight:400}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.25em;font-weight:600}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em;font-style:italic;font-weight:500}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:0;margin-bottom:.888889em;font-size:2.25em;font-weight:800;line-height:1.11111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:900}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:2em;margin-bottom:1em;font-size:1.5em;font-weight:700;line-height:1.33333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:800}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.6em;margin-bottom:.6em;font-size:1.25em;font-weight:600;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.5em;margin-bottom:.5em;font-weight:600;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em;display:block}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-kbd);box-shadow:0 0 0 1px var(--tw-prose-kbd-shadows),0 3px 0 var(--tw-prose-kbd-shadows);padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;border-radius:.3125rem;padding-inline-start:.375em;font-family:inherit;font-size:.875em;font-weight:500}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-size:.875em;font-weight:600}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);padding-top:.857143em;padding-inline-end:1.14286em;padding-bottom:.857143em;border-radius:.375rem;margin-top:1.71429em;margin-bottom:1.71429em;padding-inline-start:1.14286em;font-size:.875em;font-weight:400;line-height:1.71429;overflow-x:auto}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit;background-color:#0000;border-width:0;border-radius:0;padding:0}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){table-layout:auto;width:100%;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.71429}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);vertical-align:bottom;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em;font-weight:600}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);margin-top:.857143em;font-size:.875em;line-height:1.42857}.prose{--tw-prose-body:oklch(37.3% .034 259.733);--tw-prose-headings:oklch(21% .034 264.665);--tw-prose-lead:oklch(44.6% .03 256.802);--tw-prose-links:oklch(21% .034 264.665);--tw-prose-bold:oklch(21% .034 264.665);--tw-prose-counters:oklch(55.1% .027 264.364);--tw-prose-bullets:oklch(87.2% .01 258.338);--tw-prose-hr:oklch(92.8% .006 264.531);--tw-prose-quotes:oklch(21% .034 264.665);--tw-prose-quote-borders:oklch(92.8% .006 264.531);--tw-prose-captions:oklch(55.1% .027 264.364);--tw-prose-kbd:oklch(21% .034 264.665);--tw-prose-kbd-shadows:oklab(21% -.00316127 -.0338527/.1);--tw-prose-code:oklch(21% .034 264.665);--tw-prose-pre-code:oklch(92.8% .006 264.531);--tw-prose-pre-bg:oklch(27.8% .033 256.848);--tw-prose-th-borders:oklch(87.2% .01 258.338);--tw-prose-td-borders:oklch(92.8% .006 264.531);--tw-prose-invert-body:oklch(87.2% .01 258.338);--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:oklch(70.7% .022 261.325);--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:oklch(70.7% .022 261.325);--tw-prose-invert-bullets:oklch(44.6% .03 256.802);--tw-prose-invert-hr:oklch(37.3% .034 259.733);--tw-prose-invert-quotes:oklch(96.7% .003 264.542);--tw-prose-invert-quote-borders:oklch(37.3% .034 259.733);--tw-prose-invert-captions:oklch(70.7% .022 261.325);--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:#ffffff1a;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:oklch(87.2% .01 258.338);--tw-prose-invert-pre-bg:#00000080;--tw-prose-invert-th-borders:oklch(44.6% .03 256.802);--tw-prose-invert-td-borders:oklch(37.3% .034 259.733);font-size:1rem;line-height:1.75}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.571429em;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-10{margin-top:calc(var(--spacing)*10)}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-2{margin-right:calc(var(--spacing)*2)}.mb-0\.5{margin-bottom:calc(var(--spacing)*.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-10{margin-bottom:calc(var(--spacing)*10)}.ml-1{margin-left:calc(var(--spacing)*1)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.table{display:table}.h-0\.5{height:calc(var(--spacing)*.5)}.h-1{height:calc(var(--spacing)*1)}.h-8{height:calc(var(--spacing)*8)}.h-screen{height:100vh}.max-h-full{max-height:100%}.max-h-screen{max-height:100vh}.min-h-screen{min-height:100vh}.w-8{width:calc(var(--spacing)*8)}.w-full{width:100%}.max-w-none{max-width:none}.max-w-xl{max-width:var(--container-xl)}.flex-1{flex:1}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-auto\!{cursor:auto!important}.cursor-pointer{cursor:pointer}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-8{gap:calc(var(--spacing)*8)}.justify-self-center{justify-self:center}.justify-self-end{justify-self:flex-end}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-t-md{border-top-left-radius:var(--radius-md);border-top-right-radius:var(--radius-md)}.rounded-r-none\!{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.rounded-b-lg{border-bottom-right-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.rounded-b-md{border-bottom-right-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-gray-200{border-color:var(--color-gray-200)}.border-red-600{border-color:var(--color-red-600)}.border-t-gray-200{border-top-color:var(--color-gray-200)}.bg-\(--bg\){background-color:var(--bg)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-800{background-color:var(--color-gray-800)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-green-200{background-color:var(--color-green-200)}.bg-white{background-color:var(--color-white)}.bg-yellow-200{background-color:var(--color-yellow-200)}.fill-blue-600{fill:var(--color-blue-600)}.p-0\.5{padding:calc(var(--spacing)*.5)}.p-1{padding:calc(var(--spacing)*1)}.p-2{padding:calc(var(--spacing)*2)}.p-4{padding:calc(var(--spacing)*4)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-4{padding-inline:calc(var(--spacing)*4)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-2{padding-block:calc(var(--spacing)*2)}.py-4{padding-block:calc(var(--spacing)*4)}.py-10{padding-block:calc(var(--spacing)*10)}.pb-24{padding-bottom:calc(var(--spacing)*24)}.pl-5\!{padding-left:calc(var(--spacing)*5)!important}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-xs\!{font-size:var(--text-xs)!important;line-height:var(--tw-leading,var(--text-xs--line-height))!important}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-\(--text-color-primary\){color:var(--text-color-primary)}.text-\(--text-color-secondary\){color:var(--text-color-secondary)}.text-black\/30{color:#0000004d}@supports (color:color-mix(in lab,red,red)){.text-black\/30{color:color-mix(in oklab,var(--color-black)30%,transparent)}}.text-blue-600{color:var(--color-blue-600)}.text-blue-800{color:var(--color-blue-800)}.text-gray-100{color:var(--color-gray-100)}.text-gray-200{color:var(--color-gray-200)}.text-gray-300{color:var(--color-gray-300)}.text-gray-600{color:var(--color-gray-600)}.text-green-800{color:var(--color-green-800)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-white{color:var(--color-white)}.text-yellow-800{color:var(--color-yellow-800)}.capitalize{text-transform:capitalize}.italic{font-style:italic}.underline{text-decoration-line:underline}.opacity-30{opacity:.3}.opacity-40{opacity:.4}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.outline-none{--tw-outline-style:none;outline-style:none}@media(hover:hover){.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-600:hover{background-color:var(--color-gray-600)}}@media(min-width:48rem){.md\:grid{display:grid}.md\:w-2xl{width:var(--container-2xl)}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(min-width:64rem){.lg\:w-lg{width:var(--container-lg)}.lg\:w-sm{width:var(--container-sm)}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:pb-12{padding-bottom:calc(var(--spacing)*12)}}@media(prefers-color-scheme:dark){.dark\:text-gray-600{color:var(--color-gray-600)}}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}.scrollbar::-webkit-scrollbar{border-radius:10pt;width:5px}.scrollbar::-webkit-scrollbar-track{background-color:var(--color-gray-100);border-radius:10px}.scrollbar::-webkit-scrollbar-thumb{background-color:var(--color-gray-300);border-radius:10px}.scrollbar::-webkit-scrollbar-thumb:hover{background-color:var(--color-gray-400)}}.page-container{max-width:100%;padding:calc(var(--spacing)*4)}.page-content{width:100%;max-width:1024px;padding-bottom:calc(var(--spacing)*12);flex-direction:column;margin-left:auto;margin-right:auto;display:flex}@media(min-width:48rem){.page-content{padding-bottom:calc(var(--spacing)*0)}}.hr-slide{cursor:col-resize;-webkit-user-select:none;user-select:none;z-index:1;width:8px;height:100%;position:absolute;right:-4px}@media(hover:hover){.hr-slide:hover{background-color:var(--color-blue-200)}}.hl-slide{cursor:col-resize;-webkit-user-select:none;user-select:none;z-index:1;width:8px;height:100%;position:absolute;left:-4px}@media(hover:hover){.hl-slide:hover{background-color:var(--color-blue-200)}}.vb-slide{cursor:row-resize;-webkit-user-select:none;user-select:none;z-index:1;width:100%;height:8px;position:absolute;bottom:-4px}@media(hover:hover){.vb-slide:hover{background-color:var(--color-blue-200)}}.vt-slide{cursor:row-resize;-webkit-user-select:none;user-select:none;z-index:1;width:100%;height:8px;position:absolute;top:-4px}@media(hover:hover){.vt-slide:hover{background-color:var(--color-blue-200)}}.input{border:1px solid var(--bg-quat);background-color:var(--color-white);padding:calc(var(--spacing)*1);outline-style:var(--tw-outline-style);border-radius:.25rem;outline-width:0}.input:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--color-blue-400);--tw-ring-inset:inset}.input:disabled{cursor:not-allowed;background-color:var(--bg-ter)}.form{gap:calc(var(--spacing)*2);background-color:var(--color-white);flex-direction:column;display:flex}.form.shadow{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.form.padding{padding:calc(var(--spacing)*4)}.button{cursor:pointer;border-radius:var(--radius-md);padding-inline:calc(var(--spacing)*2);padding-block:calc(var(--spacing)*.5);--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.button:disabled{opacity:.6;cursor:not-allowed}.button.primary{border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-blue-600);background-color:var(--color-blue-600);color:var(--color-white)}.button.primary:hover:not(:disabled){border-color:var(--color-blue-700);background-color:var(--color-blue-700)}.button.secondary{background-color:var(--color-gray-300);color:var(--color-gray-800)}.button.tertiary{border:1px solid var(--bg-quat);background-color:var(--color-white);color:var(--color-gray-700)}.button.tertiary:hover{background-color:var(--bg-sec)}.button.danger{color:#fff;background-color:#dc3545}.button.danger:hover{background-color:#bf2e3c}.page-head{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.roboto{font-family:Roboto,sans-serif}.context-menu-container{border-radius:var(--radius-lg);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-gray-200);background-color:var(--color-white);min-width:150px;max-width:400px;max-height:400px;padding:calc(var(--spacing)*2);--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);overflow:hidden}.context-menu-item{cursor:pointer;border-radius:var(--radius-lg);text-align:left;text-overflow:ellipsis;white-space:nowrap;width:100%;padding:2px 4px;font-size:15px;display:block;overflow:hidden}@media(hover:hover){.context-menu-item:hover{background-color:var(--color-gray-100)}}.a{color:var(--color-blue-400);text-decoration-line:underline}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@keyframes spin{to{transform:rotate(360deg)}}
|