@kazurolabs/psql-explorer 0.0.0-stage → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +505 -2
  3. package/RELEASES.md +87 -0
  4. package/dist/app.js +39 -0
  5. package/dist/cli.js +307 -0
  6. package/dist/commands/configgen.js +128 -0
  7. package/dist/commands/explore.js +388 -0
  8. package/dist/commands/terminal-prompt.js +68 -0
  9. package/dist/config/load.js +324 -0
  10. package/dist/config/resolve-environment.js +112 -0
  11. package/dist/config/resolvers/env.js +12 -0
  12. package/dist/config/resolvers/file.js +24 -0
  13. package/dist/config/resolvers/groups.js +1 -0
  14. package/dist/config/resolvers/index.js +49 -0
  15. package/dist/config/resolvers/literal.js +7 -0
  16. package/dist/config/resolvers/prompt.js +159 -0
  17. package/dist/config/resolvers/stored.js +13 -0
  18. package/dist/config/resolvers/types.js +18 -0
  19. package/dist/config/resolvers/vault.js +283 -0
  20. package/dist/config/schema.js +24 -0
  21. package/dist/config/source.js +105 -0
  22. package/dist/db/connect.js +55 -0
  23. package/dist/db/identifiers.js +6 -0
  24. package/dist/db/paths.js +14 -0
  25. package/dist/db/store.js +323 -0
  26. package/dist/db/tester.js +190 -0
  27. package/dist/db/validate.js +99 -0
  28. package/dist/environments.js +140 -0
  29. package/dist/explorer/alter.js +493 -0
  30. package/dist/explorer/catalog.js +414 -0
  31. package/dist/explorer/connect-entry.js +42 -0
  32. package/dist/explorer/cypher-parse.js +478 -0
  33. package/dist/explorer/cypher.js +963 -0
  34. package/dist/explorer/ddl.js +502 -0
  35. package/dist/explorer/dependents.js +222 -0
  36. package/dist/explorer/design-load.js +254 -0
  37. package/dist/explorer/design.js +45 -0
  38. package/dist/explorer/edit.js +108 -0
  39. package/dist/explorer/explain.js +37 -0
  40. package/dist/explorer/filter.js +121 -0
  41. package/dist/explorer/format.js +134 -0
  42. package/dist/explorer/graph.js +679 -0
  43. package/dist/explorer/gucs.js +31 -0
  44. package/dist/explorer/profile.js +102 -0
  45. package/dist/explorer/references.js +95 -0
  46. package/dist/explorer/rows.js +64 -0
  47. package/dist/explorer/schema-diff.js +360 -0
  48. package/dist/explorer/search.js +309 -0
  49. package/dist/explorer/security.js +152 -0
  50. package/dist/explorer/seed.js +1376 -0
  51. package/dist/explorer/session.js +122 -0
  52. package/dist/explorer/stats.js +135 -0
  53. package/dist/explorer/timeout.js +13 -0
  54. package/dist/prompts.js +52 -0
  55. package/dist/screens/environments.js +229 -0
  56. package/dist/screens/explorer.js +145 -0
  57. package/dist/screens/header.js +8 -0
  58. package/dist/screens/index.js +13 -0
  59. package/dist/screens/new-connection.js +178 -0
  60. package/dist/screens/panes/common.js +35 -0
  61. package/dist/screens/panes/history.js +36 -0
  62. package/dist/screens/panes/info.js +61 -0
  63. package/dist/screens/panes/query.js +113 -0
  64. package/dist/screens/panes/table.js +178 -0
  65. package/dist/screens/panes/tables.js +142 -0
  66. package/dist/screens/prompt-modal.js +18 -0
  67. package/dist/screens/record-view.js +42 -0
  68. package/dist/screens/result-grid.js +126 -0
  69. package/dist/screens/scroll.js +12 -0
  70. package/dist/screens/splash.js +78 -0
  71. package/dist/screens/terminal.js +25 -0
  72. package/dist/screens/types.js +1 -0
  73. package/dist/services.js +1 -0
  74. package/dist/startup.js +84 -0
  75. package/dist/web/server.js +988 -0
  76. package/package.json +69 -5
  77. package/web/dist/assets/anton-latin-400-normal-AUNGEG_V.woff +0 -0
  78. package/web/dist/assets/anton-latin-400-normal-Byf51wtH.woff2 +0 -0
  79. package/web/dist/assets/anton-latin-ext-400-normal-BMODBQc6.woff +0 -0
  80. package/web/dist/assets/anton-latin-ext-400-normal-SyiqE2Jt.woff2 +0 -0
  81. package/web/dist/assets/anton-vietnamese-400-normal-2FfR1wHA.woff +0 -0
  82. package/web/dist/assets/anton-vietnamese-400-normal-CkBxLiRJ.woff2 +0 -0
  83. package/web/dist/assets/antonio-latin-400-normal-B7iMKlzw.woff +0 -0
  84. package/web/dist/assets/antonio-latin-400-normal-CZjzwNAN.woff2 +0 -0
  85. package/web/dist/assets/antonio-latin-700-normal-BY3mCh47.woff +0 -0
  86. package/web/dist/assets/antonio-latin-700-normal-DSH-lEDG.woff2 +0 -0
  87. package/web/dist/assets/antonio-latin-ext-400-normal-nE82dizb.woff2 +0 -0
  88. package/web/dist/assets/antonio-latin-ext-400-normal-qA9Jb92z.woff +0 -0
  89. package/web/dist/assets/antonio-latin-ext-700-normal-BdSkr58W.woff +0 -0
  90. package/web/dist/assets/antonio-latin-ext-700-normal-D-dvgqjr.woff2 +0 -0
  91. package/web/dist/assets/button-ClA70PLR.js +1 -0
  92. package/web/dist/assets/code-xml-CXkpHeU9.js +1 -0
  93. package/web/dist/assets/compare-view-DKl5l_Jw.js +2 -0
  94. package/web/dist/assets/copy-CCXzeW-s.js +1 -0
  95. package/web/dist/assets/cypher-view-Pd0WFH8F.js +13 -0
  96. package/web/dist/assets/design-view-CIHSmH4u.js +9 -0
  97. package/web/dist/assets/erd-view-CV7mFGAN.js +1 -0
  98. package/web/dist/assets/format-sql-BLj5_RDZ.js +5 -0
  99. package/web/dist/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  100. package/web/dist/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  101. package/web/dist/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  102. package/web/dist/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  103. package/web/dist/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  104. package/web/dist/assets/graph-force-yBLyErpS.js +1 -0
  105. package/web/dist/assets/graph-link-OCo_s0zO.js +1 -0
  106. package/web/dist/assets/graph-view-sM1OlByf.js +3 -0
  107. package/web/dist/assets/index-CDcnUacl.js +10 -0
  108. package/web/dist/assets/index-OzJqnJWG.css +2 -0
  109. package/web/dist/assets/key-round-Cv_7QeED.js +1 -0
  110. package/web/dist/assets/loader-circle-BK_GMdvN.js +1 -0
  111. package/web/dist/assets/orbitron-latin-700-normal-4jsRXGGJ.woff2 +0 -0
  112. package/web/dist/assets/orbitron-latin-700-normal-DmYOh-W9.woff +0 -0
  113. package/web/dist/assets/orbitron-latin-900-normal-BbJatbhp.woff +0 -0
  114. package/web/dist/assets/orbitron-latin-900-normal-DrIi7unX.woff2 +0 -0
  115. package/web/dist/assets/query-builder-view-ChNFb51g.js +4 -0
  116. package/web/dist/assets/rotate-ccw-CdCaf7Q6.js +1 -0
  117. package/web/dist/assets/route-DO6IZ7of.js +15 -0
  118. package/web/dist/assets/seed-view-DFNB8WHE.js +7 -0
  119. package/web/dist/assets/share-tech-mono-latin-400-normal-15MgdvEM.woff +0 -0
  120. package/web/dist/assets/share-tech-mono-latin-400-normal-CCqdbj5z.woff2 +0 -0
  121. package/web/dist/assets/shield-alert-CMS-3j4U.js +1 -0
  122. package/web/dist/assets/sliders-horizontal-Dg51yc-C.js +1 -0
  123. package/web/dist/assets/sql-tabs-B4jt6bQj.js +2 -0
  124. package/web/dist/assets/table-DfMz2f8M.js +1 -0
  125. package/web/dist/assets/triangle-alert-COGnHCD1.js +1 -0
  126. package/web/dist/assets/zone-D9dXk8tn.js +5 -0
  127. package/web/dist/index.html +26 -0
package/package.json CHANGED
@@ -1,6 +1,70 @@
1
1
  {
2
- "name": "@kazurolabs/psql-explorer",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
2
+ "name": "@kazurolabs/psql-explorer",
3
+ "version": "0.3.0",
4
+ "description": "Explore your Postgres databases from the terminal, with credentials from Vault",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "psql-explorer": "dist/cli.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "web/dist",
13
+ "README.md",
14
+ "RELEASES.md",
15
+ "LICENSE"
16
+ ],
17
+ "engines": {
18
+ "node": ">=22.13"
19
+ },
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "scripts": {
24
+ "build": "tsc && npm run build:web",
25
+ "dev": "tsx scripts/dev.mjs",
26
+ "test": "vitest run",
27
+ "typecheck": "tsc -p tsconfig.test.json",
28
+ "lint": "npm run typecheck && eslint . && prettier --check .",
29
+ "format": "prettier --write .",
30
+ "prepublishOnly": "npm run install:web && npm run build",
31
+ "dev:reset": "tsx scripts/dev.mjs --reset",
32
+ "dev:plain": "tsx src/cli.tsx",
33
+ "build:web": "npm --prefix web run build",
34
+ "dev:web": "tsx scripts/dev-web.mjs",
35
+ "dev:web:reset": "tsx scripts/dev-web.mjs --reset",
36
+ "install:web": "npm --prefix web install",
37
+ "dev:vite": "npm --prefix web run dev"
38
+ },
39
+ "dependencies": {
40
+ "@faker-js/faker": "^10.6.0",
41
+ "ink": "^8.0.0",
42
+ "ink-big-text": "^2.0.0",
43
+ "ink-gradient": "^4.0.1",
44
+ "ink-spinner": "^5.0.0",
45
+ "ink-text-input": "^6.0.0",
46
+ "meow": "^14.1.0",
47
+ "pg": "^8.23.1",
48
+ "pg-cursor": "^2.22.1",
49
+ "react": "^19.3.1",
50
+ "string-width": "^8.3.0",
51
+ "yaml": "^2.9.1"
52
+ },
53
+ "devDependencies": {
54
+ "@eslint/js": "^10.0.1",
55
+ "@types/node": "^22.20.5",
56
+ "@types/pg": "^8.23.1",
57
+ "@types/pg-cursor": "^2.7.2",
58
+ "@types/react": "^19.3.0",
59
+ "eslint": "^10.13.0",
60
+ "eslint-config-prettier": "^10.1.8",
61
+ "eslint-plugin-react-hooks": "^7.1.1",
62
+ "globals": "^17.13.0",
63
+ "ink-testing-library": "^4.0.0",
64
+ "prettier": "^3.9.10",
65
+ "tsx": "^4.23.15",
66
+ "typescript": "~6.0.3",
67
+ "typescript-eslint": "^8.72.1",
68
+ "vitest": "^5.0.5"
69
+ }
70
+ }
@@ -0,0 +1 @@
1
+ import{at as e,ct as t,it as n,ot as r,rt as i}from"./route-DO6IZ7of.js";var a={name:`check`,size:24,node:[[`path`,{d:`M20 6 9 17l-5-5`,key:`1gmf2c`}]]};a.node;var o=e(a);function s(e,t){if(e&&!t)return e;if(!e&&t)return t;if(e||t)return{...e,...t}}var c={};function l(e,t,n,r,i){if(!n&&!r&&!i&&!e)return d(t);let a=d(e);return t&&(a=f(a,t)),n&&(a=f(a,n)),r&&(a=f(a,r)),i&&(a=f(a,i)),a}function u(e){if(e.length===0)return c;if(e.length===1)return d(e[0]);let t=d(e[0]);for(let n=1;n<e.length;n+=1)t=f(t,e[n]);return t}function d(e){return h(e)?{...e(c)}:p(e)}function f(e,t){return h(t)?t(e):ee(e,t)}function p(e){let t={...e};for(let e in t){let n=t[e];m(e,n)&&(t[e]=g(n))}return t}function ee(e,t){if(!t)return e;for(let n in t){let r=t[n];switch(n){case`style`:e[n]=s(e.style,r);break;case`className`:e[n]=v(e.className,r);break;default:e[n]=m(n,r)?te(e[n],r):r}}return e}function m(e,t){let n=e.charCodeAt(0),r=e.charCodeAt(1),i=e.charCodeAt(2);return n===111&&r===110&&i>=65&&i<=90&&(typeof t==`function`||t===void 0)}function h(e){return typeof e==`function`}function te(e,t){return t?e?(...n)=>{let r=n[0];if(y(r)){let i=r;_(i);let a=t(...n);return i.baseUIHandlerPrevented||e?.(...n),a}let i=t(...n);return e?.(...n),i}:g(t):e}function g(e){return e&&((...t)=>{let n=t[0];return y(n)&&_(n),e(...t)})}function _(e){return e.preventBaseUIHandler=()=>{e.baseUIHandlerPrevented=!0},e}function v(e,t){return t?e?t+` `+e:t:e}function y(e){return typeof e==`object`&&!!e&&`nativeEvent`in e}var b=t(r(),1),x={};function S(e,t){let n=b.useRef(x);return n.current===x&&(n.current=e(t)),n}function C(e,t,n,r){let i=S(w).current;return re(i,e,t,n,r)&&ae(i,[e,t,n,r]),i.callback}function ne(e){let t=S(w).current;return ie(t,e)&&ae(t,e),t.callback}function w(){return{callback:null,cleanup:null,refs:[]}}function re(e,t,n,r,i){return e.refs[0]!==t||e.refs[1]!==n||e.refs[2]!==r||e.refs[3]!==i}function ie(e,t){return e.refs.length!==t.length||e.refs.some((e,n)=>e!==t[n])}function ae(e,t){e.refs=t,e.callback=t.every(e=>e==null)?null:n=>{if(e.cleanup&&=(e.cleanup(),null),n!=null){let r=Array(t.length).fill(null);for(let e=0;e<t.length;e+=1){let i=t[e];if(i!=null)switch(typeof i){case`function`:{let t=i(n);typeof t==`function`&&(r[e]=t);break}case`object`:i.current=n}}e.cleanup=()=>{for(let e=0;e<t.length;e+=1){let n=t[e];if(n!=null)switch(typeof n){case`function`:{let t=r[e];typeof t==`function`?t():n(null);break}case`object`:n.current=null}}}}}}var oe=19;function se(e){return oe>=e}function ce(e){if(!b.isValidElement(e))return null;let t=e,n=t.props;return(se(19)?n?.ref:t.ref)??null}function le(){}var ue=Object.freeze([]),T=Object.freeze({});function de(e,t){let n={};for(let r in e){let i=e[r];if(t?.hasOwnProperty(r)){let e=t[r](i);e!=null&&Object.assign(n,e)}else i===!0?n[`data-${r.toLowerCase()}`]=``:i&&(n[`data-${r.toLowerCase()}`]=i.toString())}return n}function fe(e,t){return typeof e==`function`?e(t):e}function pe(e,t){return typeof e==`function`?e(t):e}function E(e,t,n={}){let r=t.render;n.enabled!==!1&&(r=D(r));let i=me(t,n,r);if(n.enabled===!1)return null;let a=n.state??T;return _e(e,r,i,a)}function me(e,t,n){let{className:r,style:i}=e,{state:a=T,ref:o,props:c,stateAttributesMapping:l,enabled:u=!0}=t,d=u?fe(r,a):void 0,f=u?pe(i,a):void 0,p=u?de(a,l):T,ee=u&&c?he(c):void 0,m=u?s(p,ee)??{}:T;return typeof document<`u`&&(u?m.ref=Array.isArray(o)?ne([m.ref,ce(n),...o]):C(m.ref,ce(n),o):C(null,null)),u?(d!==void 0&&(m.className=v(m.className,d)),f!==void 0&&(m.style=s(m.style,f)),m):T}function he(e){return Array.isArray(e)?u(e):l(void 0,e)}var ge=Symbol.for(`react.lazy`);function D(e){if(e?.$$typeof!==ge)return e;let t=b.Children.toArray(e)[0];return b.isValidElement(t)?t:e}function _e(e,t,n,r){if(t){if(typeof t==`function`)return t(n,r);let e=l(n,t.props);return e.ref=n.ref,b.cloneElement(t,e)}return ve(e,n)}function ve(e,t){return e===`button`?(0,b.createElement)(`button`,{type:`button`,...t,key:t.key}):e===`img`?(0,b.createElement)(`img`,{alt:``,...t,key:t.key}):b.createElement(e,t)}function O(e){var t,n,r=``;if(typeof e==`string`||typeof e==`number`)r+=e;else if(typeof e==`object`){if(Array.isArray(e)){var i=e.length;for(t=0;t<i;t++)e[t]&&(n=O(e[t]))&&(r&&(r+=` `),r+=n)}else for(n in e)e[n]&&(r&&(r+=` `),r+=n)}return r}function ye(){for(var e,t,n=0,r=``,i=arguments.length;n<i;n++)(e=arguments[n])&&(t=O(e))&&(r&&(r+=` `),r+=t);return r}var k=e=>typeof e==`boolean`?`${e}`:e===0?`0`:e,A=ye,j=(e,t)=>n=>{if(t?.variants==null)return A(e,n?.class,n?.className);let{variants:r,defaultVariants:i}=t,a=Object.keys(r).map(e=>{let t=n?.[e],a=i?.[e];if(t===null)return null;let o=k(t)||k(a);return r[e][o]}),o=n&&Object.entries(n).reduce((e,t)=>{let[n,r]=t;return r===void 0||(e[n]=r),e},{});return A(e,a,t?.compoundVariants?.reduce((e,t)=>{let{class:n,className:r,...a}=t;return Object.entries(a).every(e=>{let[t,n]=e;return Array.isArray(n)?n.includes({...i,...o}[t]):{...i,...o}[t]===n})?[...e,n,r]:e},[]),n?.class,n?.className)};function M(){return typeof window<`u`}function N(e){return I(e)?(e.nodeName||``).toLowerCase():`#document`}function P(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function F(e){return((I(e)?e.ownerDocument:e.document)||window.document)?.documentElement}function I(e){return M()?e instanceof Node||e instanceof P(e).Node:!1}function L(e){return M()?e instanceof Element||e instanceof P(e).Element:!1}function R(e){return M()?e instanceof HTMLElement||e instanceof P(e).HTMLElement:!1}function z(e){return!M()||typeof ShadowRoot>`u`?!1:e instanceof ShadowRoot||e instanceof P(e).ShadowRoot}function B(e){let{overflow:t,overflowX:n,overflowY:r,display:i}=K(e);return/auto|scroll|overlay|hidden|clip/.test(t+r+n)&&i!==`inline`&&i!==`contents`}function be(e){return/^(table|td|th)$/.test(N(e))}function V(e){try{if(e.matches(`:popover-open`))return!0}catch{}try{return e.matches(`:modal`)}catch{return!1}}var xe=/transform|translate|scale|rotate|perspective|filter/,Se=/paint|layout|strict|content/,H=e=>!!e&&e!==`none`,Ce;function U(e){let t=L(e)?K(e):e;return H(t.transform)||H(t.translate)||H(t.scale)||H(t.rotate)||H(t.perspective)||!W()&&(H(t.backdropFilter)||H(t.filter))||xe.test(t.willChange||``)||Se.test(t.contain||``)}function we(e){let t=q(e);for(;R(t)&&!G(t);){if(U(t))return t;if(V(t))return null;t=q(t)}return null}function W(){return Ce??=typeof CSS<`u`&&CSS.supports&&CSS.supports(`-webkit-backdrop-filter`,`none`),Ce}function G(e){return/^(html|body|#document)$/.test(N(e))}function K(e){return P(e).getComputedStyle(e)}function Te(e){return L(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function q(e){if(N(e)===`html`)return e;let t=e.assignedSlot||e.parentNode||z(e)&&e.host||F(e);return z(t)?t.host:t}function Ee(e){let t=q(e);return G(t)?(e.ownerDocument||e).body:R(t)&&B(t)?t:Ee(t)}function J(e,t,n){t===void 0&&(t=[]),n===void 0&&(n=!0);let r=Ee(e),i=r===e.ownerDocument?.body,a=P(r);if(i){let e=De(a);return t.concat(a,a.visualViewport||[],B(r)?r:[],e&&n?J(e):[])}return t.concat(r,J(r,[],n))}function De(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}var Y={...b},X=Y.useInsertionEffect,Oe=X&&X!==Y.useLayoutEffect?X:e=>e();function ke(e){let t=S(Ae).current;return t.next=e,Oe(t.effect),t.trampoline}function Ae(){let e={next:void 0,callback:je,trampoline:(...t)=>e.callback?.(...t),effect:()=>{e.callback=e.next}};return e}function je(){}var Me=typeof document<`u`?b.useLayoutEffect:()=>{};function Ne(e,t){return function(n,...r){let i=new URL(e);return i.searchParams.set(`code`,n.toString()),r.forEach(e=>i.searchParams.append(`args[]`,e)),`${t} error #${n}; visit ${i} for the full message.`}}var Pe=Ne(`https://base-ui.com/production-error`,`Base UI`),Fe=b.createContext(void 0);function Ie(e=!1){let t=b.useContext(Fe);if(t===void 0&&!e)throw Error(Pe(16));return t}function Le(e){let{focusableWhenDisabled:t,disabled:n,composite:r=!1,tabIndex:i=0,isNativeButton:a}=e,o=r&&t!==!1,s=r&&t===!1;return{props:b.useMemo(()=>{let e={onKeyDown(e){n&&t&&e.key!==`Tab`&&e.preventDefault()}};return r||(e.tabIndex=i,!a&&n&&(e.tabIndex=t?i:-1)),(a&&(t||o)||!a&&n)&&(e[`aria-disabled`]=n),a&&(!t||s)&&(e.disabled=n),e},[r,n,t,o,s,a,i])}}function Z(e,t,{detail:n=0,pointerType:r=``}={}){e.dispatchEvent(new(P(e)).PointerEvent(`click`,{bubbles:!0,cancelable:!0,composed:!0,detail:n,pointerType:r,shiftKey:t.shiftKey,ctrlKey:t.ctrlKey,altKey:t.altKey,metaKey:t.metaKey}))}function Q(e={}){let{disabled:t=!1,focusableWhenDisabled:n,tabIndex:r=0,native:i=!0,composite:a}=e,o=b.useRef(null),s=Ie(!0),c=a??s!==void 0,{props:u}=Le({focusableWhenDisabled:n,disabled:t,composite:c,tabIndex:r,isNativeButton:i}),d=b.useCallback(()=>{let e=o.current;$(e)&&c&&t&&u.disabled===void 0&&e.disabled&&(e.disabled=!1)},[t,u.disabled,c]);return Me(d,[d]),{getButtonProps:b.useCallback((e={})=>{let{onClick:n,onMouseDown:r,onKeyUp:a,onKeyDown:o,onPointerDown:s,...d}=e;return l({onClick(e){t?e.preventDefault():n?.(e)},onMouseDown(e){t||r?.(e)},onKeyDown(e){if(t||(_(e),o?.(e),e.baseUIHandlerPrevented))return;let n=e.target===e.currentTarget,r=e.currentTarget,a=$(r),s=!i&&Re(r),l=n&&(i?a:!s),u=e.key===`Enter`,d=e.key===` `,f=r.getAttribute(`role`),p=f?.startsWith(`menuitem`)||f===`option`||f===`gridcell`;if(n&&c&&d){if(e.defaultPrevented&&p)return;e.preventDefault(),(!i||a)&&(e.preventBaseUIHandler(),Z(r,e))}else!l||i||!d&&!u?n&&s&&d&&e.preventDefault():e.defaultPrevented||(e.preventDefault(),u&&(e.preventBaseUIHandler(),Z(r,e)))},onKeyUp(e){t||(_(e),a?.(e),e.target===e.currentTarget&&i&&c&&$(e.currentTarget)&&e.key===` `?e.preventDefault():e.baseUIHandlerPrevented||e.target!==e.currentTarget||i||c||e.defaultPrevented||e.key!==` `||(e.preventBaseUIHandler(),Z(e.currentTarget,e)))},onPointerDown(e){t?e.preventDefault():s?.(e)}},i?{type:`button`}:{role:`button`},u,d)},[t,u,c,i]),buttonRef:ke(e=>{o.current=e,d()})}}function $(e){return R(e)&&e.tagName===`BUTTON`}function Re(e){return R(e)&&e.tagName===`A`&&!!e.href}var ze=b.forwardRef(function(e,t){let{render:n,className:r,disabled:i=!1,focusableWhenDisabled:a=!1,nativeButton:o=!0,style:s,...c}=e,{getButtonProps:l,buttonRef:u}=Q({disabled:i,focusableWhenDisabled:a,native:o});return E(`button`,e,{state:{disabled:i},ref:[t,u],props:[c,l]})}),Be=i(),Ve=j(`group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,{variants:{variant:{default:`bg-primary text-primary-foreground hover:bg-primary/80`,outline:`border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50`,secondary:`bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground`,ghost:`hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50`,destructive:`bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40`,link:`text-primary underline-offset-4 hover:underline`},size:{default:`h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2`,xs:`h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3`,sm:`h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5`,lg:`h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2`,icon:`size-8`,"icon-xs":`size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3`,"icon-sm":`size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg`,"icon-lg":`size-9`}},defaultVariants:{variant:`default`,size:`default`}});function He({className:e,variant:t=`default`,size:r=`default`,...i}){return(0,Be.jsx)(ze,{"data-slot":`button`,"data-variant":t,className:n(Ve({variant:t,size:r,className:e})),...i})}export{D as A,I as C,V as D,be as E,se as F,C as I,S as L,ue as M,T as N,W as O,le as P,l as R,G as S,z as T,q as _,Ie as a,L as b,ke as c,we as d,F as f,J as g,Te as h,Fe as i,E as j,j as k,Y as l,N as m,Q as n,Pe as o,De as p,Z as r,Me as s,He as t,K as u,P as v,B as w,R as x,U as y,o as z};
@@ -0,0 +1 @@
1
+ import{at as e}from"./route-DO6IZ7of.js";var t={name:`arrow-down`,size:24,node:[[`path`,{d:`M12 5v14`,key:`s699le`}],[`path`,{d:`m19 12-7 7-7-7`,key:`1idqje`}]]};t.node;var n=e(t),r={name:`arrow-up`,size:24,node:[[`path`,{d:`m5 12 7-7 7 7`,key:`hav0vg`}],[`path`,{d:`M12 19V5`,key:`x0mq9r`}]]};r.node;var i=e(r),a={name:`code-xml`,size:24,node:[[`path`,{d:`m18 16 4-4-4-4`,key:`1inbqp`}],[`path`,{d:`m6 8-4 4 4 4`,key:`15zrgr`}],[`path`,{d:`m14.5 4-5 16`,key:`e7oirm`}]],aliases:[`code-2`]};a.node;var o=e(a);export{i as n,n as r,o as t};
@@ -0,0 +1,2 @@
1
+ import{$ as e,at as t,ct as n,o as r,ot as i,rt as a}from"./route-DO6IZ7of.js";import{t as o}from"./button-ClA70PLR.js";import{G as s,Gt as c,Kt as l,Wt as u,rn as d}from"./index-CDcnUacl.js";var f={name:`clipboard-copy`,size:24,node:[[`rect`,{width:`8`,height:`4`,x:`8`,y:`2`,rx:`1`,ry:`1`,key:`tgr4d6`}],[`path`,{d:`M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2`,key:`4jdomd`}],[`path`,{d:`M16 4h2a2 2 0 0 1 2 2v4`,key:`3hqy98`}],[`path`,{d:`M21 14H11`,key:`1bme5i`}],[`path`,{d:`m15 10-4 4 4 4`,key:`5dvupr`}]]};f.node;var p=t(f),m=n(i(),1);function h(e){let t={changed:0,"only-a":0,"only-b":0,same:e.same};for(let n of e.changes)t[n.status]++;return t}function g(e,t,n=``){let r=n.trim().toLowerCase(),i=new Map;for(let n of e){if(!t.has(n.status)||r&&![n.schema,n.kind,n.name,`${n.schema}.${n.name}`,...n.parts.map(e=>e.part)].some(e=>e.toLowerCase().includes(r)))continue;let e=n.kind===`extension`?``:n.schema;i.set(e,[...i.get(e)??[],n])}return[...i]}function _(e,t=e.schema){let{kind:n,name:r}=e;if(n===`table`||n===`view`||n===`materialized view`||n===`foreign table`)return{kind:`table`,schema:t,name:r};if(n===`sequence`||n===`type`)return{kind:n,schema:t,name:r}}function v(e,t,n){let r=[];for(let i of e.changes){let e=i.kind===`schema`||i.kind===`extension`?i.name:`${i.schema}.${i.name}`,a=i.status===`only-a`?`only in ${t}`:i.status===`only-b`?`only in ${n}`:`differs`;r.push(`${i.kind} ${e}: ${a}`);for(let e of i.parts)if(i.status!==`changed`)r.push(` ${e.part}: ${e.a??e.b}`);else if(e.lines){r.push(` ${e.part} (- ${t}, + ${n})`);for(let t of e.lines)r.push(` ${t.side===`a`?`-`:t.side===`b`?`+`:` `} ${t.text}`)}else e.a===null||e.b===null?r.push(` ${e.part}, only in ${e.a===null?n:t}: ${e.a??e.b}`):r.push(` ${e.part}`,` ${t}: ${e.a}`,` ${n}: ${e.b}`);r.push(``)}return r.push(e.changes.length===0?`${t} and ${n} are the same (${e.same} objects).`:`${e.changes.length} ${e.changes.length===1?`object differs`:`objects differ`}, ${e.same} the same.`),`${r.join(`
2
+ `)}\n`}var y=a(),b=`border-input bg-background rounded-lg border px-2 py-1 text-sm`,x={a:`bg-chart-1/15`,b:`bg-chart-3/15`};function S(e,t){window.location.hash=r({environment:e,compare:t})}function C({environment:t,environments:n,compare:r}){let i=u(()=>e.schemas(t),t),a=(n??[]).filter(e=>e.name!==t),[s,c]=(0,m.useState)(r.with??a[0]?.name??``),[l,f]=(0,m.useState)(r.schema??``),[p,h]=(0,m.useState)(r.withSchema??``),g=s||a[0]?.name||``;return n&&a.length===0?(0,y.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:`There is no other environment in your config to compare with.`}):(0,y.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),g&&S(t,{with:g,...l?{schema:l,...p.trim()&&p.trim()!==l?{withSchema:p.trim()}:{}}:{}})},className:`flex flex-wrap items-center gap-2 text-sm`,children:[(0,y.jsx)(`span`,{className:`text-muted-foreground`,children:`Compare`}),(0,y.jsx)(`strong`,{children:t}),(0,y.jsx)(`span`,{className:`text-muted-foreground`,children:`with`}),(0,y.jsx)(`select`,{"aria-label":`Environment to compare with`,className:b,value:g,onChange:e=>c(e.target.value),children:a.map(e=>(0,y.jsxs)(`option`,{value:e.name,children:[e.name,` (`,e.tier,`)`]},e.name))}),(0,y.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,y.jsx)(`span`,{className:`text-muted-foreground`,children:`schema`}),(0,y.jsxs)(`select`,{"aria-label":`Schema`,className:b,value:l,onChange:e=>f(e.target.value),children:[(0,y.jsx)(`option`,{value:``,children:`all schemas`}),i.data?.map(e=>(0,y.jsx)(`option`,{value:e.name,children:e.name},e.name))]})]}),l&&(0,y.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,y.jsx)(`span`,{className:`text-muted-foreground`,children:`against its schema`}),(0,y.jsx)(`input`,{"aria-label":`Schema in ${g}`,className:`${b} w-36`,placeholder:l,value:p,onChange:e=>h(e.target.value)})]}),(0,y.jsxs)(o,{type:`submit`,disabled:!g,children:[(0,y.jsx)(d,{className:`size-4`}),` Compare`]})]})}function w({text:e,side:t,name:n}){return(0,y.jsxs)(`div`,{className:`min-w-0`,children:[(0,y.jsx)(`span`,{className:`text-muted-foreground text-xs sm:hidden`,children:n}),e===null?(0,y.jsx)(`span`,{className:`text-muted-foreground block italic`,children:`missing`}):(0,y.jsx)(`pre`,{className:`${x[t]} overflow-x-auto rounded px-1.5 py-0.5 font-mono text-xs whitespace-pre-wrap break-all`,children:e})]})}function T({part:e,a:t,b:n}){return(0,y.jsx)(`div`,{className:`overflow-x-auto rounded border font-mono text-xs`,children:e.lines.map((e,r)=>(0,y.jsxs)(`div`,{className:`flex gap-2 px-1.5 whitespace-pre ${e.side===`both`?``:x[e.side]}`,title:e.side===`both`?void 0:`only in ${e.side===`a`?t:n}`,children:[(0,y.jsx)(`span`,{className:`text-muted-foreground w-3 shrink-0 select-none`,children:e.side===`a`?`-`:e.side===`b`?`+`:` `}),(0,y.jsx)(`span`,{children:e.text||` `})]},r))})}function E({status:e,a:t,b:n}){return e===`changed`?(0,y.jsx)(l,{variant:`outline`,children:`differs`}):(0,y.jsxs)(l,{className:`${x[e===`only-a`?`a`:`b`]} text-foreground`,children:[`only in `,e===`only-a`?t:n]})}function D({change:e,environment:t,compare:n}){let i=t,a=n.with,o=e.kind===`schema`||e.kind===`extension`?e.name:`${e.schema}.${e.name}`,s=e.status===`only-b`?void 0:_(e),c=e.status===`only-a`?void 0:_(e,n.withSchema??e.schema);return(0,y.jsxs)(`details`,{open:e.status===`changed`,className:`bg-card rounded-lg border`,children:[(0,y.jsxs)(`summary`,{className:`flex cursor-pointer flex-wrap items-center gap-2 px-3 py-2 text-sm`,children:[(0,y.jsx)(`span`,{className:`text-muted-foreground w-28 shrink-0 text-xs uppercase tracking-wider`,children:e.kind}),(0,y.jsx)(`span`,{className:`font-mono`,children:o}),(0,y.jsx)(E,{status:e.status,a:i,b:a}),e.status===`changed`&&(0,y.jsxs)(`span`,{className:`text-muted-foreground text-xs`,children:[e.parts.length,` `,e.parts.length===1?`part`:`parts`]}),(0,y.jsxs)(`span`,{className:`ml-auto flex gap-3 text-xs`,children:[s&&(0,y.jsxs)(`a`,{className:`text-accent-text hover:underline`,href:r({environment:i,object:s}),children:[`open in `,i]}),c&&(0,y.jsxs)(`a`,{className:`text-accent-text hover:underline`,href:r({environment:a,object:c}),children:[`open in `,a]})]})]}),e.parts.length>0&&(0,y.jsx)(`div`,{className:`border-t px-3 py-2`,children:e.status===`changed`?(0,y.jsxs)(`div`,{className:`grid gap-x-3 gap-y-1.5 text-sm sm:grid-cols-[minmax(8rem,max-content)_1fr_1fr]`,children:[(0,y.jsxs)(`div`,{className:`hidden sm:contents`,children:[(0,y.jsx)(`span`,{}),(0,y.jsx)(`span`,{className:`text-muted-foreground text-xs`,children:i}),(0,y.jsx)(`span`,{className:`text-muted-foreground text-xs`,children:a})]}),e.parts.map(e=>(0,y.jsxs)(`div`,{className:`contents`,children:[(0,y.jsx)(`span`,{className:`mt-2 font-mono text-xs sm:mt-0`,children:e.part}),e.lines?(0,y.jsx)(`div`,{className:`min-w-0 sm:col-span-2`,children:(0,y.jsx)(T,{part:e,a:i,b:a})}):(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(w,{text:e.a,side:`a`,name:i}),(0,y.jsx)(w,{text:e.b,side:`b`,name:a})]})]},e.part))]}):(0,y.jsx)(`dl`,{className:`grid gap-x-3 gap-y-1 text-sm sm:grid-cols-[minmax(8rem,max-content)_1fr]`,children:e.parts.map(e=>(0,y.jsxs)(`div`,{className:`contents`,children:[(0,y.jsx)(`dt`,{className:`font-mono text-xs`,children:e.part}),(0,y.jsx)(`dd`,{className:`min-w-0`,children:(0,y.jsx)(`pre`,{className:`overflow-x-auto font-mono text-xs whitespace-pre-wrap break-all`,children:e.a??e.b})})]},e.part))})})]})}function O({environment:t,compare:n}){let r=[t,n.with,n.schema??``,n.withSchema??``].join(`\0`),i=u(()=>e.schemaDiff(t,n.with,n.schema,n.withSchema),r),[a,o]=(0,m.useState)(new Set([`changed`,`only-a`,`only-b`])),[l,d]=(0,m.useState)(``),f=t,_=n.with,S=n.schema?n.withSchema?` (schema ${n.schema} against ${n.withSchema})`:` (schema ${n.schema})`:``;if(i.error)return(0,y.jsx)(`p`,{className:`text-destructive text-sm`,children:i.error});if(!i.data)return(0,y.jsxs)(`div`,{className:`space-y-2`,children:[(0,y.jsxs)(`p`,{className:`text-muted-foreground text-sm`,children:[`Reading the structure of `,f,` and `,_,`...`]}),(0,y.jsx)(c,{className:`h-10`}),(0,y.jsx)(c,{className:`h-10`}),(0,y.jsx)(c,{className:`h-10`})]});let C=h(i.data);if(i.data.changes.length===0)return(0,y.jsxs)(`p`,{className:`text-sm`,children:[f,` and `,_,` are the same`,S,`: `,C.same,` `,C.same===1?`object`:`objects`,` compared.`]});let w=e=>o(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),T=g(i.data.changes,a,l),E=[[`changed`,`${C.changed} differ`],[`only-a`,`${C[`only-a`]} only in ${f}`],[`only-b`,`${C[`only-b`]} only in ${_}`]];return(0,y.jsxs)(`div`,{className:`space-y-4`,children:[(0,y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 text-sm`,children:[E.map(([e,t])=>(0,y.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-1.5 rounded-lg border px-2 py-1 ${e===`changed`?``:x[e===`only-a`?`a`:`b`]}`,children:[(0,y.jsx)(`input`,{type:`checkbox`,checked:a.has(e),onChange:()=>w(e)}),t]},e)),(0,y.jsxs)(`span`,{className:`text-muted-foreground`,children:[C.same,` the same`,S]}),(0,y.jsx)(`input`,{"aria-label":`Filter by name`,className:`${b} ml-auto w-48`,placeholder:`Filter by name...`,value:l,onChange:e=>d(e.target.value)}),(0,y.jsx)(s,{label:`Copy as text`,done:`Copied`,icon:p,text:()=>v(i.data,f,_),disabled:!1})]}),T.length===0&&(0,y.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:`Nothing matches.`}),T.map(([e,r])=>(0,y.jsxs)(`section`,{className:`space-y-1.5`,children:[(0,y.jsx)(`h3`,{className:`text-accent-text text-sm uppercase tracking-widest`,children:e?`schema ${e}`:`database`}),r.map(e=>(0,y.jsx)(D,{change:e,environment:t,compare:n},`${e.kind}\0${e.name}`))]},e))]})}function k({environment:e,environments:t,compare:n}){let r=n.with;return(0,y.jsxs)(`div`,{className:`space-y-6`,children:[(0,y.jsxs)(`div`,{children:[(0,y.jsxs)(`h2`,{className:`text-accent-text mb-1 flex items-center gap-2 text-2xl`,children:[(0,y.jsx)(d,{className:`size-6`}),` Compare schemas`]}),(0,y.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:`Tables and their columns, indexes, constraints, triggers and policies, views, functions, sequences, types and extensions, side by side with another environment. Owners, grants, comments and column order are not compared.`})]}),(0,y.jsx)(C,{environment:e,environments:t,compare:n},JSON.stringify(n)),r&&t&&!t.some(e=>e.name===r)?(0,y.jsxs)(`p`,{className:`text-destructive text-sm`,children:[`You do not have access to "`,r,`": it is not in your config.`]}):r&&(0,y.jsx)(O,{environment:e,compare:{...n,with:r}})]})}export{k as CompareView};
@@ -0,0 +1 @@
1
+ import{at as e}from"./route-DO6IZ7of.js";var t={name:`copy`,size:24,node:[[`rect`,{width:`14`,height:`14`,x:`8`,y:`8`,rx:`2`,ry:`2`,key:`17jyea`}],[`path`,{d:`M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2`,key:`zix9uf`}]]};t.node;var n=e(t);export{n as t};
@@ -0,0 +1,13 @@
1
+ import{$ as e,a as t,ct as n,o as r,ot as i,r as a,rt as o}from"./route-DO6IZ7of.js";import{t as s,z as c}from"./button-ClA70PLR.js";import{t as l}from"./copy-CCXzeW-s.js";import{t as u}from"./loader-circle-BK_GMdvN.js";import{d,i as f,l as p,o as m,p as h,r as g,s as _,u as v}from"./graph-force-yBLyErpS.js";import{t as y}from"./shield-alert-CMS-3j4U.js";import{t as b}from"./triangle-alert-COGnHCD1.js";import{$t as x,an as S}from"./index-CDcnUacl.js";var C=n(i(),1),w=o(),T=8,E=80,D=[[58,120,3],[140,410,2.5],[210,60,2],[260,300,3.5],[330,520,2.5],[380,150,2],[450,380,3],[520,90,2.5],[570,470,2],[90,580,2.5],[300,600,2],[610,260,3]],O=e=>`${e.schema}.${e.name}`,k=(e,t)=>e.length>t?`${e.slice(0,t-1)}…`:e,A={paintOrder:`stroke`};function j({nodes:e,edges:t,selected:n,onSelect:r}){let{frame:i,view:a,setView:o,dragged:s,startDrag:c,zoomBy:l}=v(),[u,y]=(0,C.useState)(),[b,x]=(0,C.useState)(),S=(0,C.useMemo)(()=>{let n=t.map(e=>({source:e.from,target:e.to})),r=new Map;for(let e of t)r.set(e.from,(r.get(e.from)??0)+1),r.set(e.to,(r.get(e.to)??0)+1);let i=m(e.map(e=>({id:e.id,r:T+Math.min(8,Math.sqrt(r.get(e.id)??0))})),n);return _(i,n,400),i},[e,t]),j=(0,C.useMemo)(()=>new Map(S.map(e=>[e.id,e])),[S]),M=(0,C.useCallback)(()=>{let e=i.current?.getBoundingClientRect();if(!e||S.length===0)return;let t=f(S),n=h(t,e);o({k:n.k,x:n.x-t.x*n.k,y:n.y-t.y*n.k})},[S,i,o]);(0,C.useLayoutEffect)(M,[M]);let N=t.map(e=>e.weight===null?NaN:Number(e.weight)),P=N.length>0&&N.every(Number.isFinite),[F,I]=P?[Math.min(...N),Math.max(...N)]:[0,0],L=e=>I>F?1+4*(e-F)/(I-F):2,R=(0,C.useMemo)(()=>{if(!u)return;let e=new Set([u]);for(let n of t)n.from===u&&e.add(n.to),n.to===u&&e.add(n.from);return e},[u,t]);return(0,w.jsxs)(`div`,{className:`relative`,children:[(0,w.jsx)(p,{zoomBy:l,fit:M}),(0,w.jsxs)(`div`,{ref:i,onPointerDown:c,className:`cypher-frame border-border relative h-[60vh] min-h-80 touch-none overflow-hidden border`,children:[(0,w.jsxs)(`svg`,{role:`img`,"aria-label":`Query graph`,width:`100%`,height:`100%`,className:`cursor-grab select-none active:cursor-grabbing`,onClick:()=>!s.current&&r(void 0),children:[(0,w.jsxs)(`defs`,{children:[(0,w.jsx)(`pattern`,{id:`star-chart-grid`,width:48,height:48,patternUnits:`userSpaceOnUse`,children:(0,w.jsx)(`path`,{d:`M48 0H0V48`,fill:`none`,className:`star-grid-line`,strokeWidth:1.4})}),(0,w.jsx)(`pattern`,{id:`star-chart-stars`,width:640,height:640,patternUnits:`userSpaceOnUse`,children:D.map(([e,t,n])=>(0,w.jsx)(`circle`,{cx:e,cy:t,r:n,className:`star-dot`},`${e}-${t}`))})]}),(0,w.jsxs)(`g`,{transform:`translate(${a.x},${a.y}) scale(${a.k})`,children:[(0,w.jsx)(`rect`,{className:`star-chart`,x:-6e3,y:-6e3,width:12e3,height:12e3,fill:`url(#star-chart-grid)`,pointerEvents:`none`}),(0,w.jsx)(`rect`,{className:`star-chart`,x:-6e3,y:-6e3,width:12e3,height:12e3,fill:`url(#star-chart-stars)`,pointerEvents:`none`}),t.map((e,n)=>{let[r,i]=[j.get(e.from),j.get(e.to)];if(!r||!i)return null;let a=g(r,i,!1),o=b===e.id||!!u&&(e.from===u||e.to===u),s=u&&!o?.1:o?.95:.5,c=e.weight!==null&&(t.length<=E||b===e.id||o);return(0,w.jsxs)(`g`,{"data-edge":e.id,children:[(0,w.jsx)(`line`,{...a,className:`cypher-edge stroke-accent-text`,strokeWidth:P?L(N[n]):1.4,opacity:s,strokeLinecap:`round`}),(0,w.jsx)(`line`,{...a,stroke:`transparent`,strokeWidth:12,pointerEvents:`stroke`,onPointerEnter:()=>x(e.id),onPointerLeave:()=>x(void 0),children:(0,w.jsx)(`title`,{children:e.weight??`linked`})}),c&&(0,w.jsx)(`text`,{x:(r.x+i.x)/2,y:(r.y+i.y)/2-3,textAnchor:`middle`,className:`cypher-weight fill-accent-text text-[11px] font-medium`,stroke:`var(--background)`,strokeWidth:3,strokeLinejoin:`round`,style:A,opacity:u&&!o?.15:1,children:e.weight})]},e.id)}),e.map(e=>{let t=j.get(e.id);if(!t)return null;let i=n===e.id;return(0,w.jsxs)(`g`,{transform:`translate(${t.x},${t.y})`,"data-node":e.id,role:`button`,"aria-label":`${O(e.table)} ${e.label}`,"aria-pressed":i,className:`cursor-pointer`,opacity:R&&!R.has(e.id)?.2:1,onPointerDown:e=>e.stopPropagation(),onClick:t=>{t.stopPropagation(),r(i?void 0:e.id)},onPointerEnter:()=>y(e.id),onPointerLeave:()=>y(void 0),children:[(0,w.jsx)(`title`,{children:`${O(e.table)}\n${Object.entries(e.key).map(([e,t])=>`${e} = ${t??`null`}`).join(`, `)}`}),(0,w.jsx)(`circle`,{r:t.r+6,fill:`transparent`}),(0,w.jsx)(`circle`,{className:`cypher-dot`,r:t.r,fill:d(O(e.table)),stroke:i?`var(--primary)`:`var(--background)`,strokeWidth:i?3:1.5}),(0,w.jsx)(`text`,{y:t.r+14,textAnchor:`middle`,className:`cypher-label fill-foreground text-[11px]`,stroke:`var(--background)`,strokeWidth:3,strokeLinejoin:`round`,style:A,children:k(e.label,24)}),(0,w.jsx)(`text`,{y:t.r+26,textAnchor:`middle`,className:`cypher-table fill-muted-foreground text-[9px]`,opacity:.75,stroke:`var(--background)`,strokeWidth:3,strokeLinejoin:`round`,style:A,children:O(e.table)})]},e.id)})]})]}),(0,w.jsxs)(`div`,{className:`cypher-readout`,"aria-hidden":!0,children:[(0,w.jsxs)(`span`,{children:[`Query net `,e.length]}),(0,w.jsxs)(`strong`,{children:[e.length,`.`,t.length]})]})]})]})}var M=[{title:`Products bought by the same customers`,query:`MATCH (a:Product)<-[]-(c:Customer)-[]->(b:Product)
2
+ WHERE a.id < b.id
3
+ RETURN a, b, count(DISTINCT c) AS customers
4
+ ORDER BY customers DESC
5
+ LIMIT 25`},{title:`Rows linked by a key`,query:`MATCH (o:Order)-[]->(c:Customer)
6
+ RETURN o, c
7
+ LIMIT 25`},{title:`Customers with the most orders`,query:`MATCH (c:Customer)<-[]-(o:Order)
8
+ RETURN c, count(o) AS orders
9
+ ORDER BY orders DESC
10
+ LIMIT 10`}],N=e=>`${e.schema}.${e.name}`;function P({environment:e,node:t}){let n=r({environment:e,object:{kind:`table`,schema:t.table.schema,name:t.table.name},rows:{filters:Object.entries(t.key).map(([e,t])=>t===null?{column:e,op:`null`}:{column:e,op:`eq`,value:t}),sort:[]}});return(0,w.jsxs)(`div`,{className:`border-border mt-3 border p-3 text-sm`,children:[(0,w.jsxs)(`div`,{className:`mb-2 flex items-center justify-between gap-3`,children:[(0,w.jsxs)(`span`,{className:`font-medium`,children:[(0,w.jsx)(`span`,{className:`mr-2 inline-block size-2.5 rounded-full`,style:{background:d(N(t.table))}}),N(t.table),` · `,t.label]}),(0,w.jsx)(`a`,{href:n,className:`text-accent-text text-xs underline-offset-2 hover:underline`,children:`Open in Browse`})]}),(0,w.jsx)(`dl`,{className:`grid grid-cols-[max-content_1fr] gap-x-4 gap-y-1 font-mono text-xs`,children:Object.entries(t.row).map(([e,t])=>(0,w.jsxs)(`div`,{className:`contents`,children:[(0,w.jsx)(`dt`,{className:`text-muted-foreground`,children:e}),(0,w.jsx)(`dd`,{className:`break-all`,children:t===null?(0,w.jsx)(`span`,{className:`text-muted-foreground`,children:`NULL`}):t})]},e))})]})}function F({result:e,onForce:t,busy:n}){let{complexity:r}=e;if(r.warnings.length===0)return(0,w.jsxs)(`p`,{className:`text-muted-foreground text-xs`,children:[`Complexity: low`,r.cost!==null&&` · planner cost ${Math.round(r.cost).toLocaleString()}`,r.tables>1&&` · ${r.tables} tables joined`]});let i=r.level===`high`,a=i&&!e.ran;return(0,w.jsxs)(`div`,{role:`alert`,className:`flex gap-3 border p-3 text-sm ${i?`border-destructive/50 bg-destructive/5`:`border-amber-500/50 bg-amber-500/5`}`,children:[i?(0,w.jsx)(y,{className:`text-destructive mt-0.5 size-4 shrink-0`}):(0,w.jsx)(b,{className:`mt-0.5 size-4 shrink-0 text-amber-500`}),(0,w.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,w.jsx)(`p`,{className:`font-medium`,children:a?`Not run: this query looks heavy`:i?`This query looked heavy`:`This query may be slow`}),(0,w.jsx)(`ul`,{className:`text-muted-foreground mt-1 list-disc space-y-0.5 pl-4`,children:r.warnings.map(e=>(0,w.jsx)(`li`,{children:e.message},e.message))}),a&&(0,w.jsxs)(s,{variant:`destructive`,size:`sm`,className:`mt-2`,disabled:n,onClick:t,children:[(0,w.jsx)(x,{}),` Run anyway`]})]})]})}function I({result:e}){return(0,w.jsx)(`div`,{className:`overflow-x-auto`,children:(0,w.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,w.jsx)(`thead`,{children:(0,w.jsx)(`tr`,{className:`text-muted-foreground border-border border-b text-left text-xs uppercase tracking-wider`,children:e.columns.map((e,t)=>(0,w.jsxs)(`th`,{className:`px-3 py-2 font-medium`,children:[e.name,e.node&&(0,w.jsx)(`span`,{className:`ml-1.5 normal-case opacity-60`,children:`row`})]},t))})}),(0,w.jsx)(`tbody`,{children:e.rows.map((e,t)=>(0,w.jsx)(`tr`,{className:`border-border/60 border-b`,children:e.map((e,t)=>(0,w.jsx)(`td`,{className:`max-w-md truncate px-3 py-1.5 font-mono text-xs`,title:e??void 0,children:e===null?(0,w.jsx)(`span`,{className:`text-muted-foreground`,children:`NULL`}):e},t))},t))})]})})}function L({environment:n,cypher:r}){let[i,o]=(0,C.useState)(r.query??``),[f,p]=(0,C.useState)(),[m,h]=(0,C.useState)(``),[g,_]=(0,C.useState)(),[v,y]=(0,C.useState)(),[b,T]=(0,C.useState)(!1),[E,D]=(0,C.useState)(`graph`),[O,k]=(0,C.useState)(),[A,L]=(0,C.useState)(!1),R=(0,C.useRef)(null),z=(0,C.useRef)(void 0),B=async(r,a=!1)=>{z.current?.abort();let o=z.current=new AbortController;y(r?`run`:`check`),_(void 0);try{let s=await e.cypher(n,{query:i,run:r,force:a},o.signal);p(s),h(i),k(void 0),r?(D(s.nodes.length>0?`graph`:`table`),t({environment:n,cypher:{query:i}})):T(!0)}catch(e){if(o.signal.aborted)return;let t=e.message;_(t);let n=/\(at character (\d+)\)$/.exec(t);if(n&&R.current){let e=Math.min(Number(n[1])-1,i.length);R.current.focus(),R.current.setSelectionRange(e,Math.min(e+1,i.length))}}finally{z.current===o&&y(void 0)}},V=(0,C.useRef)(!1);(0,C.useEffect)(()=>{V.current||(V.current=!0,r.run&&r.query?.trim()&&B(!0))},[]);let H=f!==void 0&&m===i,U=f?[...new Map(f.nodes.map(e=>[N(e.table),e.table])).keys()]:[],W=f?.nodes.find(e=>e.id===O);return(0,w.jsxs)(`div`,{className:`space-y-4`,children:[(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`textarea`,{ref:R,value:i,spellCheck:!1,rows:Math.min(12,Math.max(5,i.split(`
11
+ `).length+1)),"aria-label":`Cypher query`,placeholder:`MATCH (a:Product)<-[]-(c:Customer)-[]->(b:Product)
12
+ RETURN a, b, count(DISTINCT c) AS customers
13
+ ORDER BY customers DESC LIMIT 25`,onChange:e=>o(e.target.value),onKeyDown:e=>{(e.metaKey||e.ctrlKey)&&e.key===`Enter`&&i.trim()&&!v&&(e.preventDefault(),B(!0))},className:`border-input bg-background w-full rounded-lg border px-3 py-2 font-mono text-sm`}),(0,w.jsxs)(`div`,{className:`mt-2 flex flex-wrap items-center gap-2`,children:[(0,w.jsxs)(s,{disabled:!i.trim()||!!v,onClick:()=>void B(!0),children:[v===`run`?(0,w.jsx)(u,{className:`animate-spin`}):(0,w.jsx)(x,{}),` Run`]}),(0,w.jsxs)(s,{variant:`outline`,disabled:!i.trim()||!!v,onClick:()=>H?T(e=>!e):void B(!1),children:[v===`check`?(0,w.jsx)(u,{className:`animate-spin`}):(0,w.jsx)(S,{}),` `,H&&b?`Hide SQL`:`Show SQL`]}),(0,w.jsx)(`span`,{className:`text-muted-foreground text-xs`,children:`⌘/Ctrl + Enter runs. A label is a table; a relationship is a foreign key.`})]})]}),!f&&!g&&(0,w.jsxs)(`details`,{className:`text-sm`,open:!i.trim(),children:[(0,w.jsx)(`summary`,{className:`text-muted-foreground cursor-pointer text-xs uppercase tracking-widest`,children:`Examples and syntax`}),(0,w.jsxs)(`div`,{className:`mt-2 space-y-3`,children:[(0,w.jsx)(`ul`,{className:`space-y-1`,children:M.map(e=>(0,w.jsx)(`li`,{children:(0,w.jsx)(`button`,{type:`button`,className:`text-accent-text underline-offset-2 hover:underline`,onClick:()=>o(e.query),children:e.title})},e.title))}),(0,w.jsxs)(`p`,{className:`text-muted-foreground max-w-3xl text-xs leading-relaxed`,children:[(0,w.jsx)(`code`,{children:`(c:Customer)`}),` is a row of the `,(0,w.jsx)(`em`,{children:`customers`}),` table (`,(0,w.jsx)(`code`,{children:`Customer`}),`, `,(0,w.jsx)(`code`,{children:`customers`}),` and `,(0,w.jsx)(`code`,{children:`OrderLine`}),` for `,(0,w.jsx)(`em`,{children:`order_lines`}),` all work; `,(0,w.jsx)(`code`,{children:"`schema.table`"}),` names another schema).`,` `,(0,w.jsx)(`code`,{children:`-[]->`}),` follows a foreign key, `,(0,w.jsx)(`code`,{children:`<-[]-`}),` follows it backwards. Tables with no key between them are joined through the tables in between (customers → orders → order_lines → products), and if that is ambiguous you are told how to pick one, e.g. `,(0,w.jsx)(`code`,{children:`-[:orders]-`}),` or `,(0,w.jsx)(`code`,{children:`-[:billing_address_id]-`}),`. Supported: `,(0,w.jsx)(`code`,{children:`WHERE`}),` (`,(0,w.jsx)(`code`,{children:`=`}),` `,(0,w.jsx)(`code`,{children:`<>`}),` `,(0,w.jsx)(`code`,{children:`<`}),` `,(0,w.jsx)(`code`,{children:`IN`}),` `,(0,w.jsx)(`code`,{children:`IS NULL`}),` `,(0,w.jsx)(`code`,{children:`STARTS WITH`}),` `,(0,w.jsx)(`code`,{children:`CONTAINS`}),` `,(0,w.jsx)(`code`,{children:`=~`}),` `,(0,w.jsx)(`code`,{children:`AND`}),` `,(0,w.jsx)(`code`,{children:`OR`}),` `,(0,w.jsx)(`code`,{children:`NOT`}),`), `,(0,w.jsx)(`code`,{children:`RETURN`}),` with `,(0,w.jsx)(`code`,{children:`DISTINCT`}),`, `,(0,w.jsx)(`code`,{children:`count`}),`, `,(0,w.jsx)(`code`,{children:`sum`}),`, `,(0,w.jsx)(`code`,{children:`avg`}),`, `,(0,w.jsx)(`code`,{children:`min`}),`, `,(0,w.jsx)(`code`,{children:`max`}),`, `,(0,w.jsx)(`code`,{children:`collect`}),`, `,(0,w.jsx)(`code`,{children:`ORDER BY`}),`, `,(0,w.jsx)(`code`,{children:`SKIP`}),`, `,(0,w.jsx)(`code`,{children:`LIMIT`}),`. It only reads.`]})]})]}),g&&(0,w.jsx)(`p`,{role:`alert`,className:`text-destructive text-sm whitespace-pre-wrap`,children:g}),f&&(0,w.jsxs)(w.Fragment,{children:[(0,w.jsx)(F,{result:f,busy:!!v,onForce:()=>void B(!0,!0)}),!H&&(0,w.jsx)(`p`,{className:`text-muted-foreground text-xs`,children:`The query has changed since; run it again to update.`}),b&&(0,w.jsxs)(`div`,{className:`border-border border`,children:[(0,w.jsxs)(`div`,{className:`border-border flex items-center justify-between border-b px-3 py-1.5`,children:[(0,w.jsx)(`span`,{className:`text-muted-foreground text-xs uppercase tracking-widest`,children:`SQL`}),(0,w.jsxs)(`div`,{className:`flex gap-1`,children:[(0,w.jsxs)(s,{variant:`ghost`,size:`sm`,onClick:()=>navigator.clipboard.writeText(f.sql).then(()=>{L(!0),window.setTimeout(()=>L(!1),1500)},()=>{}),children:[A?(0,w.jsx)(c,{}):(0,w.jsx)(l,{}),` `,A?`Copied`:`Copy`]}),(0,w.jsxs)(s,{variant:`ghost`,size:`sm`,onClick:()=>a(n,f.sql,!1),children:[(0,w.jsx)(S,{}),` Open in SQL`]})]})]}),(0,w.jsx)(`pre`,{className:`overflow-x-auto p-3 font-mono text-xs leading-relaxed`,children:f.sql}),f.joins.length>0&&(0,w.jsx)(`ul`,{className:`text-muted-foreground border-border space-y-0.5 border-t px-3 py-2 text-xs`,children:f.joins.map(e=>(0,w.jsx)(`li`,{children:e},e))})]}),f.ran&&(0,w.jsxs)(`div`,{children:[(0,w.jsxs)(`div`,{className:`mb-2 flex flex-wrap items-center gap-3 text-sm`,children:[[`graph`,`table`].map(e=>(0,w.jsx)(`button`,{type:`button`,"aria-pressed":E===e,onClick:()=>D(e),className:`border-b-2 px-1 py-1 text-xs uppercase tracking-widest ${E===e?`border-primary text-accent-text`:`text-muted-foreground hover:text-foreground border-transparent`}`,children:e===`graph`?`Graph (${f.nodes.length} rows, ${f.edges.length} links)`:`Table (${f.rows.length})`},e)),(0,w.jsxs)(`span`,{className:`text-muted-foreground ml-auto text-xs`,children:[f.truncated&&`first ${f.rowCap.toLocaleString()} rows only · `,f.durationMs!==null&&`${Math.round(f.durationMs).toLocaleString()} ms`]})]}),E===`graph`?f.nodes.length===0?(0,w.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:f.rows.length===0?`No rows matched.`:`This query returns no rows of tables, so there is nothing to draw. Return them, e.g. RETURN a, b.`}):(0,w.jsxs)(w.Fragment,{children:[(0,w.jsxs)(`div`,{className:`text-muted-foreground mb-2 flex flex-wrap gap-x-4 gap-y-1 text-xs`,children:[U.map(e=>(0,w.jsxs)(`span`,{children:[(0,w.jsx)(`span`,{className:`mr-1.5 inline-block size-2.5 rounded-full align-middle`,style:{background:d(e)}}),e]},e)),f.edges.some(e=>e.weight!==null)&&(0,w.jsx)(`span`,{children:`link labels: the number the query returns`})]}),(0,w.jsx)(j,{nodes:f.nodes,edges:f.edges,selected:O,onSelect:k},m+f.rows.length),W&&(0,w.jsx)(P,{environment:n,node:W})]}):f.rows.length===0?(0,w.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:`No rows matched.`}):(0,w.jsx)(I,{result:f})]})]})]})}export{L as CypherView};
@@ -0,0 +1,9 @@
1
+ import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,I as s,L as c,M as l,N as u,O as d,P as f,R as p,S as m,T as h,b as g,ct as _,j as ee,k as te,o as v,ot as y,r as ne,rt as b,w as re,x,z as S}from"./route-DO6IZ7of.js";import{n as C,r as ie,t as w}from"./code-xml-CXkpHeU9.js";import{t as T,z as ae}from"./button-ClA70PLR.js";import{t as E}from"./copy-CCXzeW-s.js";import{Gt as oe,Jt as D,Kt as O,Qt as k,U as se,Wt as A,Yt as ce,en as le,q as ue,qt as j}from"./index-CDcnUacl.js";import{n as M}from"./format-sql-BLj5_RDZ.js";var N=_(y(),1),P=b(),F=`border-input bg-background rounded-lg border px-2 py-1 text-sm`,I=`text-muted-foreground flex items-center gap-1 text-xs`,de=300,L=e=>e.map(e=>/^CREATE (UNLOGGED )?TABLE/.test(e)?e:M(e));function R({issues:e,row:t}){let n=e.filter(e=>e.row===t);return n.length===0?null:(0,P.jsx)(`ul`,{className:`mt-1 text-xs`,children:n.map((e,t)=>(0,P.jsx)(`li`,{className:e.level===`error`?`text-destructive`:e.level===`warning`?`text-amber-500`:`text-muted-foreground`,children:e.message},t))})}var fe=(e,t,n)=>{if(n<0||n>=e.length)return e;let r=[...e];return r.splice(n,0,...r.splice(t,1)),r};function z({label:e,onClick:t,disabled:n,children:r}){return(0,P.jsx)(`button`,{type:`button`,"aria-label":e,title:e,disabled:n,onClick:t,className:`hover:text-accent-text p-1 disabled:opacity-30`,children:r})}function B({label:e,columns:t,value:n,onChange:r}){return(0,P.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5`,role:`group`,"aria-label":e,children:[n.map((i,a)=>(0,P.jsxs)(`span`,{className:`flex items-center`,children:[(0,P.jsxs)(`select`,{"aria-label":`${e} ${a+1}`,value:i,onChange:e=>r(n.map((t,n)=>n===a?e.target.value:t)),className:F,children:[(0,P.jsx)(`option`,{value:``,children:`pick a column`}),t.map(e=>(0,P.jsx)(`option`,{value:e.id,children:e.name||`(no name)`},e.id))]}),(0,P.jsx)(z,{label:`Remove ${e} ${a+1}`,onClick:()=>r(n.filter((e,t)=>t!==a)),children:(0,P.jsx)(j,{className:`size-3.5`})})]},a)),(0,P.jsxs)(`button`,{type:`button`,onClick:()=>r([...n,``]),className:`text-accent-text flex items-center gap-1 text-xs`,children:[(0,P.jsx)(k,{className:`size-3`}),` column`]})]})}function pe({type:e,databaseTypes:t,onChange:n}){let r=u(e),i=e=>e.trim()===``?void 0:Number(e),a=e.schema===void 0||t.some(t=>t.schema===e.schema&&t.name===e.name);return(0,P.jsxs)(`span`,{className:`flex flex-wrap items-center gap-1`,children:[(0,P.jsxs)(`select`,{"aria-label":`Type`,value:S(e),onChange:t=>n({...p(t.target.value),...e.array?{array:e.array}:{}}),className:F,children:[(0,P.jsx)(`optgroup`,{label:`Built in`,children:x.map(e=>(0,P.jsx)(`option`,{value:`b:${e.name}`,children:e.name},e.name))}),(t.length>0||!a)&&(0,P.jsxs)(`optgroup`,{label:`This database`,children:[!a&&(0,P.jsx)(`option`,{value:S(e),children:`${e.schema}.${e.name}`}),t.map(e=>(0,P.jsxs)(`option`,{value:`t:${e.schema}.${e.name}`,children:[e.schema,`.`,e.name,` (`,e.kind,`)`]},`${e.schema}.${e.name}`))]})]}),(r===`length`||r===`precision`)&&(0,P.jsx)(`input`,{"aria-label":r===`length`?`Length`:`Precision`,type:`number`,min:+(r===`length`),placeholder:r===`length`?`length`:`precision`,value:e.length??``,onChange:t=>n({...e,length:i(t.target.value)}),className:`${F} w-20`}),r===`numeric`&&(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(`input`,{"aria-label":`Precision`,type:`number`,min:1,placeholder:`precision`,value:e.precision??``,onChange:t=>n({...e,precision:i(t.target.value)}),className:`${F} w-24`}),(0,P.jsx)(`input`,{"aria-label":`Scale`,type:`number`,min:0,placeholder:`scale`,value:e.scale??``,onChange:t=>n({...e,scale:i(t.target.value)}),className:`${F} w-20`})]}),(0,P.jsxs)(`label`,{className:I,title:`An array of this type`,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:!!e.array,onChange:t=>n({...e,array:t.target.checked?1:void 0})}),`array`]})]})}function me({column:e,at:t,count:n,issues:r,databaseTypes:i,onChange:a,onMove:o,onRemove:s}){let[c,l]=(0,N.useState)(!!(e.default||e.identity||e.generated||e.comment));return(0,P.jsxs)(`li`,{className:`border-border border-b py-2`,"aria-label":`Column ${e.name||t+1}`,children:[(0,P.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,P.jsx)(`input`,{"aria-label":`Column name`,placeholder:`name`,value:e.name,onChange:t=>a({...e,name:t.target.value}),className:`${F} w-44 font-mono`}),(0,P.jsx)(pe,{type:e.type,databaseTypes:i,onChange:t=>a({...e,type:t})}),(0,P.jsxs)(`label`,{className:I,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:e.notNull,onChange:t=>a({...e,notNull:t.target.checked})}),`NOT NULL`]}),(0,P.jsx)(`button`,{type:`button`,onClick:()=>l(!c),"aria-expanded":c,className:`text-accent-text text-xs`,children:c?`less`:`default, identity, comment`}),(0,P.jsxs)(`span`,{className:`ml-auto flex`,children:[(0,P.jsx)(z,{label:`Move up`,disabled:t===0,onClick:()=>o(t-1),children:(0,P.jsx)(C,{className:`size-3.5`})}),(0,P.jsx)(z,{label:`Move down`,disabled:t===n-1,onClick:()=>o(t+1),children:(0,P.jsx)(ie,{className:`size-3.5`})}),(0,P.jsx)(z,{label:`Remove column`,onClick:s,children:(0,P.jsx)(D,{className:`text-destructive size-3.5`})})]})]}),c&&(0,P.jsxs)(`div`,{className:`mt-2 grid gap-2 pl-1 sm:grid-cols-2`,children:[(0,P.jsxs)(`label`,{className:I,children:[`Default`,(0,P.jsx)(`input`,{"aria-label":`Default`,list:`design-defaults`,placeholder:`an expression, or pick one`,value:e.default,onChange:t=>a({...e,default:t.target.value}),className:`${F} flex-1 font-mono`})]}),(0,P.jsxs)(`label`,{className:I,children:[`Identity`,(0,P.jsxs)(`select`,{"aria-label":`Identity`,value:e.identity,onChange:t=>a({...e,identity:t.target.value}),className:F,children:[(0,P.jsx)(`option`,{value:``,children:`none`}),(0,P.jsx)(`option`,{value:`always`,children:`GENERATED ALWAYS`}),(0,P.jsx)(`option`,{value:`by default`,children:`GENERATED BY DEFAULT`})]})]}),(0,P.jsxs)(`label`,{className:I,children:[`Generated`,(0,P.jsx)(`input`,{"aria-label":`Generated`,placeholder:`an expression: stored generated column`,value:e.generated,onChange:t=>a({...e,generated:t.target.value}),className:`${F} flex-1 font-mono`})]}),(0,P.jsxs)(`label`,{className:I,children:[`Comment`,(0,P.jsx)(`input`,{"aria-label":`Comment`,value:e.comment,onChange:t=>a({...e,comment:t.target.value}),className:`${F} flex-1`})]})]}),(0,P.jsx)(R,{issues:r,row:e.id})]})}function V({environment:t,form:n,constraint:r,schemas:i,onChange:a,onTarget:o}){let{schema:c,table:l,self:u}=r.target,d=A(()=>c&&!u?e.objects(t,c):Promise.resolve(void 0),`${t}/${c}/${u}`).data?.tables.filter(e=>e.kind===`table`||e.kind===`partitioned`)??[],f=A(()=>c&&l&&!u?e.relation(t,{kind:`table`,schema:c,name:l}):Promise.resolve(void 0),`${t}/${c}/${l}/${u}`).data;(0,N.useEffect)(()=>{f&&o(s(c,l),f.columns.map(e=>({name:e.name,type:e.type})))},[f,c,l,o]);let p=e=>a({...r,...e}),m=e=>p({target:{...r.target,...e},targetColumns:r.columns.map(()=>``)}),h=u?n.columns.map(e=>({value:e.id,label:e.name||`(no name)`})):(f?.columns??[]).map(e=>({value:e.name,label:`${e.name} (${e.type})`})),_=r.columns.length;return(0,P.jsxs)(`div`,{className:`mt-2 flex flex-col gap-2`,children:[(0,P.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,P.jsx)(`span`,{className:I,children:`References`}),(0,P.jsxs)(`select`,{"aria-label":`Target`,value:u?`__self__`:``,onChange:e=>{e.target.value===`__self__`?m({self:!0,schema:``,table:``}):m({self:!1})},className:F,children:[(0,P.jsx)(`option`,{value:``,children:`a table of the database`}),(0,P.jsx)(`option`,{value:`__self__`,children:`this table`})]}),!u&&(0,P.jsxs)(P.Fragment,{children:[(0,P.jsxs)(`select`,{"aria-label":`Target schema`,value:c,onChange:e=>m({schema:e.target.value,table:``}),className:F,children:[(0,P.jsx)(`option`,{value:``,children:`schema`}),i.map(e=>(0,P.jsx)(`option`,{children:e},e))]}),(0,P.jsxs)(`select`,{"aria-label":`Target table`,value:l,onChange:e=>m({table:e.target.value}),className:F,children:[(0,P.jsx)(`option`,{value:``,children:`table`}),d.map(e=>(0,P.jsx)(`option`,{children:e.name},e.name))]})]})]}),(0,P.jsx)(`ul`,{className:`flex flex-col gap-1`,"aria-label":`Columns`,children:r.columns.map((e,t)=>(0,P.jsxs)(`li`,{className:`flex flex-wrap items-center gap-1.5`,children:[(0,P.jsxs)(`select`,{"aria-label":`Column ${t+1}`,value:e,onChange:e=>p({columns:r.columns.map((n,r)=>r===t?e.target.value:n)}),className:F,children:[(0,P.jsx)(`option`,{value:``,children:`pick a column`}),n.columns.map(e=>(0,P.jsx)(`option`,{value:e.id,children:e.name||`(no name)`},e.id))]}),(0,P.jsx)(`span`,{className:`text-accent-text`,children:`→`}),(0,P.jsxs)(`select`,{"aria-label":`Referenced column ${t+1}`,value:r.targetColumns[t]??``,onChange:e=>p({targetColumns:r.columns.map((n,i)=>i===t?e.target.value:r.targetColumns[i]??``)}),className:F,children:[(0,P.jsx)(`option`,{value:``,children:`pick a column`}),h.map(e=>(0,P.jsx)(`option`,{value:e.value,children:e.label},e.value))]}),(0,P.jsx)(z,{label:`Remove pair ${t+1}`,onClick:()=>p({columns:r.columns.filter((e,n)=>n!==t),targetColumns:r.targetColumns.filter((e,n)=>n!==t)}),children:(0,P.jsx)(j,{className:`size-3.5`})})]},t))}),(0,P.jsxs)(`button`,{type:`button`,onClick:()=>p({columns:[...r.columns,``],targetColumns:[...r.targetColumns.slice(0,_),``]}),className:`text-accent-text flex items-center gap-1 self-start text-xs`,children:[(0,P.jsx)(k,{className:`size-3`}),` column pair`]}),(0,P.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[[`onDelete`,`onUpdate`].map(e=>(0,P.jsxs)(`label`,{className:I,children:[e===`onDelete`?`ON DELETE`:`ON UPDATE`,(0,P.jsxs)(`select`,{"aria-label":e===`onDelete`?`On delete`:`On update`,value:r[e],onChange:t=>p({[e]:t.target.value}),className:F,children:[(0,P.jsx)(`option`,{value:``,children:`default (no action)`}),g.map(e=>(0,P.jsx)(`option`,{value:e,children:e.toUpperCase()},e))]})]},e)),(0,P.jsxs)(`label`,{className:I,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:r.matchFull,onChange:e=>p({matchFull:e.target.checked})}),`MATCH FULL`]}),(0,P.jsxs)(`label`,{className:I,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:r.deferrable,onChange:e=>p({deferrable:e.target.checked,...e.target.checked?{}:{initiallyDeferred:!1}})}),`DEFERRABLE`]}),r.deferrable&&(0,P.jsxs)(`label`,{className:I,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:r.initiallyDeferred,onChange:e=>p({initiallyDeferred:e.target.checked})}),`INITIALLY DEFERRED`]})]})]})}var H={primary:`Primary key`,unique:`Unique`,check:`Check`,foreign:`Foreign key`};function he({environment:e,form:t,constraint:n,issues:r,schemas:i,onChange:a,onRemove:s,onTarget:c}){return(0,P.jsxs)(`li`,{className:`border-border border-b py-2`,"aria-label":H[n.kind],children:[(0,P.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,P.jsx)(`strong`,{className:`text-accent-text w-28 text-sm`,children:H[n.kind]}),(0,P.jsx)(`input`,{"aria-label":`Constraint name`,placeholder:o(t,n),value:n.name,onChange:e=>a({...n,name:e.target.value}),className:`${F} w-64 font-mono`}),n.kind===`unique`&&(0,P.jsxs)(`label`,{className:I,title:`PostgreSQL 15 and later`,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:n.nullsNotDistinct,onChange:e=>a({...n,nullsNotDistinct:e.target.checked})}),`NULLS NOT DISTINCT`]}),(0,P.jsx)(`span`,{className:`ml-auto`,children:(0,P.jsx)(z,{label:`Remove ${H[n.kind].toLowerCase()}`,onClick:s,children:(0,P.jsx)(D,{className:`text-destructive size-3.5`})})})]}),(0,P.jsxs)(`div`,{className:`mt-2`,children:[(n.kind===`primary`||n.kind===`unique`)&&(0,P.jsx)(B,{label:`Column`,columns:t.columns,value:n.columns,onChange:e=>a({...n,columns:e})}),n.kind===`check`&&(0,P.jsx)(`input`,{"aria-label":`Check expression`,placeholder:`e.g. total >= 0`,value:n.expression,onChange:e=>a({...n,expression:e.target.value}),className:`${F} w-full font-mono`}),n.kind===`foreign`&&(0,P.jsx)(V,{environment:e,form:t,constraint:n,schemas:i,onChange:a,onTarget:c})]}),(0,P.jsx)(R,{issues:r,row:n.id})]})}function ge({form:e,index:t,issues:n,onChange:i,onRemove:a}){return(0,P.jsxs)(`li`,{className:`border-border border-b py-2`,"aria-label":`Index`,children:[(0,P.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,P.jsx)(`input`,{"aria-label":`Index name`,placeholder:f(e,t),value:t.name,onChange:e=>i({...t,name:e.target.value}),className:`${F} w-64 font-mono`}),(0,P.jsx)(`select`,{"aria-label":`Method`,value:t.method,onChange:e=>i({...t,method:e.target.value}),className:F,children:r.map(e=>(0,P.jsx)(`option`,{children:e},e))}),(0,P.jsxs)(`label`,{className:I,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:t.unique,onChange:e=>i({...t,unique:e.target.checked})}),`UNIQUE`]}),(0,P.jsx)(`span`,{className:`ml-auto`,children:(0,P.jsx)(z,{label:`Remove index`,onClick:a,children:(0,P.jsx)(D,{className:`text-destructive size-3.5`})})})]}),(0,P.jsx)(`ul`,{className:`mt-2 flex flex-col gap-1`,"aria-label":`Index items`,children:t.items.map((n,r)=>{let a=e=>i({...t,items:t.items.map(t=>t.id===n.id?{...t,...e}:t)});return(0,P.jsxs)(`li`,{className:`flex flex-wrap items-center gap-1.5`,children:[(0,P.jsxs)(`select`,{"aria-label":`Item ${r+1}`,value:n.column||`__expr__`,onChange:e=>e.target.value===`__expr__`?a({column:``}):a({column:e.target.value}),className:F,children:[(0,P.jsx)(`option`,{value:`__expr__`,children:`an expression`}),e.columns.map(e=>(0,P.jsx)(`option`,{value:e.id,children:e.name||`(no name)`},e.id))]}),!n.column&&(0,P.jsx)(`input`,{"aria-label":`Expression ${r+1}`,placeholder:`e.g. lower(email)`,value:n.expression,onChange:e=>a({expression:e.target.value}),className:`${F} w-64 font-mono`}),(0,P.jsxs)(`label`,{className:I,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:n.descending,onChange:e=>a({descending:e.target.checked})}),`DESC`]}),(0,P.jsx)(z,{label:`Remove item ${r+1}`,onClick:()=>i({...t,items:t.items.filter(e=>e.id!==n.id)}),children:(0,P.jsx)(j,{className:`size-3.5`})})]},n.id)})}),(0,P.jsxs)(`button`,{type:`button`,onClick:()=>i({...t,items:[...t.items,ee()]}),className:`text-accent-text mt-1 flex items-center gap-1 text-xs`,children:[(0,P.jsx)(k,{className:`size-3`}),` column or expression`]}),(0,P.jsxs)(`div`,{className:`mt-2 grid gap-2 sm:grid-cols-2`,children:[(0,P.jsxs)(`label`,{className:I,children:[`WHERE`,(0,P.jsx)(`input`,{"aria-label":`Where`,placeholder:`a partial index: an expression`,value:t.where,onChange:e=>i({...t,where:e.target.value}),className:`${F} flex-1 font-mono`})]}),(0,P.jsxs)(`div`,{className:I,children:[`INCLUDE`,(0,P.jsx)(B,{label:`Included column`,columns:e.columns,value:t.include,onChange:e=>i({...t,include:e})})]})]}),(0,P.jsx)(R,{issues:n,row:t.id})]})}function _e({statements:e,error:t,failed:n,failure:r,pending:i,onOpenInSql:a}){let[o,s]=(0,N.useState)(!1),c=e?L(e).map(e=>`${e};`).join(`
2
+
3
+ `):``;return(0,P.jsxs)(`section`,{"aria-label":`SQL`,className:`border-input bg-card border p-3`,children:[(0,P.jsxs)(`div`,{className:`mb-2 flex flex-wrap items-center gap-2`,children:[(0,P.jsx)(`h3`,{className:`text-accent-text text-sm uppercase tracking-widest`,children:`SQL`}),i&&(0,P.jsx)(`span`,{className:`text-muted-foreground text-xs`,children:`updating...`}),(0,P.jsxs)(`span`,{className:`ml-auto flex gap-2`,children:[(0,P.jsxs)(T,{variant:`outline`,size:`sm`,onClick:()=>{navigator.clipboard.writeText(c).then(()=>{s(!0),window.setTimeout(()=>s(!1),1500)},()=>void 0)},disabled:!c,children:[o?(0,P.jsx)(ae,{}):(0,P.jsx)(E,{}),` `,o?`Copied`:`Copy`]}),(0,P.jsxs)(T,{variant:`outline`,size:`sm`,onClick:a,disabled:!c,children:[(0,P.jsx)(w,{}),` Open in SQL`]})]})]}),t&&(0,P.jsx)(`p`,{className:`text-muted-foreground mb-2 text-xs`,children:t}),e&&(0,P.jsx)(`ol`,{className:`flex flex-col gap-2`,children:L(e).map((e,t)=>(0,P.jsxs)(`li`,{className:n===t?`border-destructive border-l-2 pl-2`:``,children:[(0,P.jsxs)(`pre`,{className:`font-mono text-xs whitespace-pre-wrap`,children:[e,`;`]}),n===t&&r&&(0,P.jsx)(`p`,{role:`alert`,className:`text-destructive mt-1 text-xs whitespace-pre-wrap`,children:r})]},t))}),!e&&!t&&(0,P.jsx)(`p`,{className:`text-muted-foreground text-xs`,children:`Nothing to show yet.`})]})}var ve={using:{},notValid:[],concurrently:[],cascade:[]},U=(e,t,n)=>n?[...e.filter(e=>e!==t),t]:e.filter(e=>e!==t);function W({environment:t,target:n,cascade:r}){let i=A(()=>e.dependentsOf(t,n),JSON.stringify(n));if(i.error)return(0,P.jsxs)(`p`,{className:`text-muted-foreground text-xs`,children:[`Could not list what depends on it: `,i.error]});if(!i.data)return(0,P.jsx)(`p`,{className:`text-muted-foreground text-xs`,children:`Looking for what depends on it...`});let a=i.data.dependents.filter(e=>e.blocking),o=i.data.mentions;return a.length===0&&o.length===0?(0,P.jsx)(`p`,{className:`text-muted-foreground text-xs`,children:`Nothing else depends on it.`}):(0,P.jsxs)(`div`,{className:`mt-1 text-xs`,children:[a.length>0&&(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(`p`,{className:r?`text-amber-500`:`text-destructive`,children:r?`CASCADE also drops ${a.length} dependent ${a.length===1?`object`:`objects`}:`:`A plain DROP refuses while ${a.length===1?`this exists`:`these exist`}:`}),(0,P.jsx)(`ul`,{"aria-label":`Dependents`,children:a.map(e=>(0,P.jsxs)(`li`,{className:`flex flex-wrap items-baseline gap-2`,children:[(0,P.jsx)(O,{variant:`outline`,children:e.type}),(0,P.jsx)(`span`,{className:`font-mono break-all`,children:e.identity})]},`${e.type}:${e.identity}`))})]}),o.length>0&&(0,P.jsxs)(`p`,{className:`text-muted-foreground`,children:[`Mentioned in function bodies, which only fail when next run:`,` `,o.map(e=>`${e.schema}.${e.name}`).join(`, `),`.`]})]})}var G=e=>e.kind===`column`||e.kind===`constraint`?{kind:e.kind,schema:e.schema,table:e.name,name:e.detail??``}:{kind:e.kind,schema:e.schema,name:e.name},ye=e=>{let t=e.statements.filter(e=>!e.concurrent),n=e.statements.filter(e=>e.concurrent);return{lockTimeout:t.length>0?e.lockTimeout:null,inside:t,apart:n,all:[...t.length>0&&e.lockTimeout?[e.lockTimeout]:[],...t.map(e=>e.sql),...n.map(e=>e.sql)]}};function be({environment:e,plan:t,error:n,options:r,onOptions:i,lockSeconds:a,onLockSeconds:o,failed:s,failure:c,pending:l,onOpenInSql:u}){let[d,f]=(0,N.useState)(!1),p=t?ye(t):void 0,m=p?p.all.map(e=>`${e};`).join(`
4
+
5
+ `):``,h=()=>{navigator.clipboard.writeText(m).then(()=>{f(!0),window.setTimeout(()=>f(!1),1500)},()=>void 0)},g=+!!p?.lockTimeout,_=(t,n)=>(0,P.jsxs)(`li`,{className:s===n?`border-destructive border-l-2 pl-2`:``,children:[(0,P.jsxs)(`pre`,{className:`font-mono text-xs whitespace-pre-wrap`,children:[L([t.sql])[0],`;`]}),t.concurrent&&(0,P.jsx)(`p`,{className:`text-muted-foreground text-xs`,children:`Runs apart from the transaction, after it has committed.`}),t.warnings.map(e=>(0,P.jsx)(`p`,{className:`text-xs text-amber-500`,children:e},e)),(0,P.jsxs)(`div`,{className:`mt-1 flex flex-wrap items-center gap-3`,children:[t.offers.includes(`using`)&&(0,P.jsxs)(`label`,{className:I,children:[`USING`,(0,P.jsx)(`input`,{"aria-label":`USING for ${t.key}`,placeholder:`an expression that converts the old value`,value:r.using[t.key.replace(/^type:/,``)]??``,onChange:e=>i({...r,using:{...r.using,[t.key.replace(/^type:/,``)]:e.target.value}}),className:`${F} w-80 font-mono`})]}),t.offers.includes(`notValid`)&&(0,P.jsxs)(`label`,{className:I,title:`Add it without checking the rows already there, then validate in a second, lighter statement`,children:[(0,P.jsx)(`input`,{type:`checkbox`,"aria-label":`NOT VALID for ${t.key}`,checked:r.notValid.includes(t.key),onChange:e=>i({...r,notValid:U(r.notValid,t.key,e.target.checked)})}),`add NOT VALID, then VALIDATE`]}),t.offers.includes(`concurrently`)&&(0,P.jsxs)(`label`,{className:I,title:`Does not block writes while it builds, but runs outside the transaction`,children:[(0,P.jsx)(`input`,{type:`checkbox`,"aria-label":`CONCURRENTLY for ${t.key}`,checked:r.concurrently.includes(t.key),onChange:e=>i({...r,concurrently:U(r.concurrently,t.key,e.target.checked)})}),`build CONCURRENTLY`]}),t.offers.includes(`cascade`)&&(0,P.jsxs)(`label`,{className:I,title:`Also drop everything that depends on it`,children:[(0,P.jsx)(`input`,{type:`checkbox`,"aria-label":`CASCADE for ${t.key}`,checked:r.cascade.includes(t.key),onChange:e=>i({...r,cascade:U(r.cascade,t.key,e.target.checked)})}),`CASCADE`]})]}),t.drop&&(0,P.jsx)(W,{environment:e,target:G(t.drop),cascade:r.cascade.includes(t.key)}),s===n&&c&&(0,P.jsx)(`p`,{role:`alert`,className:`text-destructive mt-1 text-xs whitespace-pre-wrap`,children:c})]},t.key);return(0,P.jsxs)(`section`,{"aria-label":`SQL`,className:`border-input bg-card border p-3`,children:[(0,P.jsxs)(`div`,{className:`mb-2 flex flex-wrap items-center gap-2`,children:[(0,P.jsx)(`h3`,{className:`text-accent-text text-sm uppercase tracking-widest`,children:`SQL`}),l&&(0,P.jsx)(`span`,{className:`text-muted-foreground text-xs`,children:`updating...`}),(0,P.jsxs)(`label`,{className:`${I} ml-2`,title:`A statement that cannot get its lock in this time fails instead of queueing behind other work`,children:[`lock timeout`,(0,P.jsx)(`input`,{"aria-label":`Lock timeout in seconds`,type:`number`,min:0,value:a,onChange:e=>o(Math.max(0,Number(e.target.value)||0)),className:`${F} w-16`}),`s`]}),(0,P.jsxs)(`span`,{className:`ml-auto flex gap-2`,children:[(0,P.jsxs)(T,{variant:`outline`,size:`sm`,onClick:h,disabled:!m,children:[d?(0,P.jsx)(ae,{}):(0,P.jsx)(E,{}),` `,d?`Copied`:`Copy`]}),(0,P.jsxs)(T,{variant:`outline`,size:`sm`,onClick:u,disabled:!m,children:[(0,P.jsx)(w,{}),` Open in SQL`]})]})]}),n&&(0,P.jsx)(`p`,{className:`text-destructive mb-2 text-xs`,children:n}),t&&p&&p.all.length===0&&(0,P.jsx)(`p`,{className:`text-muted-foreground text-xs`,children:`No changes yet.`}),t&&p&&p.all.length>0&&(0,P.jsxs)(`ol`,{className:`flex flex-col gap-3`,children:[p.lockTimeout&&(0,P.jsx)(`li`,{className:s===0?`border-destructive border-l-2 pl-2`:``,children:(0,P.jsxs)(`pre`,{className:`font-mono text-xs whitespace-pre-wrap`,children:[p.lockTimeout,`;`]})}),p.inside.map((e,t)=>_(e,t+g)),p.apart.map((e,t)=>_(e,p.inside.length+g+t))]}),!t&&!n&&(0,P.jsx)(`p`,{className:`text-muted-foreground text-xs`,children:`Nothing to show yet.`})]})}function xe({environment:t,schema:n,name:r,disabled:i,onDropped:a}){let[o,s]=(0,N.useState)(!1),[c,l]=(0,N.useState)(!1),[u,d]=(0,N.useState)(),[f,p]=(0,N.useState)(!1),[m,h]=(0,N.useState)();return(0,N.useEffect)(()=>{if(!o)return;let i=!0;return e.dropTable(t,n,r,c).then(e=>i&&d(e.statements[0]?.sql)).catch(e=>i&&h(e.message)),()=>{i=!1}},[o,t,n,r,c]),o?(0,P.jsxs)(`section`,{"aria-label":`Drop table`,className:`border-destructive w-full border p-3`,children:[(0,P.jsx)(`h3`,{className:`text-destructive mb-2 text-sm uppercase tracking-widest`,children:`Drop table`}),u&&(0,P.jsxs)(`pre`,{className:`font-mono text-xs whitespace-pre-wrap`,children:[u,`;`]}),(0,P.jsxs)(`label`,{className:`${I} mt-2`,children:[(0,P.jsx)(`input`,{type:`checkbox`,"aria-label":`CASCADE for drop-table`,checked:c,onChange:e=>l(e.target.checked)}),`CASCADE`]}),(0,P.jsx)(W,{environment:t,target:{kind:`table`,schema:n,name:r},cascade:c}),(0,P.jsx)(`p`,{className:`text-muted-foreground mt-2 text-xs`,children:`You will be asked to type two words before it runs. A dropped table and its rows cannot be brought back.`}),(0,P.jsxs)(`div`,{className:`mt-2 flex gap-2`,children:[(0,P.jsx)(T,{variant:`destructive`,onClick:()=>{p(!0),h(void 0),e.dropTable(t,n,r,c,!0).then(()=>{se(t,[{op:`drop`,kind:`table`,schema:n,name:r}]),a()}).catch(e=>h(e.message)).finally(()=>p(!1))},disabled:f||!u,children:f?`Waiting for confirmation...`:`Drop table`}),(0,P.jsx)(T,{variant:`outline`,onClick:()=>s(!1),disabled:f,children:`Cancel`})]}),m&&(0,P.jsx)(`p`,{role:`alert`,className:`text-destructive mt-2 text-xs whitespace-pre-wrap`,children:m})]}):(0,P.jsxs)(T,{variant:`outline`,onClick:()=>s(!0),disabled:i,children:[(0,P.jsx)(D,{className:`text-destructive`}),` Drop table`]})}var Se=e=>{let t=/(\d+)(?:\.\d+)?/.exec(e??``);return t?Number(t[1]):void 0};function K({environment:r,info:o,write:s,loaded:u}){let f=A(()=>e.schemas(r),r).data,p=A(()=>e.info(r),r).data,g=(0,N.useMemo)(()=>u?h(u.design):void 0,[u]),_=!!g,[y,b]=(0,N.useState)(()=>g??d(r)??re(``)),[x,S]=(0,N.useState)(),[C,ie]=(0,N.useState)(ve),[w,ae]=(0,N.useState)(5),[E,D]=(0,N.useState)(new Map),[O,j]=(0,N.useState)(),[M,z]=(0,N.useState)(),[B,pe]=(0,N.useState)(!1),[V,U]=(0,N.useState)(!1),[W,G]=(0,N.useState)(),[K,Ce]=(0,N.useState)(),we=p?.searchPath.split(`,`).map(e=>e.trim().replace(/^"|"$/g,``)).find(e=>f?.some(t=>t.name===e)),q=y.schema||we||f?.find(e=>e.tables>0)?.name||f?.[0]?.name||``,J=(0,N.useMemo)(()=>({...y,schema:q}),[y,q]),Te=(A(()=>q?e.objects(r,q):Promise.resolve(void 0),`${r}/${q}`).data?.types??[]).filter(e=>e.kind===`enum`||e.kind===`domain`||e.kind===`composite`);(0,N.useEffect)(()=>_?void 0:l(r,J),[r,J,_]);let Y=(0,N.useMemo)(()=>n(J,{serverMajor:Se(p?.version),targets:E}),[J,p?.version,E]),X=a(Y),Ee=(0,N.useMemo)(()=>JSON.stringify(c(J,{ids:_})),[J,_]),De=(0,N.useMemo)(()=>g?JSON.stringify(c(g,{ids:!0})):``,[g]),Oe=JSON.stringify(C);(0,N.useEffect)(()=>{if(!J.schema)return;pe(!0);let t=new AbortController,n=window.setTimeout(()=>{(_?e.alter(r,{original:JSON.parse(De),design:JSON.parse(Ee),options:JSON.parse(Oe),lockTimeoutMs:w*1e3},!1,t.signal).then(e=>S(e)):e.design(r,JSON.parse(Ee),!1,t.signal).then(e=>{j(e.statements)})).then(()=>z(void 0)).catch(e=>{t.signal.aborted||(j(void 0),S(void 0),z(e.message))}).finally(()=>!t.signal.aborted&&pe(!1))},de);return()=>{window.clearTimeout(n),t.abort()}},[r,Ee,J.schema,_,De,Oe,w]);let Z=e=>{G(void 0),b({...J,...e})},ke=e=>Z({columns:J.columns.map(t=>t.id===e.id?e:t)}),Ae=e=>Z({columns:J.columns.filter(t=>t.id!==e),constraints:J.constraints.map(t=>t.kind===`primary`||t.kind===`unique`?{...t,columns:t.columns.filter(t=>t!==e)}:t.kind===`foreign`?{...t,columns:t.columns.filter(t=>t!==e),targetColumns:t.targetColumns.filter((n,r)=>t.columns[r]!==e)}:t),indexes:J.indexes.map(t=>({...t,items:t.items.filter(t=>t.column!==e),include:t.include.filter(t=>t!==e)})),partition:J.partition.column===e?{method:J.partition.method,column:``}:J.partition}),je=e=>{let n={id:t(),name:``},r=J.columns.find(e=>e.name)?.id??``,i=e===`primary`?{...n,kind:e,columns:[r]}:e===`unique`?{...n,kind:e,columns:[r],nullsNotDistinct:!1}:e===`check`?{...n,kind:e,expression:``}:{...n,kind:e,columns:[r],target:{self:!1,schema:J.schema,table:``},targetColumns:[``],onDelete:``,onUpdate:``,matchFull:!1,deferrable:!1,initiallyDeferred:!1};Z({constraints:[...J.constraints,i]})},Me=(0,N.useRef)((e,t)=>D(n=>n.get(e)===t?n:new Map(n).set(e,t))).current,Q=!!o?.readOnly&&!s.enabled,$=!!o&&!o.designer,Ne=_?x?ye(x).all.map(e=>`${e};`).join(`
6
+
7
+ `):``:O?L(O).map(e=>`${e};`).join(`
8
+
9
+ `):``,Pe=_&&!!x&&x.statements.length===0;return f?K?(0,P.jsxs)(`section`,{"aria-label":`Created`,className:`border-input bg-card flex flex-col gap-3 border p-4`,children:[(0,P.jsxs)(`p`,{className:`text-sm`,children:[`Created`,` `,(0,P.jsxs)(`code`,{className:`font-mono`,children:[K.schema,`.`,K.name]}),`.`]}),(0,P.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,P.jsx)(T,{onClick:()=>{window.location.hash=v({environment:r,object:{kind:`table`,schema:K.schema,name:K.name}})},children:`Open table`}),o?.seeder&&(0,P.jsxs)(T,{variant:`outline`,onClick:()=>{window.location.hash=v({environment:r,seed:{schema:K.schema,table:K.name}})},children:[(0,P.jsx)(ce,{}),` Seed it`]}),(0,P.jsx)(T,{variant:`outline`,onClick:()=>{Ce(void 0),j(void 0),b(re(K.schema))},children:`Design another`})]})]}):(0,P.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,P.jsx)(`datalist`,{id:`design-defaults`,children:m.map(e=>(0,P.jsx)(`option`,{value:e},e))}),(0,P.jsxs)(`section`,{"aria-label":`Table`,className:`flex flex-col gap-3`,children:[(0,P.jsxs)(`div`,{className:`flex flex-wrap items-end gap-3`,children:[(0,P.jsxs)(`label`,{className:`${I} flex-col items-start`,children:[`Schema`,(0,P.jsx)(`select`,{"aria-label":`Schema`,value:q,onChange:e=>Z({schema:e.target.value}),className:F,children:f.map(e=>(0,P.jsx)(`option`,{children:e.name},e.name))})]}),(0,P.jsxs)(`label`,{className:`${I} flex-col items-start`,children:[`Name`,(0,P.jsx)(`input`,{"aria-label":`Table name`,placeholder:`orders`,value:J.name,onChange:e=>Z({name:e.target.value}),className:`${F} w-64 font-mono`})]}),(0,P.jsxs)(`label`,{className:I,title:`Not written to the write-ahead log: faster, but lost in a crash`,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:J.unlogged,onChange:e=>Z({unlogged:e.target.checked})}),`UNLOGGED`]}),(0,P.jsxs)(`label`,{className:I,children:[`Partition by`,(0,P.jsxs)(`select`,{"aria-label":`Partition method`,disabled:_,value:J.partition.method,onChange:e=>Z({partition:{...J.partition,method:e.target.value}}),className:F,children:[(0,P.jsx)(`option`,{value:``,children:`not partitioned`}),(0,P.jsx)(`option`,{value:`range`,children:`range`}),(0,P.jsx)(`option`,{value:`list`,children:`list`}),(0,P.jsx)(`option`,{value:`hash`,children:`hash`})]}),J.partition.method&&(0,P.jsxs)(`select`,{"aria-label":`Partition column`,disabled:_,value:J.partition.column,onChange:e=>Z({partition:{...J.partition,column:e.target.value}}),className:F,children:[(0,P.jsx)(`option`,{value:``,children:`pick a column`}),J.columns.map(e=>(0,P.jsx)(`option`,{value:e.id,children:e.name||`(no name)`},e.id))]})]})]}),(0,P.jsxs)(`label`,{className:I,children:[`Comment`,(0,P.jsx)(`input`,{"aria-label":`Table comment`,value:J.comment,onChange:e=>Z({comment:e.target.value}),className:`${F} flex-1`})]}),(0,P.jsx)(R,{issues:Y,row:void 0})]}),(0,P.jsxs)(`section`,{"aria-label":`Columns`,children:[(0,P.jsx)(`h3`,{className:`text-accent-text mb-1 text-sm uppercase tracking-widest`,children:`Columns`}),(0,P.jsx)(`ul`,{children:J.columns.map((e,t)=>(0,P.jsx)(me,{column:e,at:t,count:J.columns.length,issues:Y,databaseTypes:Te,onChange:ke,onMove:e=>Z({columns:fe(J.columns,t,e)}),onRemove:()=>Ae(e.id)},e.id))}),(0,P.jsxs)(T,{variant:`outline`,size:`sm`,className:`mt-2`,onClick:()=>Z({columns:[...J.columns,te()]}),children:[(0,P.jsx)(k,{}),` Add column`]})]}),(0,P.jsxs)(`section`,{"aria-label":`Constraints`,children:[(0,P.jsx)(`h3`,{className:`text-accent-text mb-1 text-sm uppercase tracking-widest`,children:`Constraints`}),(0,P.jsx)(`ul`,{children:J.constraints.map(e=>(0,P.jsx)(he,{environment:r,form:J,constraint:e,issues:Y,schemas:f.map(e=>e.name),onChange:e=>Z({constraints:J.constraints.map(t=>t.id===e.id?e:t)}),onRemove:()=>Z({constraints:J.constraints.filter(t=>t.id!==e.id)}),onTarget:Me},e.id))}),(0,P.jsx)(`div`,{className:`mt-2 flex flex-wrap gap-2`,children:[`primary`,`unique`,`check`,`foreign`].map(e=>(0,P.jsxs)(T,{variant:`outline`,size:`sm`,onClick:()=>je(e),children:[(0,P.jsx)(k,{}),` `,H[e]]},e))})]}),(0,P.jsxs)(`section`,{"aria-label":`Indexes`,children:[(0,P.jsx)(`h3`,{className:`text-accent-text mb-1 text-sm uppercase tracking-widest`,children:`Indexes`}),(0,P.jsx)(`ul`,{children:J.indexes.map(e=>(0,P.jsx)(ge,{form:J,index:e,issues:Y,onChange:e=>Z({indexes:J.indexes.map(t=>t.id===e.id?e:t)}),onRemove:()=>Z({indexes:J.indexes.filter(t=>t.id!==e.id)})},e.id))}),(0,P.jsxs)(T,{variant:`outline`,size:`sm`,className:`mt-2`,onClick:()=>Z({indexes:[...J.indexes,{id:t(),name:``,unique:!1,method:`btree`,items:[ee()],include:[],where:``}]}),children:[(0,P.jsx)(k,{}),` Add index`]})]}),_?(0,P.jsx)(be,{environment:r,plan:x,error:M,options:C,onOptions:ie,lockSeconds:w,onLockSeconds:ae,failed:W?.statement,failure:W?.statement===void 0?void 0:W.message,pending:B,onOpenInSql:()=>ne(r,Ne,!1)}):(0,P.jsx)(_e,{statements:O,error:M,failed:W?.statement,failure:W?.statement===void 0?void 0:W.message,pending:B,onOpenInSql:()=>ne(r,Ne,!1)}),_&&u&&u.untouched.length>0&&(0,P.jsxs)(`p`,{className:`text-muted-foreground text-xs`,children:[`Left as they are, because the designer cannot show them:`,` `,u.untouched.map(e=>`${e.name} (${e.reason})`).join(`; `),`.`]}),(0,P.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[_?(0,P.jsxs)(T,{onClick:()=>{U(!0),G(void 0),e.alter(r,{original:JSON.parse(De),design:c(J,{ids:!0}),options:C,lockTimeoutMs:w*1e3},!0).then(()=>{se(r,[]),window.location.hash=v({environment:r,object:{kind:`table`,schema:J.schema,name:J.name}})}).catch(e=>G({statement:e.statement,message:e.message})).finally(()=>U(!1))},disabled:V||X||!x||Pe||!!M||Q||$,title:$?`The designer is turned off`:Q?`This environment is read only`:X?`Fix the errors first`:void 0,children:[(0,P.jsx)(le,{}),` `,V?`Applying...`:`Apply changes`]}):(0,P.jsxs)(T,{onClick:()=>{U(!0),G(void 0),e.design(r,c(J),!0).then(()=>{se(r,[{op:`add`,kind:`table`,schema:J.schema,name:J.name}]),l(r,void 0),Ce({schema:J.schema,name:J.name})}).catch(e=>G({statement:e.statement,message:e.message})).finally(()=>U(!1))},disabled:V||X||!J.schema||!O||Q||$,title:$?`The designer is turned off`:Q?`This environment is read only`:X?`Fix the errors first`:void 0,children:[(0,P.jsx)(le,{}),` `,V?`Creating...`:`Create table`]}),(0,P.jsx)(T,{variant:`outline`,onClick:()=>{G(void 0),j(void 0),b(g??re(J.schema)),g&&ie(ve)},disabled:V||(_?JSON.stringify(c(J,{ids:!0}))===De&&Oe===JSON.stringify(ve):i(J)),children:_?`Reset`:`Clear`}),_&&(0,P.jsx)(xe,{environment:r,schema:g.schema,name:g.name,disabled:V||Q||$,onDropped:()=>{window.location.hash=v({environment:r})}}),Q&&s.available&&!$&&(0,P.jsx)(ue,{write:s})]}),Pe&&(0,P.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:`The form matches the table: there is nothing to apply.`}),$&&(0,P.jsxs)(`p`,{className:`text-muted-foreground text-sm`,children:[`The designer is turned off for `,r,`, so the SQL can only be previewed. Add`,` `,(0,P.jsx)(`code`,{children:`designer: true`}),` to its explorer.yaml to `,_?`change tables`:`create tables`,`.`]}),Q&&!$&&(0,P.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:s.available?`This environment is read only: switch on write mode to ${_?`change the table`:`create the table`}. The SQL is shown either way.`:`This environment is read only, so the SQL can only be previewed here.`}),s.error&&(0,P.jsx)(`p`,{className:`text-destructive text-sm`,children:s.error}),W&&W.statement===void 0&&(0,P.jsx)(`p`,{role:`alert`,className:`text-destructive text-sm whitespace-pre-wrap`,children:W.message})]}):(0,P.jsx)(oe,{className:`h-40`})}function Ce({environment:t,schema:n,table:r,info:i,write:a}){let o=A(()=>e.loadDesign(t,n,r),`${t}/${n}/${r}`);return o.error?(0,P.jsx)(`p`,{className:`text-destructive text-sm`,children:o.error}):o.data?(0,P.jsx)(K,{environment:t,info:i,write:a,loaded:o.data},`${t}/${n}/${r}`):(0,P.jsx)(oe,{className:`h-40`})}function we({environment:e,info:t,write:n,design:r}){let i=r?.schema&&r.table?{schema:r.schema,table:r.table}:void 0;return(0,P.jsxs)(P.Fragment,{children:[(0,P.jsxs)(`h2`,{className:`text-accent-text mb-1 flex items-center gap-2 text-2xl`,children:[(0,P.jsx)(le,{className:`size-6`}),` `,i?`Edit design of ${i.schema}.${i.table}`:`Design`]}),(0,P.jsx)(`p`,{className:`text-muted-foreground mb-4 text-sm`,children:i?`Change the table: rename, add and drop columns, keys and indexes. The ALTER statements are worked out from what you change and shown as you go; Apply runs them in one transaction with a short lock timeout, so a busy table fails fast. Anything that drops something asks for two words first.`:`Design a new table: its columns, keys and indexes. The SQL is shown as you go, and Create runs all of it in one transaction, so the table is made whole or not at all. The form is kept in this browser until the table is created or cleared.`}),i?(0,P.jsx)(Ce,{environment:e,schema:i.schema,table:i.table,info:t,write:n}):(0,P.jsx)(K,{environment:e,info:t,write:n},e)]})}export{we as DesignView};
@@ -0,0 +1 @@
1
+ import{$ as e,ct as t,o as n,ot as r,rt as i}from"./route-DO6IZ7of.js";import{Gt as a,Wt as o,tn as s}from"./index-CDcnUacl.js";var c=t(r(),1),l=i(),u=260,d=30,f=22,p=40,m=24,h=12,g=6,_=5;function v(e){let t=new Set(e.map(e=>e.name));return e.flatMap(e=>e.columns.flatMap(n=>{let r=n.references;return r&&r.schema===e.schema&&r.table!==e.name&&t.has(r.table)?[[e.name,r.table]]:[]}))}function y(e){let t=Math.max(1,Math.round(Math.sqrt(e.length))),n=Math.ceil(e.length/t)*t,r=v(e),i=e=>{let n=new Map;return e.forEach((e,t)=>e&&n.set(e.name,t)),r.reduce((e,[r,i])=>{let[a,o]=[n.get(r),n.get(i)],s=Math.abs(a%t-o%t),c=Math.abs(Math.floor(a/t)-Math.floor(o/t));return e+s+c+(s>1?3:0)+(s===0?.5:0)},0)},a=t=>{let r=t,a=i(r);for(let t=0;t<20&&e.length<=150;t++){let e=!1;for(let t=0;t<n;t++)for(let o=t+1;o<n;o++){if(!r[t]&&!r[o])continue;let n=[...r];[n[t],n[o]]=[n[o],n[t]];let s=i(n);s<a-1e-9&&(r=n,a=s,e=!0)}if(!e)break}return{cells:r,best:a}},o=new Map;for(let[e,t]of r)for(let n of[e,t])o.set(n,(o.get(n)??0)+1);let s=[...e].sort((e,t)=>(o.get(t.name)??0)-(o.get(e.name)??0)),c=[];for(;s.length>0;){c.push(s.shift());for(let e=0;e<c.length;e++)for(let[t,n]of r){let r=t===c[e].name?n:n===c[e].name?t:void 0,i=s.findIndex(e=>e.name===r);i>=0&&c.push(...s.splice(i,1))}}let l=e=>[...e,...Array(n-e.length).fill(void 0)],{cells:u}=[a(l(e)),a(l(c))].sort((e,t)=>e.best-t.best)[0],d=[];for(let e=0;e<n;e+=t)d.push(u.slice(e,e+t));let f=d.filter(e=>e.some(Boolean)),p=Array.from({length:t},(e,t)=>f.some(e=>e[t])).flatMap((e,t)=>e?[t]:[]);return f.map(e=>p.map(t=>e[t]))}function b(e,t,n){let r=new Map,i=[],a=m,o=m;return e.forEach((e,s)=>{let c=m,l=0;e.forEach((e,n)=>{if(e){let t=a+(n%2==1?f/2:0),i=d+f*Math.max(e.columns.length,1);r.set(e.name,{table:e,x:c,y:t,height:i,col:n,row:s}),l=Math.max(l,t+i-a)}c+=u+t}),o=Math.max(o,c-t/2+m),i.push(a+l+n/2),a+=l+n}),{boxes:r,width:o,height:a-n+m,channels:i}}function x(e,t,n,r){let i=e.y+d+f*t+f/2,a=n.y+d+f*r+f/2;if(n.col===e.col){let t=e.x+u;return{x1:t,y1:i,dir1:1,x2:t,y2:a,dir2:1,gaps:[e.col]}}let o=n.col>e.col,s={x1:o?e.x+u:e.x,y1:i,dir1:o?1:-1,x2:o?n.x:n.x+u,y2:a,dir2:o?-1:1};return Math.abs(n.col-e.col)===1?{...s,gaps:[Math.min(e.col,n.col)]}:{...s,gaps:o?[e.col,n.col-1]:[e.col-1,n.col],channel:n.row<e.row?e.row-1:e.row}}function S(e){let t=[...e.values()].flatMap(t=>t.table.columns.flatMap((n,r)=>{let i=n.references,a=i&&i.schema===t.table.schema?e.get(i.table):void 0,o=a?.table.columns.findIndex(e=>e.name===i?.column)??-1;return!a||o<0?[]:[{...x(t,r,a,o),key:`${t.table.name}.${n.name}`,unique:n.unique,optional:n.nullable}]})),n=new Map;for(let e of t)for(let[t,r]of[[1,e.y2],[2,e.y1]]){let i=`${e[`x${t}`]},${e[`y${t}`]}`;n.set(i,[...n.get(i)??[],{plan:e,end:t,other:r}])}for(let e of n.values()){if(e.length<2)continue;e.sort((e,t)=>e.other-t.other);let t=Math.min(5,14/(e.length-1));e.forEach(({plan:n,end:r},i)=>{n[`y${r}`]+=(i-(e.length-1)/2)*t})}return t}function C(e){let t=new Map,n=new Map;for(let r of e){for(let e of r.gaps)t.set(e,(t.get(e)??0)+1);r.channel!==void 0&&n.set(r.channel,(n.get(r.channel)??0)+1)}return{gap:Math.max(0,...t.values()),channel:Math.max(0,...n.values())}}function w(e,t,n){let r=new Map,i=new Map;for(let t of e)t.channel!==void 0&&i.set(t.channel,[...i.get(t.channel)??[],t]);for(let[e,n]of i)n.sort((e,t)=>e.x1+e.x2-(t.x1+t.x2)),n.forEach((i,a)=>{r.set(i.key,t.channels[e]+(a-(n.length-1)/2)*h)});let a=e.flatMap(e=>e.gaps.map((t,n)=>{let i=r.get(e.key),[a,o]=e.gaps.length===1?[e.y1,e.y2]:n===0?[e.y1,i]:[i,e.y2];return{key:e.key,index:n,gap:t,from:a,to:o}})),o=new Map,s=new Map;for(let e of a)s.set(e.gap,[...s.get(e.gap)??[],e]);for(let[e,t]of s){t.sort((e,t)=>e.from+e.to-(t.from+t.to));let r=m+e*(u+n)+u+n/2;t.forEach((e,n)=>{o.set(`${e.key}:${e.index}`,r+(n-(t.length-1)/2)*h)})}return new Map(e.map(e=>{let t=t=>o.get(`${e.key}:${t}`),n=r.get(e.key),i=e.gaps.length===1?[[e.x1,e.y1],[t(0),e.y1],[t(0),e.y2],[e.x2,e.y2]]:[[e.x1,e.y1],[t(0),e.y1],[t(0),n],[t(1),n],[t(1),e.y2],[e.x2,e.y2]];return[e.key,i]}))}function T(e,t,n){let r=(e,t)=>Math.hypot(t[0]-e[0],t[1]-e[1])||1,i=(e,t,n)=>[e[0]+(t[0]-e[0])/r(e,t)*n,e[1]+(t[1]-e[1])/r(e,t)*n],a=(t,r)=>{if(t[1]!==r[1])return`L${r[0]},${r[1]}`;let i=Math.sign(r[0]-t[0]),a=t[1],o=Math.min(t[0],r[0])+_+1,s=Math.max(t[0],r[0])-_-1,c=n.filter(t=>t.key!==e&&t.x>o&&t.x<s&&t.top<a&&a<t.bottom).map(e=>e.x).sort((e,t)=>i*(e-t)),l=``,u=-1/0;for(let e of c)i*e<u+10+2||(u=i*e,l+=`L${e-i*_},${a} A${_},${_} 0 0 ${+(i>0)} ${e+i*_},${a} `);return`${l}L${r[0]},${r[1]}`},o=`M${t[0][0]},${t[0][1]} `,s=t[0];for(let e=1;e<t.length-1;e++){let[n,c,l]=[t[e-1],t[e],t[e+1]],u=i(c,n,Math.min(g,r(n,c)/2)),d=i(c,l,Math.min(g,r(c,l)/2));o+=`${a(s,u)} Q${c[0]},${c[1]} ${d[0]},${d[1]} `,s=d}return o+a(s,t[t.length-1])}var E=(e,t)=>`M${e},${t-6} L${e},${t+6}`;function D({x:e,y:t,dir:n,unique:r}){let i={cx:e+n*18,cy:t,r:4};return{symbol:r?E(e+n*9,t):`M${e+n*12},${t} L${e},${t-6} M${e+n*12},${t} L${e},${t+6} M${e+n*12},${t} L${e},${t}`,ring:i}}function O({x:e,y:t,dir:n,optional:r}){return r?{symbol:E(e+n*8,t),ring:{cx:e+n*16,cy:t,r:4}}:{symbol:`${E(e+n*8,t)} ${E(e+n*14,t)}`,ring:void 0}}function k({symbol:e,ring:t}){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(`path`,{d:e,fill:`none`,strokeWidth:1.5,className:`stroke-accent-text`}),t&&(0,l.jsx)(`circle`,{...t,strokeWidth:1.5,className:`fill-card stroke-accent-text`})]})}function A({environment:e,tables:t}){let{boxes:r,width:i,height:a,edges:o}=(0,c.useMemo)(()=>{let e=y(t),{gap:n,channel:r}=C(S(b(e,60,p).boxes)),i=48+h*(n+1),a=b(e,i,Math.max(p,h*(r+1))),o=S(a.boxes),s=w(o,a,i),c=[...s].flatMap(([e,t])=>t.slice(0,-1).flatMap(([n,r],i)=>{let[a,o]=t[i+1];return n===a&&r!==o?[{key:e,x:n,top:Math.min(r,o),bottom:Math.max(r,o)}]:[]})),l=o.map(e=>({key:e.key,d:T(e.key,s.get(e.key),c),child:{x:e.x1,y:e.y1,dir:e.dir1,unique:e.unique},parent:{x:e.x2,y:e.y2,dir:e.dir2,optional:e.optional}}));return{...a,edges:l}},[t]);return(0,l.jsx)(`div`,{className:`border-border overflow-auto border`,children:(0,l.jsxs)(`svg`,{role:`img`,"aria-label":`Entity relationship diagram`,width:i,height:a,className:`min-w-full`,children:[o.map(({key:e,d:t,child:n,parent:r})=>(0,l.jsxs)(`g`,{opacity:.85,children:[(0,l.jsx)(`path`,{d:t,fill:`none`,strokeWidth:1.5,className:`stroke-accent-text`}),(0,l.jsx)(k,{...D(n)}),(0,l.jsx)(k,{...O(r)})]},e)),[...r.values()].map(({table:t,x:r,y:i,height:a})=>(0,l.jsxs)(`g`,{transform:`translate(${r},${i})`,children:[(0,l.jsx)(`rect`,{width:u,height:a,className:`fill-card stroke-border`}),(0,l.jsx)(`rect`,{width:u,height:d,className:`fill-sidebar`}),(0,l.jsx)(`a`,{href:n({environment:e,object:{kind:`table`,schema:t.schema,name:t.name}}),children:(0,l.jsx)(`text`,{x:10,y:20,className:`fill-accent-text text-sm font-bold`,children:t.name})}),t.columns.map((e,n)=>{let r=e.references&&e.references.schema!==t.schema;return(0,l.jsxs)(`g`,{transform:`translate(0,${d+f*n})`,children:[(0,l.jsxs)(`text`,{x:10,y:15,className:`fill-foreground text-xs`,children:[e.primaryKey?`🔑 `:e.references?`↗ `:``,e.name]}),(0,l.jsx)(`text`,{x:250,y:15,textAnchor:`end`,className:`fill-muted-foreground text-xs`,children:r?`→ ${e.references.schema}.${e.references.table}`:e.type})]},e.name)})]},t.name))]})})}var j=[[`zero or many`,{x:0,y:0,dir:1,unique:!1},`child`],[`zero or one`,{x:0,y:0,dir:1,unique:!0},`child`],[`exactly one`,{x:0,y:0,dir:1,optional:!1},`parent`],[`zero or one (nullable key)`,{x:0,y:0,dir:1,optional:!0},`parent`]];function M(){return(0,l.jsx)(`ul`,{"aria-label":`Legend`,className:`text-muted-foreground mb-4 flex flex-wrap gap-x-6 gap-y-1 text-xs`,children:j.map(([e,t,n])=>(0,l.jsxs)(`li`,{className:`flex items-center gap-2`,children:[(0,l.jsxs)(`svg`,{width:34,height:14,viewBox:`-2 -7 34 14`,"aria-hidden":!0,children:[(0,l.jsx)(`path`,{d:`M0,0 L30,0`,className:`stroke-accent-text`,strokeWidth:1.5}),(0,l.jsx)(k,{...n===`child`?D(t):O(t)})]}),e]},e))})}function N({environment:t,schema:n}){let{data:r,error:i}=o(()=>e.erd(t,n),`${t}/${n}`);return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)(`h2`,{className:`text-accent-text mb-1 flex items-center gap-2 text-2xl`,children:[(0,l.jsx)(s,{className:`size-6`}),n,(0,l.jsx)(`span`,{className:`text-muted-foreground text-sm`,children:`ERD`})]}),(0,l.jsx)(`p`,{className:`text-muted-foreground mb-4 text-sm`,children:`Tables of the schema in crow's foot notation, with a line from each foreign key to the column it references. Click a table name to open it.`}),(0,l.jsx)(M,{}),i?(0,l.jsx)(`p`,{className:`text-destructive text-sm`,children:i}):r?r.length===0?(0,l.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:`This schema has no tables.`}):(0,l.jsx)(A,{environment:t,tables:r}):(0,l.jsx)(a,{className:`h-80`})]})}export{N as ErdView};
@@ -0,0 +1,5 @@
1
+ import{G as e,U as t,p as n}from"./route-DO6IZ7of.js";var r=` `,i=[[`with`],[`select`],[`from`],[`where`],[`group`,`by`],[`order`,`by`],[`having`],[`limit`],[`offset`],[`union`],[`intersect`],[`except`],[`values`],[`insert`,`into`],[`update`],[`set`],[`delete`,`from`],[`returning`],[`window`],[`on`,`conflict`]],a=new Set([`join`,`inner`,`left`,`right`,`full`,`cross`,`natural`,`outer`]),o=new Set([`select`,`group by`,`order by`,`set`,`returning`]),s=new Set([`where`,`having`,`on`]),c=new Set([`cast`,`filter`,`over`,`left`,`right`]),l=(e,t)=>e?.kind===`word`&&e.text.toLowerCase()===t;function u(e){let u=t(e).filter(e=>e.kind!==`space`),d=[],f=``,p=0,m=[{base:0,clause:``,between:!1,depth:0}],h,g=!1,_=e=>{f.trim()!==``&&d.push(r.repeat(p)+f),f=``,p=e,h=void 0},v=(e,t)=>{let r=h!==void 0;if(h){let t=h.text;t===`(`||t===`[`||t===`.`||t===`::`||g&&h.kind===`operator`||[`)`,`]`,`,`,`;`,`.`,`::`].includes(e.text)?r=!1:e.text===`[`?r=h.kind!==`word`&&h.kind!==`quoted`:e.text===`(`&&(r=!(h.kind===`quoted`||h.kind===`word`&&t.toLowerCase()!==`conflict`&&(!n(t)||c.has(t.toLowerCase()))||t===`)`||t===`]`))}f+=(r?` `:``)+t,h=e},y=()=>m[m.length-1],b=e=>{let t=0;for(let n=e;n<u.length;n++){let e=u[n];if(e.text===`(`||e.text===`[`)t++;else if(e.text===`)`||e.text===`]`){if(--t<0)return!1}else if(t===0&&e.text===`,`)return!0;else if(t===0&&e.kind===`word`&&i.some(e=>e.every((e,t)=>l(u[n+t],e))))return!1}return!1};for(let e=0;e<u.length;e++){let t=u[e],r=t.text.toLowerCase(),c=y();if(t.kind===`comment`)v(t,t.text),t.text.startsWith(`--`)&&_(p);else if(t.kind===`word`){let d=c.depth===0&&!l(u[e-1],`distinct`)&&!l(u[e-1],`for`)?i.find(t=>t.every((t,n)=>l(u[e+n],t))):void 0;if(d){_(c.base),c.clause=d.join(` `),c.between=!1;for(let t=0;t<d.length;t++)v(u[e+t],d[t].toUpperCase());e+=d.length-1,g=!1,o.has(c.clause)&&b(e+1)&&(l(u[e+1],`distinct`)&&v(u[++e],`DISTINCT`),_(c.base+1));continue}let f=a.has(r)&&(u[e+1]?.text!==`(`||r!==`left`&&r!==`right`);c.depth===0&&f?a.has(h?.text.toLowerCase()??``)||(_(c.base),c.clause=`join`):c.depth===0&&r===`on`&&c.clause===`join`?(_(c.base+1),c.clause=`on`):c.depth===0&&(r===`and`||r===`or`)&&s.has(c.clause)?r===`and`&&c.between?c.between=!1:_(c.base+1):r===`between`&&c.depth===0&&(c.between=!0),v(t,n(t.text)?t.text.toUpperCase():t.text),g=!1}else{if(t.kind===`punct`){if(t.text===`(`){v(t,`(`),g=!0;let n=u[e+1];l(n,`select`)||l(n,`with`)?(m.push({base:p+1,clause:``,between:!1,depth:0}),_(p+1)):c.depth++;continue}if(t.text===`)`){c.depth>0?(c.depth--,v(t,`)`)):(m.length>1&&_(m.pop().base-1),v(t,`)`)),g=!1;continue}if(t.text===`,`){v(t,`,`),g=!0,c.depth===0&&(o.has(c.clause)||c.clause===`with`)&&_(c.clause===`with`?c.base:c.base+1);continue}}if(t.kind===`operator`&&t.text!==`::`){let e=h?.kind===`word`&&n(h.text),r=h===void 0||h.kind===`operator`||h.text===`(`||h.text===`,`||e,i=/^[+\-]$/.test(t.text)&&r;v(t,t.text),g=i}else v(t,t.text),g=!1}}return _(0),d.join(`
2
+ `)}function d(t){let n=e(t);return n.length===0?t:n.map(e=>`${u(e.text)};`).join(`
3
+
4
+ `)+`
5
+ `}export{u as n,d as t};
@@ -0,0 +1 @@
1
+ import{at as e,ct as t,ot as n,rt as r}from"./route-DO6IZ7of.js";import{Qt as i}from"./index-CDcnUacl.js";var a={name:`maximize`,size:24,node:[[`path`,{d:`M8 3H5a2 2 0 0 0-2 2v3`,key:`1dcmit`}],[`path`,{d:`M21 8V5a2 2 0 0 0-2-2h-3`,key:`1e4gt3`}],[`path`,{d:`M3 16v3a2 2 0 0 0 2 2h3`,key:`wsl5sc`}],[`path`,{d:`M16 21h3a2 2 0 0 0 2-2v-3`,key:`18trek`}]]};a.node;var o=e(a),s={name:`minus`,size:24,node:[[`path`,{d:`M5 12h14`,key:`1ays0h`}]]};s.node;var c=e(s),l=t(n(),1);function u(e,t){let n=e.y+e.height/2,r=t.y+t.height/2;if(e.id===t.id){let t=e.x+e.width,r=e.y+10;return{d:`M${t},${r} C${t+46},${r-22} ${t+46},${e.y+e.height-6} ${t},${e.y+e.height-10}`,mid:{x:t+40,y:n}}}if(Math.abs(e.x-t.x)<1){let t=e.x+e.width,i=40+Math.min(80,Math.abs(n-r)/4);return{d:`M${t},${n} C${t+i},${n} ${t+i},${r} ${t},${r}`,mid:{x:t+i*.75,y:(n+r)/2}}}let i=e.x<t.x,a=i?e.x+e.width:e.x,o=i?t.x:t.x+t.width,s=Math.max(30,Math.abs(o-a)/2),c=i?1:-1;return{d:`M${a},${n} C${a+c*s},${n} ${o-c*s},${r} ${o},${r}`,mid:{x:(a+o)/2,y:(n+r)/2}}}var d=.1;function f(e,t,n=32){if(e.width<=0||e.height<=0||t.width<=0||t.height<=0)return{x:0,y:0,k:1};let r=Math.min(1.5,Math.max(d,Math.min((t.width-2*n)/e.width,(t.height-2*n)/e.height)));return{k:r,x:(t.width-e.width*r)/2,y:(t.height-e.height*r)/2}}function p(e,t,n){let r=Math.min(3,Math.max(d,e.k*t)),i=r/e.k;return{k:r,x:n.x-(n.x-e.x)*i,y:n.y-(n.y-e.y)*i}}function m(e,t=38){let n=0;for(let t of e)n=n*31+t.charCodeAt(0)>>>0;return`hsl(${n*137%360} 55% ${t}%)`}var h=e=>m(e,55),g=r();function _(){let e=(0,l.useRef)(null),[t,n]=(0,l.useState)({x:0,y:0,k:1}),r=(0,l.useRef)(!1);return(0,l.useEffect)(()=>{let t=e.current;if(!t)return;let r=e=>{e.preventDefault();let r=t.getBoundingClientRect();if(!e.ctrlKey&&Math.abs(e.deltaX)>Math.abs(e.deltaY)){n(t=>({...t,x:t.x-e.deltaX,y:t.y-e.deltaY}));return}let i=Math.exp(-e.deltaY*(e.ctrlKey?.01:.0015));n(t=>p(t,i,{x:e.clientX-r.left,y:e.clientY-r.top}))};return t.addEventListener(`wheel`,r,{passive:!1}),()=>t.removeEventListener(`wheel`,r)},[]),{frame:e,view:t,setView:n,dragged:r,startDrag:e=>{if(e.button!==0)return;r.current=!1;let t={x:e.clientX,y:e.clientY},i=i=>{let a=i.clientX-t.x,o=i.clientY-t.y;!r.current&&Math.hypot(i.clientX-e.clientX,i.clientY-e.clientY)<4||(r.current=!0,t={x:i.clientX,y:i.clientY},n(e=>({...e,x:e.x+a,y:e.y+o})))},a=()=>{window.removeEventListener(`pointermove`,i),window.removeEventListener(`pointerup`,a)};window.addEventListener(`pointermove`,i),window.addEventListener(`pointerup`,a)},zoomBy:t=>{let r=e.current?.getBoundingClientRect();r&&n(e=>p(e,t,{x:r.width/2,y:r.height/2}))}}}function v({zoomBy:e,fit:t}){return(0,g.jsx)(`div`,{className:`absolute top-2 right-2 z-10 flex gap-1`,children:[{label:`Zoom in`,icon:i,run:()=>e(1.25)},{label:`Zoom out`,icon:c,run:()=>e(.8)},{label:`Fit to screen`,icon:o,run:t}].map(({label:e,icon:t,run:n})=>(0,g.jsx)(`button`,{type:`button`,"aria-label":e,title:e,onClick:n,className:`bg-card border-input hover:text-accent-text rounded-lg border p-1.5`,children:(0,g.jsx)(t,{className:`size-4`})},e))})}var y=7e3,b=.035,x=.55,S=34,C=12,w=.012,T=.0228;function E(e){let t=2166136261;for(let n of e)t=Math.imul(t^n.charCodeAt(0),16777619)>>>0;return t/4294967296}function D(e,t,n=new Map){let r=new Map;for(let t of e){let e=n.get(t.id);e&&r.set(t.id,{x:e.x,y:e.y})}let i=new Map;for(let{source:e,target:n}of t)i.set(e,[...i.get(e)??[],n]),i.set(n,[...i.get(n)??[],e]);let a=0,o=e.filter(e=>!r.has(e.id));for(;o.length>0;){let e=[];for(let t of o){let n=(i.get(t.id)??[]).find(e=>r.has(e));if(n){let e=r.get(n),i=E(t.id)*Math.PI*2;r.set(t.id,{x:e.x+Math.cos(i)*120*.6,y:e.y+Math.sin(i)*120*.6})}else e.push(t)}if(e.length===o.length){let t=e.shift(),n=a*2.399963,i=40*Math.sqrt(a+1);r.set(t.id,{x:Math.cos(n)*i,y:Math.sin(n)*i}),a++}o=e}return e.map(e=>({id:e.id,r:e.r,x:r.get(e.id).x,y:r.get(e.id).y,vx:0,vy:0,pinned:!1}))}function O(e,t){let n=new Map(e.map(e=>[e.id,e.id])),r=e=>{let t=e;for(;n.get(t)!==t;)t=n.get(t);return n.set(e,t),t};for(let{source:e,target:i}of t)n.has(e)&&n.has(i)&&n.set(r(e),r(i));return new Map(e.map(e=>[e.id,r(e.id)]))}function k(e,t,n){let r=new Map(e.map(e=>[e.id,e])),i=new Map;for(let{source:e,target:n}of t)i.set(e,(i.get(e)??0)+1),i.set(n,(i.get(n)??0)+1);let a=O(e,t);for(let t=0;t<e.length;t++){let r=e[t];for(let i=t+1;i<e.length;i++){let t=e[i],o=t.x-r.x,s=t.y-r.y,c=o*o+s*s;if(c<.01){let e=E(r.id+t.id)*Math.PI*2;o=Math.cos(e),s=Math.sin(e),c=1}let l=Math.sqrt(c),u=(a.get(r.id)===a.get(t.id)?1:C)*y*n/c,d=o/l*u,f=s/l*u,p=r.r+t.r+S;if(l<p){let e=(p-l)/l*.5;d+=o*e,f+=s*e}r.vx-=d,r.vy-=f,t.vx+=d,t.vy+=f}}for(let{source:e,target:a}of t){let t=r.get(e),o=r.get(a);if(!t||!o||t===o)continue;let s=o.x+o.vx-t.x-t.vx,c=o.y+o.vy-t.y-t.vy,l=Math.hypot(s,c)||1,u=(l-120)/l*n*.9;s*=u,c*=u;let d=i.get(e)??1,f=d/(d+(i.get(a)??1));o.vx-=s*f,o.vy-=c*f,t.vx+=s*(1-f),t.vy+=c*(1-f)}for(let t of e)t.pinned?(t.vx=0,t.vy=0):(t.vx-=t.x*b*n,t.vy-=t.y*b*n,t.vx*=x,t.vy*=x,t.x+=t.vx,t.y+=t.vy)}function A(e,t,n=300){let r=1;for(let i=0;i<n&&r>.012;i++)k(e,t,r),r*=.9772}function j(e,t=30,n=60){if(e.length===0)return{x:0,y:0,width:0,height:0};let[r,i,a,o]=[1/0,1/0,-1/0,-1/0];for(let s of e)r=Math.min(r,s.x-Math.max(s.r,n)),a=Math.max(a,s.x+Math.max(s.r,n)),i=Math.min(i,s.y-s.r),o=Math.max(o,s.y+s.r+t);return{x:r,y:i,width:a-r,height:o-i}}function M(e,t,n){let r=Math.hypot(t.x-e.x,t.y-e.y)||1,[i,a]=[(t.x-e.x)/r,(t.y-e.y)/r],o=t.r+(n?3:0);return{x1:e.x+i*e.r,y1:e.y+a*e.r,x2:t.x-i*o,y2:t.y-a*o}}function N(e,t,n){return`M${e-n*.6},${t-n*.8} C${e-n*4},${t-n*5} ${e+n*4},${t-n*5} ${e+n*.6},${t-n*.8}`}export{N as a,k as c,h as d,u as f,j as i,v as l,m,w as n,D as o,f as p,M as r,A as s,T as t,_ as u};
@@ -0,0 +1 @@
1
+ import{at as e,ct as t,o as n,ot as r,rt as i}from"./route-DO6IZ7of.js";import{t as a,z as o}from"./button-ClA70PLR.js";import{l as s}from"./zone-D9dXk8tn.js";import{a as c,i as l,n as u,o as d,r as f,t as p}from"./table-DfMz2f8M.js";var m={name:`chart-column`,size:24,node:[[`path`,{d:`M3 3v16a2 2 0 0 0 2 2h16`,key:`c24i48`}],[`path`,{d:`M18 17V9`,key:`2bz60n`}],[`path`,{d:`M13 17V5`,key:`1frdt8`}],[`path`,{d:`M8 17v-3`,key:`17ska0`}]],aliases:[`bar-chart-3`]};m.node;var h=e(m),g={name:`image-down`,size:24,node:[[`path`,{d:`M10.3 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10l-3.1-3.1a2 2 0 0 0-2.814.014L6 21`,key:`9csbqa`}],[`path`,{d:`m14 19 3 3v-5.5`,key:`9ldu5r`}],[`path`,{d:`m17 22 3-3`,key:`1nkfve`}],[`circle`,{cx:`9`,cy:`9`,r:`2`,key:`af1f0g`}]]};g.node;var _=e(g),v={name:`waypoints`,size:24,node:[[`path`,{d:`m10.586 5.414-5.172 5.172`,key:`4mc350`}],[`path`,{d:`m18.586 13.414-5.172 5.172`,key:`8c96vv`}],[`path`,{d:`M6 12h12`,key:`8npq4p`}],[`circle`,{cx:`12`,cy:`20`,r:`2`,key:`144qzu`}],[`circle`,{cx:`12`,cy:`4`,r:`2`,key:`muu5ef`}],[`circle`,{cx:`20`,cy:`12`,r:`2`,key:`1xzzfp`}],[`circle`,{cx:`4`,cy:`12`,r:`2`,key:`1hvhnz`}]]};v.node;var y=e(v),b=t(r(),1),x=/^(smallint|integer|bigint|numeric|decimal|real|double precision|oid|money)/,S=/^(date|timestamp|time)/,C=e=>x.test(e),w=e=>S.test(e);function T(e){if(e===null||e.trim()===``)return;let t=Number(e.replace(/^\$/,``).replaceAll(`,`,``));return Number.isFinite(t)?t:void 0}function E(e){if(e===null)return;let t=e.replace(/(\d:\d\d(?::\d\d(?:\.\d+)?)?)([+-]\d\d)$/,`$1$2:00`),n=Date.parse(/^\d{4}-\d\d-\d\d \d/.test(t)?t.replace(` `,`T`):t);return Number.isFinite(n)?n:void 0}function D(e,t){return w(t)?E(e):T(e)}var O=[`count`,`sum`,`avg`,`min`,`max`];function k({column:e,aggregate:t}){return t===`count`&&!e?`count`:`${t}(${e})`}function A(e,t,n){let r=t=>{let n=e.columns.findIndex(e=>e.name===t);if(n<0)throw Error(`no column "${t}"`);return n},i=t.map(r),a=new Map;for(let t of e.rows){let e=i.map(e=>t[e]??null),n=JSON.stringify(e),r=a.get(n);r?r.rows.push(t):a.set(n,{key:e,rows:[t]})}return{columns:[...t.map((t,n)=>({name:t,type:e.columns[i[n]].type})),...n.map(e=>({name:k(e),type:`double precision`}))],rows:[...a.values()].map(({key:e,rows:t})=>[...e,...n.map(({column:e,aggregate:n})=>{if(n===`count`&&!e)return String(t.length);let i=r(e),a=t.flatMap(e=>T(e[i]??null)??[]);return n===`count`?String(t.filter(e=>e[i]!==null).length):a.length===0?null:String(n===`sum`?a.reduce((e,t)=>e+t,0):n===`avg`?a.reduce((e,t)=>e+t,0)/a.length:n===`min`?Math.min(...a):Math.max(...a))})])}}function j(e){return e.columns.map((t,n)=>{let r=e.rows.map(e=>e[n]??null),i=r.filter(e=>e!==null),a={name:t.name,type:t.type,count:r.length,nulls:r.length-i.length,distinct:new Set(i).size,min:null,max:null};if(C(t.type)){let e=i.flatMap(e=>T(e)??[]).sort((e,t)=>e-t);if(e.length>0){let t=e.reduce((e,t)=>e+t,0),n=t/e.length,r=Math.floor(e.length/2);a.min=String(e[0]),a.max=String(e[e.length-1]),a.sum=t,a.mean=n,a.median=e.length%2?e[r]:(e[r-1]+e[r])/2,a.stddev=Math.sqrt(e.reduce((e,t)=>e+(t-n)**2,0)/e.length)}}else if(i.length>0){let e=[...i].sort();a.min=e[0],a.max=e[e.length-1]}return a})}var M=[{id:`bar`,label:`Bar`},{id:`line`,label:`Line`},{id:`area`,label:`Area`},{id:`scatter`,label:`Scatter`},{id:`radar`,label:`Radar (spider web)`},{id:`pie`,label:`Pie`},{id:`donut`,label:`Donut`}],N=e=>e===`radar`||e===`pie`||e===`donut`,ee=[`none`,`hour`,`day`,`week`,`month`,`year`],P=864e5;function F(e,t){let n=new Date(e),r=n.getUTCFullYear(),i=n.getUTCMonth(),a;switch(t){case`hour`:a=Math.floor(e/36e5)*36e5;break;case`day`:a=Math.floor(e/P)*P;break;case`week`:{let t=Math.floor(e/P)*P;a=t-(new Date(t).getUTCDay()+6)%7*P;break}case`month`:a=Date.UTC(r,i,1);break;case`year`:a=Date.UTC(r,0,1)}let o=new Date(a).toISOString(),s=t===`hour`?o.slice(0,13).replace(`T`,` `)+`:00`:t===`month`?o.slice(0,7):t===`year`?o.slice(0,4):o.slice(0,10);return{start:a,label:s}}function te(e,t,n,r,i={}){let a=t=>{let n=e.columns.findIndex(e=>e.name===t);if(n<0)throw Error(`no column "${t}"`);return n},o=a(n),s=e.columns[o].type,c=C(s)||w(s),l=i.bucket&&i.bucket!==`none`&&w(s)?i.bucket:void 0,u=(t===`line`||t===`area`||t===`scatter`)&&c&&!l;if(t===`scatter`&&!c)throw Error(`a scatter chart needs a number or time for x`);let d=i.group&&r.length>0?a(i.group):-1,f=[],p=0;if(d>=0){let t=a(r[0]),n=new Set;for(let t of e.rows)n.add(t[d]??null);for(let e of n)f.length>=8?p++:f.push({name:e??`NULL`,at:t,group:e})}else for(let e of r)f.push({name:e,at:a(e)});let m=0,h=new Map,g=f.map(()=>new Map),_=f.map(()=>[]);if(f.forEach((t,n)=>{for(let r of e.rows){if(t.group!==void 0&&(r[d]??null)!==t.group)continue;let e=T(r[t.at]??null),i=r[o]??null;if(e===void 0){m++;continue}if(u){let t=D(i,s);if(t===void 0){m++;continue}_[n].push({x:t,y:e,label:i??``});continue}let a=i??`NULL`,c=h.size;if(l){let e=E(i);if(e===void 0){m++;continue}let t=F(e,l);a=t.label,c=t.start}if(!h.has(a)){if(h.size>=60){p++;continue}h.set(a,c)}g[n].set(a,(g[n].get(a)??0)+e)}}),u)return{kind:t,series:f.map((e,t)=>({name:e.name,points:_[t].sort((e,t)=>e.x-t.x)})),xIsTime:w(s),skipped:m,clipped:p};let v=[...h.keys()];return l&&v.sort((e,t)=>h.get(e)-h.get(t)),{kind:t,series:f.map((e,t)=>({name:e.name,points:v.flatMap((e,n)=>g[t].has(e)?[{x:n,y:g[t].get(e),label:e}]:[])})),categories:v,xIsTime:!1,skipped:m,clipped:p}}function I(e,t,n=5){if(!(t>e))return[e];let r=(t-e)/Math.max(n,1),i=10**Math.floor(Math.log10(r)),a=[1,2,5,10].map(e=>e*i).find(e=>e>=r),o=[];for(let n=Math.ceil(e/a)*a;n<=t+a*1e-9;n+=a)o.push(Number(n.toPrecision(12)));return o}function L(e){let t=Math.abs(e);return t>=1e9?`${+(e/1e9).toPrecision(3)}B`:t>=1e6?`${+(e/1e6).toPrecision(3)}M`:t>=1e4?`${+(e/1e3).toPrecision(3)}k`:String(Number.isInteger(e)?e:+e.toPrecision(3))}function ne(e,t){let n=new Date(e).toISOString();return t>=1728e5?n.slice(0,10):n.slice(0,16).replace(`T`,` `)}var R=i(),z={colors:[`#0ea5e9`,`#14b8a6`,`#6366f1`,`#f59e0b`,`#f43f5e`],ink:`#111827`,muted:`#6b7280`,paper:`#ffffff`,border:`#e5e7eb`,bodyFont:`ui-sans-serif, system-ui, sans-serif`,headingFont:`ui-sans-serif, system-ui, sans-serif`,radius:10,glow:0};function B(){let e=getComputedStyle(document.documentElement),t=(t,n)=>e.getPropertyValue(t).trim()||n,n=t(`--radius`,`0.625rem`),r=parseFloat(getComputedStyle(document.documentElement).fontSize)||16,i=n.endsWith(`rem`)?parseFloat(n)*r:parseFloat(n);return{colors:[1,2,3,4,5].map(e=>t(`--chart-${e}`,z.colors[e-1])),ink:t(`--foreground`,z.ink),muted:t(`--muted-foreground`,z.muted),paper:t(`--background`,z.paper),border:t(`--border`,z.border),bodyFont:t(`--body-font`,z.bodyFont),headingFont:t(`--heading-font`,z.headingFont),radius:Number.isFinite(i)?i:z.radius,glow:parseFloat(t(`--chart-glow`,`0`))||0}}function re(){let[e,t]=(0,b.useState)(B);return(0,b.useEffect)(()=>{let e=()=>t(B());e();let n=new MutationObserver(e);return n.observe(document.documentElement,{attributes:!0,attributeFilter:[`data-theme`,`class`]}),()=>n.disconnect()},[]),e}function V(e,t){let n=e.colors.length,r=e.colors[t%n],i=Math.floor(t/n);return i===0?r:`color-mix(in oklab, ${r} ${i===1?62:40}%, ${e.ink})`}var H=(e,t)=>e.length>t?`${e.slice(0,t-1)}…`:e;function ie(e,t,n,r,i,a){let o=Math.max(0,Math.min(i,n/2,r));return a?`M${e} ${t+r}V${t+o}Q${e} ${t} ${e+o} ${t}H${e+n-o}Q${e+n} ${t} ${e+n} ${t+o}V${t+r}Z`:`M${e} ${t}V${t+r-o}Q${e} ${t+r} ${e+o} ${t+r}H${e+n-o}Q${e+n} ${t+r} ${e+n} ${t+r-o}V${t}Z`}function ae(e){let t=e.length;if(t===0)return``;if(t<3)return e.map((e,t)=>`${t?`L`:`M`}${e.x.toFixed(1)} ${e.y.toFixed(1)}`).join(``);let n=[],r=[];for(let i=0;i<t-1;i++)n.push(e[i+1].x-e[i].x),r.push(n[i]===0?0:(e[i+1].y-e[i].y)/n[i]);let i=[r[0]];for(let e=1;e<t-1;e++)i.push(r[e-1]*r[e]<=0?0:(r[e-1]+r[e])/2);i.push(r[t-2]);for(let e=0;e<t-1;e++){if(r[e]===0){i[e]=0,i[e+1]=0;continue}let t=i[e]/r[e],n=i[e+1]/r[e],a=t*t+n*n;if(a>9){let o=3/Math.sqrt(a);i[e]=o*t*r[e],i[e+1]=o*n*r[e]}}let a=`M${e[0].x.toFixed(1)} ${e[0].y.toFixed(1)}`;for(let r=0;r<t-1;r++){let t=e[r],o=e[r+1],s=n[r]/3;a+=`C${(t.x+s).toFixed(1)} ${(t.y+i[r]*s).toFixed(1)} ${(o.x-s).toFixed(1)} ${(o.y-i[r+1]*s).toFixed(1)} ${o.x.toFixed(1)} ${o.y.toFixed(1)}`}return a}var U=(e,t,n,r)=>({x:e+n*Math.cos(r),y:t+n*Math.sin(r)});function oe(e,t,n,r,i,a){if(a-i>=Math.PI*2-1e-6){let i=n=>`M${e-n} ${t}a${n} ${n} 0 1 0 ${2*n} 0a${n} ${n} 0 1 0 ${-2*n} 0Z`;return i(n)+(r>0?i(r):``)}let o=+(a-i>Math.PI),s=U(e,t,n,i),c=U(e,t,n,a),l=`M${s.x.toFixed(2)} ${s.y.toFixed(2)}A${n} ${n} 0 ${o} 1 ${c.x.toFixed(2)} ${c.y.toFixed(2)}`;if(r<=0)return`${l}L${e} ${t}Z`;let u=U(e,t,r,a),d=U(e,t,r,i);return`${l}L${u.x.toFixed(2)} ${u.y.toFixed(2)}A${r} ${r} 0 ${o} 0 ${d.x.toFixed(2)} ${d.y.toFixed(2)}Z`}function W({names:e,theme:t,y:n,glow:r}){let i=56;return(0,R.jsx)(`g`,{children:e.map((e,a)=>{let o=i;return i+=30+Math.min(e.length,24)*7,(0,R.jsxs)(`g`,{children:[(0,R.jsx)(`circle`,{cx:o+5,cy:n-4,r:5,fill:V(t,a),filter:r}),(0,R.jsx)(`text`,{x:o+16,y:n,fontSize:11,fill:t.ink,children:H(e,24)})]},e)})})}function G({theme:e,children:t}){return(0,R.jsx)(`text`,{x:360,y:210,fontSize:13,textAnchor:`middle`,fill:e.muted,children:t})}function K({chart:e,theme:t,glow:n,top:r,bottomSpace:i}){let a=e.kind===`donut`,o=e.categories??[],s=e.series[0],c=(s?.points??[]).filter(e=>e.y>0).map(e=>({label:o[e.x]??e.label,value:e.y})).sort((e,t)=>t.value-e.value);if(c.length>12){let e=c.slice(11);c=[...c.slice(0,11),{label:`Other (${e.length})`,value:e.reduce((e,t)=>e+t.value,0)}]}let l=c.reduce((e,t)=>e+t.value,0);if(l<=0)return(0,R.jsx)(G,{theme:t,children:`Nothing to draw: pick a column that holds positive numbers.`});let u=420-r-i,d=Math.min(u/2-4,150),f=56+d+8,p=r+u/2,m=a?d*.62:0,h=f+d+44,g=Math.min(24,u/c.length),_=p-c.length*g/2,v=-Math.PI/2;return(0,R.jsxs)(`g`,{children:[(0,R.jsx)(`g`,{filter:n,children:c.map((e,n)=>{let r=v,i=e.value/l*Math.PI*2;v+=i;let o=r+i/2,s=U(f,p,a?(d+m)/2:d*.66,o);return(0,R.jsxs)(`g`,{children:[(0,R.jsx)(`path`,{d:oe(f,p,d,m,r,r+i),fill:V(t,n),fillRule:`evenodd`,stroke:t.paper,strokeWidth:2,strokeLinejoin:`round`,children:(0,R.jsx)(`title`,{children:`${e.label}: ${e.value} (${(e.value/l*100).toFixed(1)}%)`})}),i>.4&&(0,R.jsxs)(`text`,{x:s.x,y:s.y+4,fontSize:11,fontWeight:600,textAnchor:`middle`,fill:t.paper,children:[Math.round(e.value/l*100),`%`]})]},n)})}),a&&(0,R.jsxs)(`g`,{textAnchor:`middle`,children:[(0,R.jsx)(`text`,{x:f,y:p+4,fontSize:22,fontWeight:600,fontFamily:t.headingFont,fill:t.ink,children:L(l)}),(0,R.jsx)(`text`,{x:f,y:p+22,fontSize:10,letterSpacing:.8,fill:t.muted,children:H(s?.name??`total`,18)})]}),c.map((e,r)=>(0,R.jsxs)(`g`,{children:[(0,R.jsx)(`circle`,{cx:h+5,cy:_+r*g+g/2,r:5,fill:V(t,r),filter:n}),(0,R.jsx)(`text`,{x:h+18,y:_+r*g+g/2+4,fontSize:11,fill:t.ink,children:H(e.label,22)}),(0,R.jsxs)(`text`,{x:696,y:_+r*g+g/2+4,fontSize:11,textAnchor:`end`,fill:t.muted,children:[L(e.value),` ·`,` `,(e.value/l*100).toFixed(+(e.value/l<.1)),`%`]})]},r))]})}function se({chart:e,theme:t,glow:n,top:r,bottomSpace:i}){let a=e.categories??[],o=a.length,s=e.series.map(e=>{let t=new Map(e.points.map(e=>[e.x,Math.max(e.y,0)]));return a.map((e,n)=>t.get(n)??0)}),c=Math.max(0,...s.flat());if(o<3||c<=0)return(0,R.jsx)(G,{theme:t,children:o<3?`A radar chart needs at least three categories.`:`Nothing to draw: pick columns that hold positive numbers.`});let l=I(0,c,4).filter(e=>e>0),u=l[l.length-1],d=420-r-i,f=Math.min(d/2-26,260),p=r+d/2,m=e=>-Math.PI/2+e/o*Math.PI*2,h=e=>a.map((t,n)=>{let r=U(360,p,f*e,m(n));return`${n?`L`:`M`}${r.x.toFixed(1)} ${r.y.toFixed(1)}`}).join(``)+`Z`;return(0,R.jsxs)(`g`,{children:[l.map(e=>(0,R.jsx)(`path`,{d:h(e/u),fill:`none`,stroke:t.muted,strokeOpacity:.28,strokeLinejoin:`round`},e)),a.map((e,n)=>{let r=U(360,p,f,m(n)),i=U(360,p,f+20,m(n)),a=Math.cos(m(n));return(0,R.jsxs)(`g`,{children:[(0,R.jsx)(`line`,{x1:360,y1:p,x2:r.x,y2:r.y,stroke:t.muted,strokeOpacity:.2}),(0,R.jsx)(`text`,{x:i.x,y:i.y+(Math.sin(m(n))>.5?8:Math.sin(m(n))<-.5?-4:4),fontSize:11,textAnchor:a>.3?`start`:a<-.3?`end`:`middle`,fill:t.ink,children:H(e,14)})]},n)}),l.map(e=>(0,R.jsx)(`text`,{x:364,y:p-e/u*f-3,fontSize:9,fill:t.muted,children:L(e)},e)),e.series.map((r,i)=>{let o=V(t,i),c=s[i].map((e,t)=>U(360,p,f*e/u,m(t))),l=c.map((e,t)=>`${t?`L`:`M`}${e.x.toFixed(1)} ${e.y.toFixed(1)}`).join(``)+`Z`;return(0,R.jsxs)(`g`,{filter:n,children:[(0,R.jsx)(`path`,{d:l,fill:o,fillOpacity:.2,stroke:o,strokeWidth:2.5,strokeLinejoin:`round`}),c.map((n,c)=>(0,R.jsx)(`circle`,{cx:n.x,cy:n.y,r:3.5,fill:t.paper,stroke:o,strokeWidth:2,children:(0,R.jsx)(`title`,{children:`${a[c]}: ${s[i][c]}${e.series.length>1?` (${r.name})`:``}`})},c))]},r.name)})]})}function ce({chart:e,text:t,theme:n,uid:r,glow:i,top:a,bottomSpace:o}){let{series:s,categories:c,kind:l}=e,u=s.length>1,d=!!c&&c.length>8,f=d?56:28,p=f+(t.xLabel?22:0)+o,m=420-a-p,h=Math.min(Math.max(n.radius*.6,0),8),g=s.flatMap(e=>e.points),_=g.map(e=>e.x),v=g.map(e=>e.y),y=g.length===0,b=y?0:Math.min(...v),x=y?1:Math.max(...v);(l===`bar`||l===`area`)&&(b=Math.min(b,0),x=Math.max(x,0)),x===b&&(x=b+1);let S=I(b,x,5),C=Math.min(b,S[0]),w=Math.max(x,S[S.length-1]),T=e=>a+m-(e-C)/(w-C)*m,E,D,O=c?.length??0;if(c){let e=640/Math.max(O,1);E=t=>56+e*(t+.5);let t=Math.max(1,Math.ceil(O/Math.max(Math.floor(640/(d?18:70)),1)));D=c.flatMap((e,n)=>n%t===0?[{at:E(n),label:H(e,d?16:10)}]:[])}else{let t=y?0:Math.min(..._),n=y?1:Math.max(..._);n===t&&(--t,n+=1),E=e=>56+(e-t)/(n-t)*640,D=e.xIsTime?[0,1,2,3,4].map(e=>{let r=t+(n-t)*e/4;return{at:E(r),label:ne(r,n-t)}}):I(t,n,6).map(e=>({at:E(e),label:L(e)}))}let k=c?640/Math.max(O,1):0,A=c?Math.min(k*.72/s.length,44):0,j=a+m,M=l===`bar`||l===`area`?T(0):j,N=j+(d?14:20);return(0,R.jsxs)(`g`,{children:[(0,R.jsx)(`defs`,{children:s.map((e,t)=>(0,R.jsxs)(`g`,{children:[(0,R.jsxs)(`linearGradient`,{id:`${r}bar${t}`,x1:`0`,y1:`0`,x2:`0`,y2:`1`,children:[(0,R.jsx)(`stop`,{offset:`0`,stopColor:V(n,t),stopOpacity:1}),(0,R.jsx)(`stop`,{offset:`1`,stopColor:V(n,t),stopOpacity:.45})]}),(0,R.jsxs)(`linearGradient`,{id:`${r}area${t}`,x1:`0`,y1:`0`,x2:`0`,y2:`1`,children:[(0,R.jsx)(`stop`,{offset:`0`,stopColor:V(n,t),stopOpacity:l===`area`?.5:.28}),(0,R.jsx)(`stop`,{offset:`1`,stopColor:V(n,t),stopOpacity:0})]})]},t))}),S.map(e=>(0,R.jsx)(`text`,{x:46,y:T(e)+4,fontSize:11,textAnchor:`end`,fill:n.muted,children:L(e)},e)),(0,R.jsx)(`line`,{x1:56,x2:696,y1:M,y2:M,stroke:n.muted,strokeOpacity:.6}),D.map((e,t)=>(0,R.jsx)(`text`,{x:e.at,y:N,fontSize:11,fill:n.muted,textAnchor:d||e.at>690?`end`:`middle`,transform:d?`rotate(-40 ${e.at} ${N})`:void 0,children:e.label},t)),t.yLabel&&(0,R.jsx)(`text`,{transform:`translate(16 ${a+m/2}) rotate(-90)`,fontSize:11,letterSpacing:.6,textAnchor:`middle`,fill:n.muted,children:t.yLabel}),y&&(0,R.jsx)(`text`,{x:376,y:a+m/2,fontSize:13,textAnchor:`middle`,fill:n.muted,children:`Nothing to draw: pick columns that hold numbers.`}),s.map((e,t)=>{let a=V(n,t);if(l===`bar`)return(0,R.jsx)(`g`,{filter:i,children:e.points.map((n,i)=>{let o=Math.max(A-3,2),c=E(n.x)-A*s.length/2+A*t+1.5,l=Math.min(T(n.y),T(0)),d=Math.max(Math.abs(T(n.y)-T(0)),1);return(0,R.jsx)(`path`,{d:ie(c,l,o,d,h,n.y>=0),fill:`url(#${r}bar${t})`,stroke:a,strokeOpacity:.9,strokeWidth:1,children:(0,R.jsx)(`title`,{children:`${n.label}: ${n.y}${u?` (${e.name})`:``}`})},i)})},e.name);let o=e.points.map(e=>({x:E(e.x),y:T(e.y)})),c=ae(o);return(0,R.jsxs)(`g`,{children:[(l===`line`||l===`area`)&&o.length>1&&(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`path`,{d:`${c}L${o[o.length-1].x.toFixed(1)} ${M}L${o[0].x.toFixed(1)} ${M}Z`,fill:`url(#${r}area${t})`}),(0,R.jsx)(`path`,{d:c,fill:`none`,stroke:a,strokeWidth:2.5,strokeLinejoin:`round`,strokeLinecap:`round`,filter:i})]}),(l===`scatter`||l===`line`&&e.points.length<=60||l===`area`&&e.points.length<=24)&&(0,R.jsx)(`g`,{filter:i,children:e.points.map((t,r)=>(0,R.jsx)(`circle`,{cx:o[r].x,cy:o[r].y,r:l===`scatter`?5:3.5,fill:l===`scatter`?a:n.paper,fillOpacity:l===`scatter`?.8:1,stroke:a,strokeWidth:l===`scatter`?1.5:2,children:(0,R.jsx)(`title`,{children:`${t.label}: ${t.y}${u?` (${e.name})`:``}`})},r))})]},e.name)}),t.xLabel&&(0,R.jsx)(`text`,{x:376,y:j+f+14,fontSize:11,letterSpacing:.6,textAnchor:`middle`,fill:n.muted,children:t.xLabel})]})}var le=(0,b.forwardRef)(function({chart:e,text:t},n){let r=re(),i=(0,b.useId)().replace(/[^a-zA-Z0-9]/g,``),{kind:a,series:o}=e,s=o.length>1&&a!==`pie`&&a!==`donut`,c=t.title?56:28,l=(s?26:0)+(t.caption?26:0)+8,u=Math.min(r.radius,18),d=r.glow>0?`url(#${i}glow)`:void 0,f={chart:e,text:t,theme:r,uid:i,glow:d,top:c,bottomSpace:l};return(0,R.jsxs)(`svg`,{ref:n,xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 720 420`,width:720,height:420,role:`img`,"aria-label":t.title||`Chart`,fontFamily:r.bodyFont,style:{maxWidth:`100%`,height:`auto`,display:`block`,position:`relative`,zIndex:51},children:[(0,R.jsx)(`defs`,{children:r.glow>0&&(0,R.jsxs)(`filter`,{id:`${i}glow`,x:`-20%`,y:`-20%`,width:`140%`,height:`140%`,children:[(0,R.jsx)(`feGaussianBlur`,{in:`SourceGraphic`,stdDeviation:r.glow/2,result:`blur`}),(0,R.jsxs)(`feMerge`,{children:[(0,R.jsx)(`feMergeNode`,{in:`blur`}),(0,R.jsx)(`feMergeNode`,{in:`SourceGraphic`})]})]})}),(0,R.jsx)(`rect`,{x:.5,y:.5,width:719,height:419,rx:u,fill:r.paper,stroke:r.border,strokeOpacity:.55}),t.title&&(0,R.jsx)(`text`,{x:56,y:34,fontSize:18,fontFamily:r.headingFont,fontWeight:600,fill:r.ink,letterSpacing:.3,children:H(t.title,70)}),a===`pie`||a===`donut`?(0,R.jsx)(K,{...f}):a===`radar`?(0,R.jsx)(se,{...f}):(0,R.jsx)(ce,{...f}),s&&(0,R.jsx)(W,{names:o.map(e=>e.name),theme:r,y:406-(t.caption?24:0),glow:d}),t.caption&&(0,R.jsx)(`text`,{x:56,y:406,fontSize:11,fontStyle:`italic`,fill:r.muted,children:H(t.caption,110)})]})}),ue=`http://www.w3.org/2000/svg`;function q(e){let t=e.cloneNode(!0);return t.setAttribute(`xmlns`,ue),t.removeAttribute(`style`),`<?xml version="1.0" encoding="UTF-8"?>\n${new XMLSerializer().serializeToString(t)}\n`}function de(e,t=2){return J(q(e),e.viewBox.baseVal.width,e.viewBox.baseVal.height,t)}function J(e,t,n,r=2){let i=URL.createObjectURL(new Blob([e],{type:`image/svg+xml;charset=utf-8`}));return new Promise((e,a)=>{let o=new Image;o.onload=()=>{let s=document.createElement(`canvas`);s.width=t*r,s.height=n*r;let c=s.getContext(`2d`);c?(c.drawImage(o,0,0,s.width,s.height),URL.revokeObjectURL(i),s.toBlob(t=>t?e(t):a(Error(`The image could not be made`)),`image/png`)):a(Error(`This browser cannot draw the image`))},o.onerror=()=>{URL.revokeObjectURL(i),a(Error(`The chart could not be turned into an image`))},o.src=i})}function Y(e,t){let n=URL.createObjectURL(e),r=document.createElement(`a`);r.href=n,r.download=t,document.body.append(r),r.click(),r.remove(),URL.revokeObjectURL(n)}var X=(e,t)=>e.trim().toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-|-$/g,``).slice(0,60)||t,Z=`border-input bg-background rounded-lg border px-2 py-1 text-sm`;function Q({label:e,children:t}){return(0,R.jsxs)(`label`,{className:`flex flex-col gap-1 text-xs`,children:[(0,R.jsx)(`span`,{className:`text-muted-foreground`,children:e}),t]})}function fe({data:e,filename:t}){let n=e.columns.filter(e=>C(e.type)),[r,i]=(0,b.useState)(()=>e.columns[0]&&w(e.columns[0].type)?`line`:`bar`),[c,l]=(0,b.useState)(e.columns[0]?.name??``),[u,d]=(0,b.useState)(``),[f,p]=(0,b.useState)(`none`),[m,h]=(0,b.useState)(()=>{let t=n.find(t=>t.name!==e.columns[0]?.name)??n[0];return t?[t.name]:[]}),[g,v]=(0,b.useState)({title:``,caption:``,xLabel:``,yLabel:``}),[y,x]=(0,b.useState)(),[S,T]=(0,b.useState)(),E=(0,b.useRef)(null),D=e.columns.find(e=>e.name===c)?.type??``,O=(0,b.useMemo)(()=>{try{let t=u&&u!==c&&!m.includes(u)&&r!==`pie`&&r!==`donut`;return{chart:te(e,r,c,m,{group:t?u:void 0,bucket:f})}}catch(e){return{error:e instanceof Error?e.message:String(e)}}},[e,r,c,m,u,f]),k=e=>v({...g,...e}),A=e=>h(m.includes(e)?m.filter(t=>t!==e):[...m,e].slice(-5)),j=async e=>{if(E.current){x(void 0);try{let n=`${X(g.title,t)}.${e}`;Y(e===`svg`?new Blob([q(E.current)],{type:`image/svg+xml`}):await de(E.current),n),T(e),window.setTimeout(()=>T(void 0),1500)}catch(e){x(e instanceof Error?e.message:String(e))}}};return(0,R.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,R.jsxs)(`div`,{className:`flex flex-wrap items-end gap-3`,children:[(0,R.jsx)(Q,{label:`Chart`,children:(0,R.jsx)(`select`,{"aria-label":`Chart type`,value:r,onChange:e=>i(e.target.value),className:Z,children:M.map(e=>(0,R.jsx)(`option`,{value:e.id,children:e.label},e.id))})}),(0,R.jsx)(Q,{label:`X axis`,children:(0,R.jsx)(`select`,{"aria-label":`X column`,value:c,onChange:e=>l(e.target.value),className:Z,children:e.columns.map(e=>(0,R.jsx)(`option`,{children:e.name},e.name))})}),w(D)&&r!==`scatter`&&(0,R.jsx)(Q,{label:`Group times by`,children:(0,R.jsx)(`select`,{"aria-label":`Time step`,value:f,onChange:e=>p(e.target.value),className:Z,children:ee.map(e=>(0,R.jsx)(`option`,{value:e,children:e===`none`?`as they are`:e},e))})}),r!==`pie`&&r!==`donut`&&(0,R.jsx)(Q,{label:`Colour by group`,children:(0,R.jsxs)(`select`,{"aria-label":`Group column`,value:u,onChange:e=>d(e.target.value),className:Z,children:[(0,R.jsx)(`option`,{value:``,children:`no groups`}),e.columns.filter(e=>e.name!==c).map(e=>(0,R.jsx)(`option`,{children:e.name},e.name))]})}),(0,R.jsxs)(`fieldset`,{className:`flex flex-col gap-1 text-xs`,children:[(0,R.jsx)(`legend`,{className:`text-muted-foreground mb-1`,children:r===`pie`||r===`donut`||u?`Y axis (first number is used)`:`Y axis (numbers)`}),(0,R.jsxs)(`div`,{className:`flex flex-wrap gap-x-3 gap-y-1`,children:[n.length===0&&(0,R.jsx)(`span`,{className:`text-muted-foreground`,children:`no numeric columns`}),n.map(e=>(0,R.jsxs)(`label`,{className:`flex items-center gap-1 text-sm`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:m.includes(e.name),onChange:()=>A(e.name)}),e.name]},e.name))]})]})]}),(0,R.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,R.jsx)(Q,{label:`Title`,children:(0,R.jsx)(`input`,{"aria-label":`Chart title`,value:g.title,onChange:e=>k({title:e.target.value}),className:Z})}),(0,R.jsx)(Q,{label:`Caption`,children:(0,R.jsx)(`input`,{"aria-label":`Chart caption`,value:g.caption,onChange:e=>k({caption:e.target.value}),placeholder:`Source, date, notes`,className:Z})}),!N(r)&&(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(Q,{label:`X axis label`,children:(0,R.jsx)(`input`,{"aria-label":`X axis label`,value:g.xLabel,onChange:e=>k({xLabel:e.target.value}),placeholder:c,className:Z})}),(0,R.jsx)(Q,{label:`Y axis label`,children:(0,R.jsx)(`input`,{"aria-label":`Y axis label`,value:g.yLabel,onChange:e=>k({yLabel:e.target.value}),placeholder:m.join(`, `),className:Z})})]})]}),O.error?(0,R.jsx)(`p`,{className:`text-destructive text-sm`,children:O.error}):(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`div`,{className:`max-w-full overflow-x-auto`,children:(0,R.jsx)(le,{ref:E,chart:O.chart,text:g})}),(O.chart.skipped>0||O.chart.clipped>0)&&(0,R.jsxs)(`p`,{className:`text-muted-foreground text-xs`,role:`status`,children:[O.chart.skipped>0&&`${O.chart.skipped.toLocaleString()} values left out because they are not numbers. `,O.chart.clipped>0&&`Only the first categories are drawn; group the result to see fewer.`]})]}),(0,R.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,R.jsxs)(a,{variant:`outline`,size:`sm`,disabled:!!O.error,onClick:()=>j(`png`),children:[S===`png`?(0,R.jsx)(o,{}):(0,R.jsx)(_,{}),` Save PNG`]}),(0,R.jsxs)(a,{variant:`outline`,size:`sm`,disabled:!!O.error,onClick:()=>j(`svg`),children:[S===`svg`?(0,R.jsx)(o,{}):(0,R.jsx)(s,{}),` Save SVG`]}),y&&(0,R.jsx)(`span`,{role:`status`,className:`text-destructive text-xs`,children:y})]})]})}function pe({data:e,onGrouped:t}){let[n,r]=(0,b.useState)([]),[i,o]=(0,b.useState)(``),[s,m]=(0,b.useState)(`count`),h=e.columns.filter(e=>C(e.type)),g={column:s===`count`?``:i||h[0]?.name||``,aggregate:s},_=(0,b.useMemo)(()=>{try{return A(e,n,[g])}catch{return}},[e,n,s,i]),v=s!==`count`&&!g.column;return(0,R.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,R.jsxs)(`div`,{className:`flex flex-wrap items-end gap-3`,children:[(0,R.jsxs)(`fieldset`,{className:`flex flex-col gap-1 text-xs`,children:[(0,R.jsx)(`legend`,{className:`text-muted-foreground mb-1`,children:`Group by`}),(0,R.jsx)(`div`,{className:`flex flex-wrap gap-x-3 gap-y-1`,children:e.columns.map(e=>(0,R.jsxs)(`label`,{className:`flex items-center gap-1 text-sm`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:n.includes(e.name),onChange:()=>r(n.includes(e.name)?n.filter(t=>t!==e.name):[...n,e.name])}),e.name]},e.name))})]}),(0,R.jsx)(Q,{label:`Measure`,children:(0,R.jsx)(`select`,{"aria-label":`Aggregate`,value:s,onChange:e=>m(e.target.value),className:Z,children:O.map(e=>(0,R.jsx)(`option`,{children:e},e))})}),s!==`count`&&(0,R.jsx)(Q,{label:`of`,children:(0,R.jsx)(`select`,{"aria-label":`Aggregate column`,value:g.column,onChange:e=>o(e.target.value),className:Z,children:h.map(e=>(0,R.jsx)(`option`,{children:e.name},e.name))})}),(0,R.jsx)(a,{size:`sm`,disabled:v||!_,onClick:()=>t(_),children:`Use for the chart`}),(0,R.jsx)(a,{variant:`outline`,size:`sm`,onClick:()=>t(void 0),children:`Chart the result`})]}),v?(0,R.jsxs)(`p`,{className:`text-muted-foreground text-sm`,children:[`There is no numeric column to `,s,`.`]}):_&&(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`p`,{className:`text-muted-foreground text-xs`,children:[_.rows.length.toLocaleString(),` groups: `,k(g),n.length>0&&` by ${n.join(`, `)}`]}),(0,R.jsx)(`div`,{className:`max-h-72 overflow-auto`,children:(0,R.jsxs)(p,{children:[(0,R.jsx)(c,{children:(0,R.jsx)(d,{children:_.columns.map(e=>(0,R.jsx)(l,{children:e.name},e.name))})}),(0,R.jsx)(u,{children:_.rows.slice(0,200).map((e,t)=>(0,R.jsx)(d,{children:e.map((e,t)=>(0,R.jsx)(f,{children:e===null?(0,R.jsx)(`span`,{className:`text-muted-foreground italic`,children:`NULL`}):e},t))},t))})]})})]})]})}function me({data:e}){let t=(0,b.useMemo)(()=>j(e),[e]),n=e=>e===void 0?``:L(e);return(0,R.jsx)(`div`,{className:`overflow-x-auto`,children:(0,R.jsxs)(p,{children:[(0,R.jsx)(c,{children:(0,R.jsx)(d,{children:[`column`,`rows`,`nulls`,`distinct`,`min`,`max`,`mean`,`median`,`sum`,`std dev`].map(e=>(0,R.jsx)(l,{children:e},e))})}),(0,R.jsx)(u,{children:t.map(e=>(0,R.jsxs)(d,{children:[(0,R.jsx)(f,{title:e.type,children:e.name}),(0,R.jsx)(f,{children:e.count.toLocaleString()}),(0,R.jsx)(f,{children:e.nulls.toLocaleString()}),(0,R.jsx)(f,{children:e.distinct.toLocaleString()}),(0,R.jsx)(f,{children:(0,R.jsx)(`span`,{className:`block max-w-40 truncate`,title:e.min??``,children:e.min??``})}),(0,R.jsx)(f,{children:(0,R.jsx)(`span`,{className:`block max-w-40 truncate`,title:e.max??``,children:e.max??``})}),(0,R.jsx)(f,{children:n(e.mean)}),(0,R.jsx)(f,{children:n(e.median)}),(0,R.jsx)(f,{children:n(e.sum)}),(0,R.jsx)(f,{children:n(e.stddev)})]},e.name))})]})})}function he({data:e,fetchAll:t,filename:n}){let[r,i]=(0,b.useState)(!1),[a,o]=(0,b.useState)(`chart`),[s,c]=(0,b.useState)(),[l,u]=(0,b.useState)(!1),[d,f]=(0,b.useState)(!1),[p,m]=(0,b.useState)(),[g,_]=(0,b.useState)(),v=l&&s?s:e,y=async e=>{if(m(void 0),_(void 0),e&&!s){f(!0);try{c(await t())}catch(e){m(e instanceof Error?e.message:String(e)),f(!1);return}f(!1)}u(e)};return e.columns.length>0&&e.rows.length>0?(0,R.jsxs)(`section`,{className:`mb-3`,"aria-label":`Analyze the result`,children:[(0,R.jsxs)(`button`,{type:`button`,onClick:()=>i(!r),"aria-expanded":r,className:`text-muted-foreground hover:text-foreground flex items-center gap-1 text-xs`,children:[(0,R.jsx)(h,{className:`size-4`}),` `,r?`Hide`:`Chart and analyze`]}),r&&(0,R.jsxs)(`div`,{className:`border-input bg-card mt-2 flex flex-col gap-3 border p-3`,children:[(0,R.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3 text-xs`,children:[(0,R.jsx)(`div`,{role:`tablist`,className:`flex gap-1`,children:[[`chart`,`Chart`],[`group`,`Group by`],[`stats`,`Column stats`]].map(([e,t])=>(0,R.jsx)(`button`,{type:`button`,role:`tab`,"aria-selected":a===e,onClick:()=>o(e),className:`rounded-lg px-2.5 py-1 text-sm ${a===e?`bg-secondary text-secondary-foreground`:`text-muted-foreground hover:text-foreground`}`,children:t},e))}),(0,R.jsx)(`span`,{className:`text-muted-foreground ml-auto`,children:`Rows`}),(0,R.jsxs)(`select`,{"aria-label":`Rows to analyze`,value:l?`all`:`page`,disabled:d,onChange:e=>void y(e.target.value===`all`),className:Z,children:[(0,R.jsxs)(`option`,{value:`page`,children:[`this page (`,e.rows.length.toLocaleString(),`)`]}),(0,R.jsxs)(`option`,{value:`all`,children:[`all rows`,s?` (${s.rows.length.toLocaleString()}${s.truncated?`+`:``})`:``]})]}),d&&(0,R.jsx)(`span`,{role:`status`,children:`Reading...`})]}),p&&(0,R.jsx)(`p`,{className:`text-destructive text-sm`,children:p}),a===`chart`&&(0,R.jsxs)(R.Fragment,{children:[g&&(0,R.jsxs)(`p`,{className:`text-muted-foreground text-xs`,children:[`Charting the grouping (`,g.columns.map(e=>e.name).join(`, `),`).`]}),(0,R.jsx)(fe,{data:g??v,filename:n},`${l}-${g?g.columns.map(e=>e.name).join(`|`):`rows`}-${v.rows.length}`)]}),a===`group`&&(0,R.jsx)(pe,{data:v,onGrouped:e=>{_(e),o(`chart`)}}),a===`stats`&&(0,R.jsx)(me,{data:v})]})]}):null}function ge(e,t){let n=e.filter(e=>e.primaryKey);return(n.length>0?n:e.filter(e=>e.type!==`json`&&e.type!==`xml`)).map(({name:e})=>{let n=t[e];return n==null?{column:e,op:`null`}:{column:e,op:`eq`,value:n}})}function $(e,t,r){return n({environment:e,graph:{schema:t.schema,table:t.name,keys:r}})}function _e(e,t,r){return n({environment:e,graph:{schema:t.schema,table:t.name,filters:r}})}function ve(e,t,n){let r=new Set(t.map(e=>e.name)),i=e=>{let t=e.columns.filter(e=>e.primaryKey);return t.length>0&&t.every(e=>r.has(e.name))},a=e.filter((t,n)=>e.findIndex(e=>e.schema===t.schema&&e.name===t.name)===n),o=n.filter(e=>!a.some(t=>t.schema===e.schema&&t.name===e.name));return[...a,...o].filter(i)}function ye(e,t,n){let r=e.columns.filter(e=>e.primaryKey).map(e=>t.findIndex(t=>t.name===e.name)),i=new Set,a=[];for(let e of n){let t=r.map(t=>e[t]??null);if(t.some(e=>e===null))continue;let n=t,o=JSON.stringify(n);i.has(o)||(i.add(o),a.push(n))}return a}export{ge as a,Y as c,h as d,ye as i,J as l,$ as n,he as o,ve as r,X as s,_e as t,y as u};
@@ -0,0 +1,3 @@
1
+ import{$ as e,a as t,at as n,ct as r,o as i,ot as a,rt as o}from"./route-DO6IZ7of.js";import{c as s,l as c,s as l,u}from"./graph-link-OCo_s0zO.js";import{z as d}from"./button-ClA70PLR.js";import{c as f,l as p}from"./zone-D9dXk8tn.js";import{t as m}from"./loader-circle-BK_GMdvN.js";import{a as h,c as g,d as _,f as v,i as ee,l as y,m as b,o as x,p as S,r as C,s as te,t as ne,u as w}from"./graph-force-yBLyErpS.js";import{t as T}from"./sliders-horizontal-Dg51yc-C.js";import{Gt as E,Wt as D,X as O,Y as k,qt as re,tn as A}from"./index-CDcnUacl.js";var j={name:`eye-off`,size:24,node:[[`path`,{d:`M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49`,key:`ct8e1f`}],[`path`,{d:`M14.084 14.158a3 3 0 0 1-4.242-4.242`,key:`151rxh`}],[`path`,{d:`M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143`,key:`13bj9a`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}]]};j.node;var M=n(j),N={name:`layout-grid`,size:24,node:[[`rect`,{width:`7`,height:`7`,x:`3`,y:`3`,rx:`1`,key:`1g98yp`}],[`rect`,{width:`7`,height:`7`,x:`14`,y:`3`,rx:`1`,key:`6d4xhi`}],[`rect`,{width:`7`,height:`7`,x:`14`,y:`14`,rx:`1`,key:`nxv5o0`}],[`rect`,{width:`7`,height:`7`,x:`3`,y:`14`,rx:`1`,key:`1bb6yr`}]]};N.node;var ie=n(N),P={name:`undo-2`,size:24,node:[[`path`,{d:`M9 14 4 9l5-5`,key:`102s5s`}],[`path`,{d:`M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11`,key:`f3b9sd`}]]};P.node;var F=n(P),I=r(a(),1),L=()=>({labels:{},hidden:[],skipped:[],confirmed:[]}),R=e=>`${e.schema}.${e.name}`,z=e=>`psql-explorer-graph:${e}`,B=()=>globalThis.localStorage,V=e=>Array.isArray(e)&&e.every(e=>typeof e==`string`);function ae(e){try{let t=JSON.parse(B().getItem(z(e))??`null`);if(!t||typeof t!=`object`)return L();let n={};for(let[e,r]of Object.entries(t.labels??{}))V(r)&&r.length>0&&(n[e]=r);return{labels:n,hidden:(Array.isArray(t.hidden)?t.hidden:[]).filter(e=>typeof e?.schema==`string`&&typeof e.name==`string`),skipped:V(t.skipped)?t.skipped:[],confirmed:V(t.confirmed)?t.confirmed:[]}}catch{return L()}}function oe(e,t){try{B().setItem(z(e),JSON.stringify(t))}catch{}}var se=e=>JSON.stringify([e.from.schema,e.from.name,e.name]);function ce(e,t){let n=e=>new Set([...e.hidden.map(e=>`t:${R(e)}`),...e.skipped.map(e=>`k:${e}`)]),[r,i]=[n(e),n(t)];return[...r].filter(e=>!i.has(e)).length+[...i].filter(e=>!r.has(e)).length}function H(e,t){if(!t||t.length===0)return e.label;let n=t.filter(t=>t in e.row).map(t=>e.row[t]??`NULL`).join(`, `);return n===``?e.label:n.length>60?`${n.slice(0,59)}…`:n}function le(e,t){let n=(t??[]).filter(t=>t in e.row);return n.length>0&&n.every(t=>e.row[t]===null)}function ue(e,t){let n=new Map;for(let[r,i]of e){if(le(i,t[R(i.table)]))continue;let e=H(i,t[R(i.table)]);n.set(r,e===i.label?i:{...i,label:e})}return n}function de(e,t){let n=new Map;for(let t of e)n.set(t.id,R(t.table));let r=new Map;for(let e of t){let t=n.get(e.from);t&&!e.via&&r.set(t,(r.get(t)??new Set).add(e.constraint))}return new Set([...r].filter(([,e])=>e.size>=2).map(([e])=>e))}var U=o(),W=22,fe=(e,t)=>e.length>t?`${e.slice(0,t-1)}…`:e;function pe(e,t,n){let[r,i]=[n.x-e.x,n.y-e.y];if(r===0&&i===0)return e;let a=Math.min(r===0?1/0:t/2/Math.abs(r),i===0?1/0:W/2/Math.abs(i));return{x:e.x+r*a,y:e.y+i*a}}function me({environment:t,schema:n,start:r,settings:i,counts:a,onToggleTable:o,onToggleKey:s}){let c=D(async()=>{let[r,i]=await Promise.all([e.erd(t,n),e.schemaForeignKeys(t,n)]);return{tables:r,keys:i}},`${t}/${n}`),{frame:l,view:u,setView:d,dragged:f,startDrag:p,zoomBy:m}=w(),h=(0,I.useMemo)(()=>{if(!c.data)return;let e=new Map,t=t=>{let r=R(t);if(e.has(r))return;let i=t.schema===n?t.name:r;e.set(r,{key:r,table:{schema:t.schema,name:t.name},label:i,width:Math.max(72,fe(i,28).length*6.6+30)})};for(let e of c.data.tables)t(e);for(let e of c.data.keys)t(e.from),t(e.to);let r=[...e.values()].map(e=>({id:e.key,r:e.width/2})),i=c.data.keys.filter(e=>R(e.from)!==R(e.to)).map(e=>({source:R(e.from),target:R(e.to)})),a=x(r,i);return te(a,i),{pills:e,at:new Map(a.map(e=>[e.id,{x:e.x,y:e.y}])),keys:c.data.keys}},[c.data,n]),g=(0,I.useCallback)(()=>{let e=l.current?.getBoundingClientRect();if(!h||!e)return;let[t,n,r,i]=[1/0,1/0,-1/0,-1/0];for(let e of h.pills.values()){let a=h.at.get(e.key);t=Math.min(t,a.x-e.width/2),r=Math.max(r,a.x+e.width/2),n=Math.min(n,a.y-W/2-30),i=Math.max(i,a.y+W/2)}if(t===1/0)return;let a={x:t,y:n,width:r-t,height:i-n},o=S(a,e,16);d({k:o.k,x:o.x-a.x*o.k,y:o.y-a.y*o.k})},[h,l,d]);if((0,I.useLayoutEffect)(g,[g]),c.error)return(0,U.jsxs)(`p`,{className:`text-destructive mb-3 text-sm`,children:[`Could not load the schema: `,String(c.error)]});if(!h)return(0,U.jsx)(E,{className:`mb-3 h-48`});let v=new Set(i.hidden.map(R)),ee=new Set(i.skipped),b=new Map,C=e=>{let t=[R(e.from),R(e.to)].sort().join(`|`),n=b.get(t)??0;return b.set(t,n+1),n};return(0,U.jsxs)(`div`,{className:`relative mb-3`,children:[(0,U.jsx)(y,{zoomBy:m,fit:g}),(0,U.jsx)(`div`,{ref:l,onPointerDown:p,className:`border-border h-72 touch-none overflow-hidden border`,children:(0,U.jsxs)(`svg`,{role:`img`,"aria-label":`Schema map`,width:`100%`,height:`100%`,className:`cursor-grab select-none active:cursor-grabbing`,children:[(0,U.jsx)(`defs`,{children:(0,U.jsx)(`marker`,{id:`map-arrow`,viewBox:`0 0 10 10`,refX:9,refY:5,markerWidth:7,markerHeight:7,orient:`auto-start-reverse`,children:(0,U.jsx)(`path`,{d:`M0,0 L10,5 L0,10 z`,className:`fill-accent-text`})})}),(0,U.jsxs)(`g`,{transform:`translate(${u.x},${u.y}) scale(${u.k})`,children:[h.keys.map(e=>{let[t,n]=[h.at.get(R(e.from)),h.at.get(R(e.to))],[r,i]=[h.pills.get(R(e.from)),h.pills.get(R(e.to))];if(!t||!n||!r||!i)return null;let a=se(e),o=ee.has(a),c=`${e.name} (${e.fromColumns.join(`, `)} → ${e.toColumns.join(`, `)}): ${o?`not followed, click to follow`:`followed, click to stop following`}`,l=C(e),u;if(r===i){let[e,n]=[t.x,t.y-W/2];u=`M${e-12},${n} C${e-34-l*12},${n-40-l*10} ${e+34+l*12},${n-40-l*10} ${e+12},${n}`}else{let e={x:(t.x+n.x)/2,y:(t.y+n.y)/2},[a,o]=[n.x-t.x,n.y-t.y],s=Math.hypot(a,o)||1,c=l===0?0:(l%2?1:-1)*Math.ceil(l/2)*26,d={x:e.x-o/s*c,y:e.y+a/s*c},[f,p]=[pe(t,r.width,d),pe(n,i.width+6,d)];u=`M${f.x},${f.y} Q${d.x},${d.y} ${p.x},${p.y}`}return(0,U.jsxs)(`g`,{"data-key":e.name,"data-followed":!o,className:`cursor-pointer`,onClick:()=>!f.current&&s(a),children:[(0,U.jsx)(`path`,{d:u,fill:`none`,className:o?`stroke-muted-foreground`:`stroke-accent-text`,strokeWidth:1.4,strokeDasharray:o?`4 4`:void 0,opacity:o?.45:.85,markerEnd:`url(#map-arrow)`}),(0,U.jsx)(`path`,{d:u,fill:`none`,stroke:`transparent`,strokeWidth:12,children:(0,U.jsx)(`title`,{children:c})})]},a)}),[...h.pills.values()].map(e=>{let t=h.at.get(e.key),n=e.key===R(r),i=v.has(e.key),s=a.get(e.key),c=_(e.key);return(0,U.jsxs)(`g`,{transform:`translate(${t.x},${t.y})`,"data-table":e.key,"data-shown":!i,role:`button`,"aria-label":`${e.key}${i?` (left out)`:``}`,"aria-pressed":!i,className:n?`cursor-default`:`cursor-pointer`,opacity:i?.5:1,onClick:()=>!f.current&&!n&&o(e.table),children:[(0,U.jsx)(`title`,{children:n?`${e.key}: where the graph starts`:i?`${e.key}: left out, click to draw it`:`${e.key}: click to leave it out`}),(0,U.jsx)(`rect`,{x:-e.width/2,y:-11,width:e.width,height:W,rx:W/2,className:`fill-card`,stroke:n?`var(--primary)`:c,strokeWidth:n?2.5:1.5,strokeDasharray:i?`4 3`:void 0}),(0,U.jsx)(`circle`,{cx:-e.width/2+11,r:4,fill:c}),(0,U.jsx)(`text`,{x:6,y:4,textAnchor:`middle`,className:`fill-foreground text-[11px]`,textDecoration:i?`line-through`:void 0,children:fe(e.label,28)}),s!==void 0&&!i&&(0,U.jsx)(`text`,{x:e.width/2,y:-14,textAnchor:`end`,className:`fill-muted-foreground text-[9px]`,children:s})]},e.key)})]})]})})]})}var G=e=>`more:${e.node}|${e.constraint}`,K=24,he=50,q={background:`#ffffff`,card:`#f8fafc`,border:`#cbd5e1`,text:`#0f172a`,muted:`#64748b`,edge:`#2563eb`,start:`#7c3aed`},J=e=>`${e.schema}.${e.name}`,Y=(e,t)=>e.length>t?`${e.slice(0,t-1)}…`:e;function X(e){return e.replace(/[&<>"']/g,e=>`&#${e.charCodeAt(0)};`)}function ge(e,t=!1){let n=0,r=0;for(let t of e.values())n=Math.max(n,t.x+t.width),r=Math.max(r,t.y+t.height);return{width:n+48+(t?he:0),height:r+48}}var Z=e=>e.via?`${e.constraint}`:`${e.constraint} (${e.fromColumns.join(`, `)} → ${e.toColumns.join(`, `)})`;function _e({nodes:e,edges:t,more:n},r){let[i,a,o,s]=[1/0,1/0,-1/0,-1/0];for(let e of r.values())i=Math.min(i,e.x-Math.max(e.r,70)),o=Math.max(o,e.x+Math.max(e.r,70)),a=Math.min(a,e.y-e.r-(t.length>0?e.r*4:0)),s=Math.max(s,e.y+e.r+34);r.size===0&&([i,a,o,s]=[0,0,0,0]);let c=Math.ceil(o-i+48),l=Math.ceil(s-a+48),u=[`<?xml version="1.0" encoding="UTF-8"?>\n<svg xmlns="http://www.w3.org/2000/svg" width="${c}" height="${l}" viewBox="0 0 ${c} ${l}" font-family="system-ui, sans-serif">`,`<defs><marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="${q.edge}"/></marker></defs>`,`<rect width="${c}" height="${l}" fill="${q.background}"/>`,`<g transform="translate(${K-i},${K-a})">`],d=(e,t,n,r,i,a=1)=>`<text x="${e}" y="${t}" font-size="${n}" text-anchor="middle" fill="${r}" opacity="${a}" stroke="${q.background}" stroke-width="3" stroke-linejoin="round" paint-order="stroke">${X(i)}</text>`;for(let e of t){let[t,n]=[r.get(e.from),r.get(e.to)];if(!t||!n)continue;let i=`<title>${X(Z(e))}</title>`;if(e.from===e.to){u.push(`<path d="${h(t.x,t.y,t.r)}" fill="none" stroke="${q.edge}" stroke-width="1.5" opacity="0.6" marker-end="url(#arrow)">${i}</path>`);continue}let a=C(t,n,!e.via);u.push(`<line x1="${a.x1}" y1="${a.y1}" x2="${a.x2}" y2="${a.y2}" stroke="${q.edge}" stroke-width="1.5" opacity="0.6"${e.via?` stroke-dasharray="5 4"`:` marker-end="url(#arrow)"`}>${i}</line>`)}for(let e of n){let t=r.get(G(e)),n=r.get(e.node);if(!t)continue;if(n){let e=C(n,t,!1);u.push(`<line x1="${e.x1}" y1="${e.y1}" x2="${e.x2}" y2="${e.y2}" stroke="${q.muted}" stroke-width="1" stroke-dasharray="3 3" opacity="0.6"/>`)}let i=e.count-e.shown;u.push(`<circle cx="${t.x}" cy="${t.y}" r="${t.r}" fill="none" stroke="${q.muted}" stroke-dasharray="4 3"/>`,d(t.x,t.y+t.r+13,11,q.text,`+${i.toLocaleString(`en-US`)}${e.capped?`+`:``} more in ${e.table.name}`))}for(let t of e){let e=r.get(t.id);e&&u.push(`<circle cx="${e.x}" cy="${e.y}" r="${e.r}" fill="${_(J(t.table))}" stroke="${t.start?q.start:q.background}" stroke-width="${t.start?3:1.5}"/>`,d(e.x,e.y+e.r+13,11,q.text,Y(t.label,24)),d(e.x,e.y+e.r+25,9,q.muted,J(t.table),.8))}return u.push(`</g>`,`</svg>`,``),u.join(`
2
+ `)}function ve(e){if(e.dots)return _e(e,e.dots);let{nodes:t,edges:n,more:r,placed:i}=e,{width:a,height:o}=ge(i,n.some(e=>e.from===e.to)),s=[];s.push(`<?xml version="1.0" encoding="UTF-8"?>\n<svg xmlns="http://www.w3.org/2000/svg" width="${a}" height="${o}" viewBox="0 0 ${a} ${o}" font-family="system-ui, sans-serif">`,`<defs><marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="${q.edge}"/></marker></defs>`,`<rect width="${a}" height="${o}" fill="${q.background}"/>`,`<g transform="translate(${K},${K})">`);for(let e of n){let t=i.get(e.from),n=i.get(e.to);t&&n&&s.push(`<path d="${v(t,n).d}" fill="none" stroke="${q.edge}" stroke-width="1.5" opacity="0.85" marker-end="url(#arrow)"><title>${X(Z(e))}</title></path>`)}for(let e of r){let t=i.get(G(e));if(!t)continue;let n=e.count-e.shown;s.push(`<g transform="translate(${t.x},${t.y})"><rect width="190" height="30" rx="6" fill="none" stroke="${q.muted}" stroke-dasharray="4 3"/><text x="95" y="19" text-anchor="middle" font-size="12" fill="${q.text}">${X(`+${n.toLocaleString(`en-US`)}${e.capped?`+`:``} more in ${e.table.name}`)}</text></g>`)}for(let e of t){let t=i.get(e.id);if(!t)continue;let n=Object.entries(e.key).map(([e,t])=>`${e} = ${t??`null`}`).join(`, `);s.push(`<g transform="translate(${t.x},${t.y})">`,`<rect width="190" height="52" rx="6" fill="${q.card}" stroke="${e.start?q.start:q.border}" stroke-width="${e.start?2.5:1}"/>`,`<path d="M0,6 a6,6 0 0 1 6,-6 h178 a6,6 0 0 1 6,6 v10 h-190 z" fill="${b(J(e.table))}"/>`,`<text x="8" y="12" font-size="10" font-weight="bold" fill="#ffffff">${X(Y(J(e.table),28))}</text>`,`<text x="8" y="31" font-size="12" fill="${q.text}">${X(Y(e.label,26))}</text>`,`<text x="8" y="45" font-size="10" fill="${q.muted}">${X(Y(n,32))}</text>`,`</g>`)}return s.push(`</g>`,`</svg>`,``),s.join(`
3
+ `)}function ye({nodes:e,edges:t}){return JSON.stringify({nodes:e.map(({id:e,table:t,key:n,label:r,row:i,distance:a,start:o})=>({id:e,table:t,key:n,label:r,row:i,distance:a,start:o})),edges:t.map(({id:e,from:t,to:n,constraint:r,fromColumns:i,toColumns:a,via:o})=>({id:e,from:t,to:n,constraint:r,fromColumns:i,toColumns:a,...o?{via:o}:{}}))},null,2)}function be(e){let t=/<svg[^>]*\swidth="(\d+(?:\.\d+)?)"[^>]*\sheight="(\d+(?:\.\d+)?)"/.exec(e);return t?{width:Number(t[1]),height:Number(t[2])}:void 0}var Q=`border-input bg-background rounded-lg border px-2 py-1 text-sm`,$=e=>`${e.schema}.${e.name}`,xe=(e,t)=>e.length>t?`${e.slice(0,t-1)}…`:e,Se=()=>({nodes:new Map,edges:new Map,more:new Map,moreStart:!1,truncated:!1});function Ce(e,t,n){let r=new Map(e.nodes);for(let e of t.nodes)r.has(e.id)||r.set(e.id,e);let i=new Map(e.edges);for(let e of t.edges)i.has(e.id)||i.set(e.id,e);let a=new Map(e.more);n&&a.delete(G(n));for(let e of t.more)a.set(G(e),e);return{nodes:r,edges:i,more:a,moreStart:e.moreStart,truncated:e.truncated||t.truncated}}var we=e=>Object.entries(e.key).map(([e,t])=>t===null?{column:e,op:`null`}:{column:e,op:`eq`,value:t});function Te({environment:e,node:t,onClose:n}){(0,I.useEffect)(()=>{let e=e=>e.key===`Escape`&&n();return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[n]);let r=i({environment:e,object:{kind:`table`,schema:t.table.schema,name:t.table.name},rows:{filters:we(t),sort:[]}});return(0,U.jsxs)(`aside`,{"aria-label":`Row`,className:`bg-background border-border fixed top-14 right-0 bottom-0 z-20 flex w-full max-w-md flex-col border-l shadow-xl`,children:[(0,U.jsxs)(`header`,{className:`border-border flex items-center justify-between gap-3 border-b px-4 py-3`,children:[(0,U.jsx)(`h3`,{className:`text-accent-text truncate`,children:$(t.table)}),(0,U.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,U.jsxs)(`a`,{href:r,className:`text-accent-text flex items-center gap-1 text-sm`,children:[`Open in table `,(0,U.jsx)(f,{className:`size-3`})]}),(0,U.jsx)(`button`,{type:`button`,onClick:n,"aria-label":`Close row`,children:(0,U.jsx)(re,{className:`size-4`})})]})]}),(0,U.jsx)(`dl`,{className:`flex-1 overflow-y-auto p-4 text-sm`,children:Object.entries(t.row).map(([e,t])=>(0,U.jsxs)(`div`,{className:`border-border border-b py-2`,children:[(0,U.jsx)(`dt`,{className:`text-muted-foreground text-xs`,children:e}),(0,U.jsx)(`dd`,{className:`mt-0.5 font-mono break-all whitespace-pre-wrap`,children:t===null?(0,U.jsx)(`span`,{className:`text-muted-foreground italic`,children:`NULL`}):t})]},e))})]})}function Ee({drawing:e,hidden:t,onToggle:n}){let r=new Map;for(let t of e.nodes.values()){let e=$(t.table);r.set(e,(r.get(e)??0)+1)}let i=new Map;for(let t of e.edges.values())i.set(t.constraint,(i.get(t.constraint)??0)+1);let a=e=>`flex items-center gap-1.5 rounded-lg border px-2 py-0.5 text-xs ${e?`text-muted-foreground border-dashed line-through opacity-60`:`border-input`}`;return(0,U.jsxs)(`div`,{"aria-label":`Legend`,className:`mb-3 flex flex-wrap items-center gap-x-6 gap-y-2`,children:[(0,U.jsx)(`ul`,{className:`flex flex-wrap gap-1.5`,"aria-label":`Tables`,children:[...r].sort().map(([e,r])=>(0,U.jsx)(`li`,{children:(0,U.jsxs)(`button`,{type:`button`,"aria-pressed":!t.tables.has(e),onClick:()=>n(`tables`,e),className:a(t.tables.has(e)),title:t.tables.has(e)?`Show these rows`:`Hide these rows`,children:[(0,U.jsx)(`span`,{className:`size-2.5 rounded-full`,style:{background:_(e)}}),e,` `,(0,U.jsx)(`span`,{className:`text-muted-foreground`,children:r})]})},e))}),i.size>0&&(0,U.jsx)(`ul`,{className:`flex flex-wrap gap-1.5`,"aria-label":`Keys`,children:[...i].sort().map(([e,r])=>(0,U.jsx)(`li`,{children:(0,U.jsxs)(`button`,{type:`button`,"aria-pressed":!t.keys.has(e),onClick:()=>n(`keys`,e),className:a(t.keys.has(e)),title:t.keys.has(e)?`Show these links`:`Hide these links`,children:[(0,U.jsx)(`span`,{className:`text-accent-text`,children:`→`}),e,` `,(0,U.jsx)(`span`,{className:`text-muted-foreground`,children:r})]})},e))})]})}function De({environment:t,initial:n,busy:r,onDraw:i}){let a=D(()=>e.schemas(t),t).data,[o,s]=(0,I.useState)(n.schema??``),[c,l]=(0,I.useState)(n.table??``),[u,d]=(0,I.useState)(n.filters??[]),[f,p]=(0,I.useState)(n.depth??1),[m,h]=(0,I.useState)(n.direction??`both`),[g,_]=(0,I.useState)(n.keys??[]),v=o||a?.find(e=>e.tables>0)?.name||``,ee=D(()=>v?e.objects(t,v):Promise.resolve(void 0),`${t}/${v}`).data?.tables.filter(e=>e.kind===`table`||e.kind===`partitioned`)??[],y=D(()=>v&&c?e.relation(t,{kind:`table`,schema:v,name:c}):Promise.resolve(void 0),`${t}/${v}/${c}`),b=y.data?.columns??[],x=(0,I.useRef)(!1),S=(0,I.useCallback)(e=>i({schema:v,table:c,filters:e.filter(O),depth:f,...g.length>0?{keys:g}:{}},m),[i,v,c,f,m,g]);return(0,I.useEffect)(()=>{!x.current&&n.table&&y.data&&(x.current=!0,i({schema:v,table:c,filters:(n.filters??[]).filter(O),depth:f,...g.length>0?{keys:g}:{}},m,n.expanded))},[n.table,y.data]),(0,U.jsxs)(`div`,{className:`mb-4 flex flex-col gap-3`,children:[(0,U.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,U.jsx)(`select`,{"aria-label":`Schema`,value:v,onChange:e=>{s(e.target.value),l(``),_([]),d([])},className:Q,children:a?.map(e=>(0,U.jsx)(`option`,{children:e.name},e.name))}),(0,U.jsxs)(`select`,{"aria-label":`Table`,value:c,onChange:e=>{l(e.target.value),_([]),d([])},className:Q,children:[(0,U.jsx)(`option`,{value:``,children:`pick a table`}),ee.map(e=>(0,U.jsx)(`option`,{children:e.name},e.name))]}),(0,U.jsxs)(`label`,{className:`text-muted-foreground flex items-center gap-1 text-sm`,children:[`depth`,(0,U.jsx)(`select`,{"aria-label":`Depth`,value:f,onChange:e=>p(Number(e.target.value)),className:Q,children:[0,1,2,3].map(e=>(0,U.jsx)(`option`,{children:e},e))})]}),(0,U.jsxs)(`select`,{"aria-label":`Direction`,value:m,onChange:e=>h(e.target.value),className:Q,children:[(0,U.jsx)(`option`,{value:`both`,children:`both ways`}),(0,U.jsx)(`option`,{value:`out`,children:`rows it points at`}),(0,U.jsx)(`option`,{value:`in`,children:`rows pointing at it`})]}),(0,U.jsx)(`button`,{type:`button`,onClick:()=>S(u),disabled:!c||r,className:`bg-primary text-primary-foreground rounded-lg px-3 py-1 text-sm disabled:opacity-50`,children:`Draw`})]}),g.length>0&&(0,U.jsxs)(`p`,{className:`text-muted-foreground flex items-center gap-2 text-sm`,children:[`Starting from `,g.length,` `,g.length===1?`row`:`rows`,` picked in a query; the filters are not used.`,(0,U.jsx)(`button`,{type:`button`,onClick:()=>_([]),className:`border-input hover:text-accent-text rounded-lg border px-2 py-0.5 text-xs`,children:`Use filters instead`})]}),b.length>0&&g.length===0&&(0,U.jsx)(k,{columns:b,draft:u,onChange:d,onApply:()=>S(u)})]})}function Oe(e,t){let n=[...e.nodes.values()].filter(e=>!t.tables.has($(e.table))),r=new Set(n.map(e=>e.id));return{nodes:n,edges:[...e.edges.values()].filter(e=>!t.keys.has(e.constraint)&&r.has(e.from)&&r.has(e.to)),more:[...e.more.values()].filter(e=>r.has(e.node)&&!t.tables.has($(e.table))&&!t.keys.has(e.constraint))}}var ke=8,Ae=12,je=9,Me=e=>e.start?Ae:ke;function Ne({drawing:e,hidden:t,expanding:n,expanded:r,fitSignal:i,onExpand:a,onOpen:o,onLoadMore:s,onDrawn:c}){let{frame:l,view:u,setView:d,startDrag:f,zoomBy:p}=w(),[m,v]=(0,I.useState)(),[b,T]=(0,I.useState)(),[E,D]=(0,I.useState)(new Map),O=(0,I.useRef)({nodes:[],links:[],alpha:0,frame:0}),k=(0,I.useRef)(-1),re=(0,I.useRef)(u);(0,I.useEffect)(()=>{re.current=u},[u]);let A=(0,I.useMemo)(()=>Oe(e,t),[e,t]),j=(0,I.useCallback)(()=>{D(new Map(O.current.nodes.map(e=>[e.id,{x:e.x,y:e.y,r:e.r}])))},[]),M=(0,I.useCallback)(()=>{let e=O.current;if(e.frame)return;let t=()=>{e.alpha<=.012?e.frame=0:(g(e.nodes,e.links,e.alpha),e.alpha*=1-ne,j(),e.frame=requestAnimationFrame(t))};e.frame=requestAnimationFrame(t)},[j]);(0,I.useEffect)(()=>{let e=O.current;return()=>cancelAnimationFrame(e.frame)},[]);let N=(0,I.useCallback)(()=>{let e=l.current?.getBoundingClientRect();if(!e||O.current.nodes.length===0)return;let t=ee(O.current.nodes),n=S(t,e);d({k:n.k,x:n.x-t.x*n.k,y:n.y-t.y*n.k})},[l,d]);(0,I.useLayoutEffect)(()=>{let e=O.current,t=[...A.nodes.map(e=>({id:e.id,r:Me(e)})),...A.more.map(e=>({id:G(e),r:je}))],n=[...A.edges.map(e=>({source:e.from,target:e.to})),...A.more.map(e=>({source:e.node,target:G(e)}))],r=k.current!==i,a=r?void 0:new Map(e.nodes.map(e=>[e.id,{x:e.x,y:e.y}]));e.nodes=x(t,n,a),e.links=n,r?(k.current=i,te(e.nodes,n),e.alpha=0,j(),N()):(e.alpha=.5,M())},[A,i]),(0,I.useEffect)(()=>{c(()=>{let e=new Map(O.current.nodes.map(e=>[e.id,{x:e.x,y:e.y,r:e.r}]));return{nodes:A.nodes,edges:A.edges,more:A.more,placed:new Map,dots:e}})},[A,c]);let ie=(e,t)=>{if(e.button!==0)return;e.stopPropagation();let n=l.current?.getBoundingClientRect(),r=O.current.nodes.find(e=>e.id===t.id);if(!n||!r)return;let i={x:e.clientX,y:e.clientY},s=e.shiftKey,c=!1,u=e=>{if(!c&&Math.hypot(e.clientX-i.x,e.clientY-i.y)<4)return;c=!0;let t=re.current;r.pinned=!0,r.x=(e.clientX-n.left-t.x)/t.k,r.y=(e.clientY-n.top-t.y)/t.k,O.current.alpha=Math.max(O.current.alpha,.35),M()},d=()=>{window.removeEventListener(`pointermove`,u),window.removeEventListener(`pointerup`,d),r.pinned=!1,!c&&(s||!t.expandable?o(t):a(t))};window.addEventListener(`pointermove`,u),window.addEventListener(`pointerup`,d)},P=(0,I.useMemo)(()=>{if(!m)return;let e=new Set([m]);for(let t of A.edges)t.from===m&&e.add(t.to),t.to===m&&e.add(t.from);for(let t of A.more)t.node===m&&e.add(G(t));return e},[m,A]),F=b?e.edges.get(b):void 0,L=F&&E.get(F.from),R=F&&E.get(F.to),z={paintOrder:`stroke`};return(0,U.jsxs)(`div`,{className:`relative`,children:[(0,U.jsx)(y,{zoomBy:p,fit:N}),(0,U.jsx)(`div`,{ref:l,onPointerDown:f,className:`border-border h-[70vh] min-h-96 touch-none overflow-hidden border`,children:(0,U.jsxs)(`svg`,{role:`img`,"aria-label":`Record graph`,width:`100%`,height:`100%`,className:`cursor-grab select-none active:cursor-grabbing`,children:[(0,U.jsx)(`defs`,{children:(0,U.jsx)(`marker`,{id:`graph-arrow`,viewBox:`0 0 10 10`,refX:9,refY:5,markerWidth:7,markerHeight:7,orient:`auto-start-reverse`,children:(0,U.jsx)(`path`,{d:`M0,0 L10,5 L0,10 z`,className:`fill-accent-text`})})}),(0,U.jsxs)(`g`,{transform:`translate(${u.x},${u.y}) scale(${u.k})`,children:[A.edges.map(e=>{let t=E.get(e.from),n=E.get(e.to);if(!t||!n)return null;let r=b===e.id||(P?P.has(e.from)&&P.has(e.to)&&(e.from===m||e.to===m):!1),i=P&&!r?.12:b&&b!==e.id?.3:r?.95:.5,a=e.via?e.constraint:`${e.constraint} (${e.fromColumns.join(`, `)} → ${e.toColumns.join(`, `)})`,o=e.from===e.to?void 0:C(t,n,!e.via);return(0,U.jsx)(`g`,{"data-edge":e.constraint,children:o?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(`line`,{...o,className:`stroke-accent-text`,strokeWidth:r?2.2:1.4,strokeDasharray:e.via?`5 4`:void 0,opacity:i,markerEnd:e.via?void 0:`url(#graph-arrow)`}),(0,U.jsx)(`line`,{...o,stroke:`transparent`,strokeWidth:12,pointerEvents:`stroke`,onPointerEnter:()=>T(e.id),onPointerLeave:()=>T(void 0),children:(0,U.jsx)(`title`,{children:a})})]}):(0,U.jsx)(`path`,{d:h(t.x,t.y,t.r),fill:`none`,className:`stroke-accent-text`,strokeWidth:1.4,opacity:i,markerEnd:`url(#graph-arrow)`,children:(0,U.jsx)(`title`,{children:a})})},e.id)}),A.more.map(e=>{let t=E.get(G(e)),r=E.get(e.node);if(!t)return null;let i=e.count-e.shown,a=n.has(G(e)),o=P&&!P.has(G(e));return(0,U.jsxs)(`g`,{opacity:o?.2:1,children:[r&&(0,U.jsx)(`line`,{...C(r,t,!1),className:`stroke-muted-foreground`,strokeWidth:1,strokeDasharray:`3 3`,opacity:.6}),(0,U.jsxs)(`g`,{transform:`translate(${t.x},${t.y})`,className:`cursor-pointer`,role:`button`,"aria-label":`more in ${e.table.name}`,onPointerDown:e=>e.stopPropagation(),onClick:()=>!a&&s(e),children:[(0,U.jsx)(`circle`,{r:t.r,fill:`var(--background)`,strokeDasharray:`4 3`,className:`stroke-muted-foreground`}),(0,U.jsx)(`text`,{y:t.r+13,textAnchor:`middle`,className:`fill-foreground text-[11px]`,stroke:`var(--background)`,strokeWidth:3,strokeLinejoin:`round`,style:z,children:a?`loading…`:`+${i.toLocaleString()}${e.capped?`+`:``} more in ${e.table.name}`})]})]},G(e))}),A.nodes.map(e=>{let t=E.get(e.id);if(!t)return null;let i=_($(e.table)),a=n.has(e.id),o=Object.entries(e.key).map(([e,t])=>`${e} = ${t??`null`}`).join(`, `);return(0,U.jsxs)(`g`,{transform:`translate(${t.x},${t.y})`,"data-node":e.id,role:`button`,"aria-label":`${$(e.table)} ${e.label}`,className:e.expandable?`cursor-pointer`:`cursor-default`,opacity:P&&!P.has(e.id)?.2:1,onPointerDown:t=>ie(t,e),onPointerEnter:()=>v(e.id),onPointerLeave:()=>v(void 0),children:[(0,U.jsx)(`title`,{children:`${$(e.table)}\n${o}`}),(0,U.jsx)(`circle`,{r:t.r+6,fill:`transparent`}),(0,U.jsx)(`circle`,{r:t.r,fill:i,stroke:e.start?`var(--primary)`:`var(--background)`,strokeWidth:e.start?3:1.5}),r.has(e.id)&&!a&&(0,U.jsx)(`circle`,{r:t.r+4,fill:`none`,className:`stroke-accent-text`,strokeWidth:1.2,opacity:.7}),a&&(0,U.jsx)(`circle`,{r:t.r+5,fill:`none`,className:`stroke-accent-text`,strokeWidth:2,strokeDasharray:`14 14`,"aria-label":`Loading`,children:(0,U.jsx)(`animateTransform`,{attributeName:`transform`,type:`rotate`,from:`0`,to:`360`,dur:`0.8s`,repeatCount:`indefinite`})}),(0,U.jsx)(`text`,{y:t.r+14,textAnchor:`middle`,className:`fill-foreground text-[11px]`,stroke:`var(--background)`,strokeWidth:3,strokeLinejoin:`round`,style:z,children:xe(e.label,24)}),(0,U.jsx)(`text`,{y:t.r+26,textAnchor:`middle`,className:`fill-muted-foreground text-[9px]`,opacity:.75,stroke:`var(--background)`,strokeWidth:3,strokeLinejoin:`round`,style:z,children:$(e.table)})]},e.id)}),F&&L&&R&&(0,U.jsxs)(`g`,{transform:`translate(${(L.x+R.x)/2},${(L.y+R.y)/2})`,pointerEvents:`none`,children:[(0,U.jsx)(`rect`,{x:-4,y:-18,width:F.constraint.length*6.4+8,height:18,rx:4,className:`fill-card stroke-border`}),(0,U.jsx)(`text`,{y:-5,className:`fill-foreground text-[11px]`,children:F.constraint})]})]})]})})]})}function Pe({rows:e,settings:t,open:n,onToggle:r,onLabel:i,onRemove:a,onRestore:o,onDone:s,asking:c}){let l=e=>`rounded-md border px-1.5 py-0.5 font-mono text-[11px] ${e?`border-primary bg-primary/15 text-foreground`:`border-input text-muted-foreground hover:text-foreground`}`;return(0,U.jsxs)(`section`,{"aria-label":`Rows and tables`,className:`mb-3 text-sm`,children:[(0,U.jsxs)(`button`,{type:`button`,onClick:r,"aria-expanded":n,className:`border-input hover:text-accent-text flex items-center gap-1.5 rounded-lg border px-2 py-1 text-xs`,children:[(0,U.jsx)(T,{className:`size-3`}),`Labels and tables`,t.hidden.length>0&&(0,U.jsxs)(`span`,{className:`text-muted-foreground`,children:[`· `,t.hidden.length,` removed`]}),c&&!n&&(0,U.jsx)(`span`,{className:`bg-primary size-1.5 rounded-full`,"aria-label":`Needs a look`})]}),n&&(0,U.jsxs)(`div`,{className:`border-border mt-2 rounded-lg border p-3`,children:[(0,U.jsxs)(`p`,{className:`text-muted-foreground mb-3 text-xs`,children:[c?`Each kind of row in the graph is named by its key. Pick the fields to name it by instead (several are joined), and remove join tables: `:`Pick the fields that name each kind of row (several are joined), and remove join tables: `,`the graph then goes through them, linking the rows at either end directly.`]}),(0,U.jsx)(`ul`,{className:`flex max-h-72 flex-col gap-3 overflow-y-auto`,children:e.map(e=>{let n=t.labels[R(e.table)],r=n??e.keyColumns;return(0,U.jsxs)(`li`,{className:`flex flex-col gap-1.5`,"data-entity":e.name,children:[(0,U.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,U.jsx)(`span`,{className:`size-3 rounded-full`,style:{background:_(e.name)}}),(0,U.jsx)(`span`,{className:`font-medium`,children:e.name}),(0,U.jsx)(`span`,{className:`text-muted-foreground text-xs`,children:e.count}),e.join&&(0,U.jsx)(`span`,{className:`text-accent-text text-xs`,children:`looks like a join table`}),n&&(0,U.jsxs)(`button`,{type:`button`,onClick:()=>i(e.table,[]),className:`text-muted-foreground hover:text-foreground flex items-center gap-1 text-xs`,children:[(0,U.jsx)(F,{className:`size-3`}),` use the key`]}),(0,U.jsxs)(`button`,{type:`button`,onClick:()=>a(e.table),title:`Leave this table out of the graph; the rows on either side of it are linked directly`,className:`border-input hover:text-accent-text ml-auto flex items-center gap-1 rounded-lg border px-2 py-0.5 text-xs`,children:[(0,U.jsx)(M,{className:`size-3`}),` Remove from graph`]})]}),(0,U.jsx)(`div`,{className:`flex flex-wrap gap-1`,role:`group`,"aria-label":`Fields that name ${e.name}`,children:e.columns.map(t=>{let n=r.includes(t);return(0,U.jsx)(`button`,{type:`button`,"aria-pressed":n,className:l(n),title:e.keyColumns.includes(t)?`Part of the key`:void 0,onClick:()=>{let a=e.columns.filter(e=>e===t?!n:r.includes(e)),o=a.length===e.keyColumns.length&&a.every(t=>e.keyColumns.includes(t));i(e.table,a.length===0||o?[]:a)},children:t},t)})})]},e.name)})}),t.hidden.length>0&&(0,U.jsxs)(`div`,{className:`mt-3 flex flex-wrap items-center gap-1.5 text-xs`,"aria-label":`Removed tables`,children:[(0,U.jsx)(`span`,{className:`text-muted-foreground`,children:`Removed:`}),t.hidden.map(e=>(0,U.jsxs)(`button`,{type:`button`,onClick:()=>o(e),title:`Put this table back in the graph`,className:`border-input hover:text-accent-text flex items-center gap-1 rounded-lg border px-2 py-0.5`,children:[(0,U.jsx)(F,{className:`size-3`}),` `,R(e)]},R(e)))]}),(0,U.jsx)(`div`,{className:`mt-3 flex justify-end`,children:(0,U.jsx)(`button`,{type:`button`,onClick:s,className:`bg-primary text-primary-foreground rounded-lg px-3 py-1 text-xs`,children:`Done`})})]})]})}function Fe({environment:n,graph:r}){let[i,a]=(0,I.useState)(),[o,f]=(0,I.useState)(),[h,g]=(0,I.useState)(!1),[_,v]=(0,I.useState)(`both`),[ee,y]=(0,I.useState)(new Set),[b,x]=(0,I.useState)(new Set),[S,C]=(0,I.useState)(0),[te,ne]=(0,I.useState)({tables:new Set,keys:new Set}),[w,T]=(0,I.useState)(),[D,O]=(0,I.useState)(),k=(0,I.useRef)(void 0),re=(0,I.useCallback)(e=>{k.current=e},[]),j=(0,I.useRef)(void 0);(0,I.useEffect)(()=>{j.current=i},[i]);let[M,N]=(0,I.useState)(()=>ae(n)),[P,F]=(0,I.useState)(n);P!==n&&(F(n),N(ae(n)));let L=(0,I.useRef)(M);(0,I.useEffect)(()=>{L.current=M,P===n&&oe(n,M)},[M,P,n]);let[z,B]=(0,I.useState)(),[V,se]=(0,I.useState)(()=>({hidden:M.hidden,skipped:M.skipped})),H=(0,I.useRef)(V),le=(0,I.useCallback)((t,r,i=[],o=!1)=>{let{hidden:s,skipped:c}=L.current;H.current={hidden:s,skipped:c},se({hidden:s,skipped:c}),g(!0),f(void 0),v(r),O(t),e.graph(n,{schema:t.schema,name:t.table},{filters:t.filters,...t.keys?{keys:t.keys}:{},depth:t.depth,direction:r,hide:s,skipKeys:c}).then(async t=>{let l={...Ce(Se(),t),moreStart:t.moreStart},u=new Set;for(let t of i){let i=l.nodes.get(t);if(i?.expandable)try{let a=await e.expandGraph(n,{node:t,drawn:[...l.nodes.keys(),...l.edges.keys()],distance:i.distance,direction:r,hide:s,skipKeys:c});l=Ce(l,a),u.add(t)}catch{break}}a(l),x(u),ne({tables:new Set,keys:new Set}),T(void 0),C(e=>e+1),o||B([...l.nodes.values()].some(e=>!L.current.confirmed.includes(R(e.table))))}).catch(e=>f(e.message)).finally(()=>g(!1))},[n]),W=(0,I.useCallback)((t,r,i)=>{let o=j.current;if(!o)return;let s=i?G(i):t;y(e=>new Set(e).add(s)),e.expandGraph(n,{node:t,drawn:[...o.nodes.keys(),...o.edges.keys()],distance:r,direction:_,...i?{key:i.constraint,skip:i.shown}:{},hide:H.current.hidden,skipKeys:H.current.skipped}).then(e=>{a(t=>t&&Ce(t,e,i)),i||x(e=>new Set(e).add(t))}).catch(e=>f(e.message)).finally(()=>y(e=>{let t=new Set(e);return t.delete(s),t}))},[n,_]);(0,I.useEffect)(()=>{D&&t({environment:n,graph:{...D,direction:_,...b.size>0?{expanded:[...b]}:{}}})},[n,D,_,b]);let[fe,pe]=(0,I.useState)(),[K,he]=(0,I.useState)(),q=async e=>{let t=k.current?.();if(!t||t.nodes.length===0)return;he(void 0);let n=l(`graph-${D?.table??`rows`}`,`graph`);try{if(e===`json`)s(new Blob([ye(t)],{type:`application/json`}),`${n}.json`);else{let r=ve(t);if(e===`svg`)s(new Blob([r],{type:`image/svg+xml`}),`${n}.svg`);else{let e=be(r)??ge(t.placed),i=Math.min(2,8e3/Math.max(e.width,e.height));s(await c(r,e.width,e.height,i),`${n}.png`)}}pe(e),window.setTimeout(()=>pe(void 0),1500)}catch(e){he(e instanceof Error?e.message:String(e))}},J=(e,t)=>ne(n=>{let r=new Set(n[e]);return r.delete(t)||r.add(t),{...n,[e]:r}}),Y=(0,I.useMemo)(()=>i&&{...i,nodes:ue(i.nodes,M.labels)},[i,M.labels]),X=(0,I.useMemo)(()=>{if(!i)return[];let e=de(i.nodes.values(),i.edges.values()),t=new Map;for(let n of i.nodes.values()){let r=$(n.table),i=t.get(r);i?i.count++:t.set(r,{table:n.table,name:r,count:1,columns:Object.keys(n.row),keyColumns:Object.keys(n.key),join:e.has(r)})}return[...t.values()].sort((e,t)=>e.name.localeCompare(t.name))},[i]),Z=X.some(e=>!M.confirmed.includes(R(e.table))),_e=(e,t)=>N(n=>{let r={...n.labels};return t.length===0?delete r[R(e)]:r[R(e)]=t,{...n,labels:r}}),Q=e=>N(t=>({...t,hidden:t.hidden.some(t=>R(t)===R(e))?t.hidden.filter(t=>R(t)!==R(e)):[...t.hidden,e]})),xe=e=>N(t=>({...t,skipped:t.skipped.includes(e)?t.skipped.filter(t=>t!==e):[...t.skipped,e]})),we=ce(V,M),Oe=(0,I.useMemo)(()=>{let e=new Map;for(let t of i?.nodes.values()??[])e.set(R(t.table),(e.get(R(t.table))??0)+1);return e},[i]),ke=w?Y?.nodes.get(w):void 0;return(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`h2`,{className:`text-accent-text mb-1 flex items-center gap-2 text-2xl`,children:[(0,U.jsx)(u,{className:`size-6`}),`Graph`]}),(0,U.jsx)(`p`,{className:`text-muted-foreground mb-4 text-sm`,children:`Pick some rows and see the rows linked to them through foreign keys. Click a dot to follow its links; shift-click to see the row. Drag a dot to move it, drag the background to move around, scroll to zoom.`}),(0,U.jsx)(De,{environment:n,initial:r,busy:h,onDraw:le}),o&&(0,U.jsx)(`p`,{className:`text-destructive mb-3 text-sm`,children:o}),h&&!i?(0,U.jsx)(E,{className:`h-80`}):i?i.nodes.size===0?(0,U.jsxs)(`p`,{className:`text-muted-foreground flex items-center gap-2 text-sm`,children:[(0,U.jsx)(A,{className:`size-4`}),` No rows matched.`]}):(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`p`,{className:`text-muted-foreground mb-2 flex items-center gap-2 text-xs`,children:[h&&(0,U.jsx)(m,{className:`size-3 animate-spin`}),i.nodes.size,` rows, `,i.edges.size,` links`,i.moreStart&&` · more rows matched than were drawn`,i.truncated&&` · the limit on rows was reached, so some linked rows are missing`]}),(0,U.jsxs)(`div`,{className:`text-muted-foreground mb-3 flex flex-wrap items-center gap-2 text-xs`,children:[(0,U.jsxs)(`button`,{type:`button`,onClick:()=>C(e=>e+1),title:`Lay the graph out afresh and fit it to the screen`,className:`border-input hover:text-accent-text flex items-center gap-1 rounded-lg border px-2 py-1`,children:[(0,U.jsx)(ie,{className:`size-3`}),` Re-layout`]}),(0,U.jsx)(`span`,{className:`ml-2`,children:`Export`}),[`svg`,`png`,`json`].map(e=>(0,U.jsxs)(`button`,{type:`button`,onClick:()=>void q(e),className:`border-input hover:text-accent-text flex items-center gap-1 rounded-lg border px-2 py-1 uppercase`,children:[fe===e?(0,U.jsx)(d,{className:`size-3`}):(0,U.jsx)(p,{className:`size-3`}),` `,e]},e)),K&&(0,U.jsx)(`span`,{role:`alert`,className:`text-destructive`,children:K})]}),D&&(0,U.jsx)(`p`,{className:`text-muted-foreground mb-1 text-xs`,children:`Schema map: click a table to leave it out of the graph (it is gone through, like a join table), and click an arrow to stop following that key.`}),D&&(0,U.jsx)(me,{environment:n,schema:D.schema,start:{schema:D.schema,name:D.table},settings:M,counts:Oe,onToggleTable:Q,onToggleKey:xe}),we>0&&D&&(0,U.jsxs)(`p`,{className:`mb-3 flex flex-wrap items-center gap-2 text-sm`,role:`status`,children:[we,` `,we===1?`change`:`changes`,` to the tables and keys in the graph.`,(0,U.jsx)(`button`,{type:`button`,onClick:()=>le(D,_,[...b],!0),disabled:h,className:`bg-primary text-primary-foreground rounded-lg px-3 py-1 text-xs disabled:opacity-50`,children:`Draw again`}),(0,U.jsx)(`button`,{type:`button`,onClick:()=>N(e=>({...e,hidden:V.hidden,skipped:V.skipped})),className:`border-input hover:text-accent-text rounded-lg border px-2 py-1 text-xs`,children:`Undo`})]}),(0,U.jsx)(Pe,{rows:X,settings:M,open:z??Z,asking:Z,onToggle:()=>B(!(z??Z)),onLabel:_e,onRemove:Q,onRestore:Q,onDone:()=>{N(e=>({...e,confirmed:[...new Set([...e.confirmed,...X.map(e=>R(e.table))])]})),B(!1)}}),(0,U.jsx)(Ee,{drawing:Y??i,hidden:te,onToggle:J}),(0,U.jsx)(Ne,{drawing:Y??i,hidden:te,expanding:ee,expanded:b,fitSignal:S,onExpand:e=>W(e.id,e.distance),onOpen:e=>T(e.id),onLoadMore:e=>W(e.node,i.nodes.get(e.node)?.distance??0,e),onDrawn:re})]}):null,ke&&(0,U.jsx)(Te,{environment:n,node:ke,onClose:()=>T(void 0)})]})}export{Fe as GraphView};