sql-dag-flow 0.3.0__tar.gz → 0.4.1__tar.gz
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.
- {sql_dag_flow-0.3.0/src/sql_dag_flow.egg-info → sql_dag_flow-0.4.1}/PKG-INFO +22 -12
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/README.md +21 -11
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/pyproject.toml +1 -1
- sql_dag_flow-0.4.1/src/sql_dag_flow/static/assets/index-DqU54Zg2.css +1 -0
- sql_dag_flow-0.4.1/src/sql_dag_flow/static/assets/index-FP7nXXa6.js +84 -0
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/src/sql_dag_flow/static/index.html +2 -2
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1/src/sql_dag_flow.egg-info}/PKG-INFO +22 -12
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/src/sql_dag_flow.egg-info/SOURCES.txt +2 -2
- sql_dag_flow-0.3.0/src/sql_dag_flow/static/assets/index-B6fMDnZ3.js +0 -84
- sql_dag_flow-0.3.0/src/sql_dag_flow/static/assets/index-h7gxR8yA.css +0 -1
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/LICENSE +0 -0
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/MANIFEST.in +0 -0
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/setup.cfg +0 -0
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/src/sql_dag_flow/__init__.py +0 -0
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/src/sql_dag_flow/main.py +0 -0
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/src/sql_dag_flow/parser.py +0 -0
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/src/sql_dag_flow/static/vite.svg +0 -0
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/src/sql_dag_flow/test_api_endpoints.py +0 -0
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/src/sql_dag_flow/test_parser.py +0 -0
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/src/sql_dag_flow/verify_counts.py +0 -0
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/src/sql_dag_flow.egg-info/dependency_links.txt +0 -0
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/src/sql_dag_flow.egg-info/entry_points.txt +0 -0
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/src/sql_dag_flow.egg-info/requires.txt +0 -0
- {sql_dag_flow-0.3.0 → sql_dag_flow-0.4.1}/src/sql_dag_flow.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sql-dag-flow
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: A sophisticated SQL lineage visualization tool for Medallion Architectures.
|
|
5
5
|
Author-email: Flavio Sandoval <dsandovalflavio@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -83,16 +83,26 @@ Specially optimized for the **Medallion Architecture** (Bronze, Silver, Gold) an
|
|
|
83
83
|
* **Transparent & Borderless**:Create clean, floating text labels without boxes.
|
|
84
84
|
* **Groups**: Create visual containers to group related nodes.
|
|
85
85
|
|
|
86
|
-
### 📊 Discovery & Analysis Tools
|
|
86
|
+
### 📊 Discovery & Analysis Tools
|
|
87
87
|
* **Business Rule Extraction**: Automatically detects and displays WHERE filters, CASE logic, HAVING clauses, and aggregations from each SQL model.
|
|
88
88
|
* **Complexity Scoring**: Weighted metric per node (JOINs×3, CTEs×2, Subqueries×3, Filters×1, CASE×2, Aggregations×1, UNIONs×2) with color-coded badges (🟢 Low, 🟡 Medium, 🟠 High, 🔴 Very High). Toggleable via ⚡ button.
|
|
89
89
|
* **Statistics Panel**: Centered popup with layer distribution bars, edge/source/sink/orphan counts, project/dataset tree, and architecture health validation.
|
|
90
90
|
* **Schema Preview**: Extracts columns from DDL, CTAS (`CREATE TABLE AS SELECT`), and `CREATE VIEW` statements.
|
|
91
91
|
|
|
92
|
+
### 🎨 Linear-Inspired UI (New in v0.4.0 ✨)
|
|
93
|
+
* **Design Token System**: ~80 CSS custom properties for consistent theming across all components.
|
|
94
|
+
* **Premium Dark Theme**: Deep `#0d0d0d` canvas with warm white text (`#e8e8e6`), never pure white.
|
|
95
|
+
* **Refined Light Theme**: Warm off-white `#f7f6f3` backgrounds — never harsh pure white.
|
|
96
|
+
* **Glassmorphism Toolbars**: `backdrop-filter: blur(16px)` on all floating panels.
|
|
97
|
+
* **Violet-Indigo Accent**: Premium `#7c6aef` accent color replacing generic blues/greens.
|
|
98
|
+
* **Smooth Animations**: `fadeIn` and `slideUp` micro-animations on popovers and modals.
|
|
99
|
+
* **Custom Scrollbars**: Subtle, styled scrollbars matching the theme.
|
|
100
|
+
* **Focus Rings**: Accessible focus indicators using the accent color.
|
|
101
|
+
|
|
92
102
|
### ⚙️ Customization
|
|
93
103
|
* **Premium UI**:
|
|
94
104
|
* **Themes**: Toggle between Light and Dark modes.
|
|
95
|
-
* **Palettes**: Choose from Standard
|
|
105
|
+
* **Palettes**: Choose from **Standard**, **Vivid**, **Pastel**, or **Linear** (new — muted, LCH-inspired tones) color schemes.
|
|
96
106
|
* **Styles**: Switch between "Full" (colored body) and "Minimal" (colored border) node styles.
|
|
97
107
|
* **Export**: Save high-resolution **PNG** or vector **SVG** diagrams for documentation.
|
|
98
108
|
|
|
@@ -102,14 +112,14 @@ Specially optimized for the **Medallion Architecture** (Bronze, Silver, Gold) an
|
|
|
102
112
|
|
|
103
113
|
SQL DAG Flow uses distinct colors to identify node types. You can switch between these palettes in the Settings.
|
|
104
114
|
|
|
105
|
-
| Node Type | Layer / Meaning | Standard | Vivid | Pastel |
|
|
106
|
-
| :--- | :--- | :--- | :--- | :--- |
|
|
107
|
-
| **Bronze** | Raw Ingestion | 🟤 Brown (`#8B4513`) | 🟠 Orange (`#FF5722`) | 🟤 Pale Brown (`#D7CCC8`) |
|
|
108
|
-
| **Silver** | Cleaned / Conformed | ⚪ Gray (`#708090`) | 🔵 Blue (`#29B6F6`) | ⚪ Blue Grey (`#CFD8DC`) |
|
|
109
|
-
| **Gold** | Business Aggregates | 🟡 Gold (`#DAA520`) | 🟡 Yellow (`#FFEB3B`) | 🟡 Pale Yellow (`#FFF9C4`) |
|
|
110
|
-
| **External** | Missing / Ghost Node | 🟠 Dark Orange (`#D35400`) | 🟠 Neon Orange (`#FF9800`) | 🟠 Peach (`#FFE0B2`) |
|
|
111
|
-
| **CTE** | Internal Common Table Expression | 💖 Pink (`#E91E63`) | 💗 Deep Pink (`#F50057`) | 🌸 Light Pink (`#F8BBD0`) |
|
|
112
|
-
| **Other** | Uncategorized | 🔵 Teal (`#4CA1AF`) | 💠 Cyan (`#00BCD4`) | 🧊 Pale Cyan (`#B2EBF2`) |
|
|
115
|
+
| Node Type | Layer / Meaning | Standard | Vivid | Pastel | Linear |
|
|
116
|
+
| :--- | :--- | :--- | :--- | :--- | :--- |
|
|
117
|
+
| **Bronze** | Raw Ingestion | 🟤 Brown (`#8B4513`) | 🟠 Orange (`#FF5722`) | 🟤 Pale Brown (`#D7CCC8`) | 🟤 Muted (`#B08968`) |
|
|
118
|
+
| **Silver** | Cleaned / Conformed | ⚪ Gray (`#708090`) | 🔵 Blue (`#29B6F6`) | ⚪ Blue Grey (`#CFD8DC`) | ⚪ Slate (`#8E99A4`) |
|
|
119
|
+
| **Gold** | Business Aggregates | 🟡 Gold (`#DAA520`) | 🟡 Yellow (`#FFEB3B`) | 🟡 Pale Yellow (`#FFF9C4`) | 🟡 Warm (`#D4A843`) |
|
|
120
|
+
| **External** | Missing / Ghost Node | 🟠 Dark Orange (`#D35400`) | 🟠 Neon Orange (`#FF9800`) | 🟠 Peach (`#FFE0B2`) | 🟠 Sand (`#CC8B5E`) |
|
|
121
|
+
| **CTE** | Internal Common Table Expression | 💖 Pink (`#E91E63`) | 💗 Deep Pink (`#F50057`) | 🌸 Light Pink (`#F8BBD0`) | 💜 Mauve (`#C77092`) |
|
|
122
|
+
| **Other** | Uncategorized | 🔵 Teal (`#4CA1AF`) | 💠 Cyan (`#00BCD4`) | 🧊 Pale Cyan (`#B2EBF2`) | 🔵 Ocean (`#6B9DAD`) |
|
|
113
123
|
|
|
114
124
|
---
|
|
115
125
|
|
|
@@ -121,7 +131,7 @@ Install easily via `pip`:
|
|
|
121
131
|
pip install sql-dag-flow
|
|
122
132
|
```
|
|
123
133
|
|
|
124
|
-
To update to the latest version (**v0.
|
|
134
|
+
To update to the latest version (**v0.4.0**):
|
|
125
135
|
|
|
126
136
|
```bash
|
|
127
137
|
pip install --upgrade sql-dag-flow
|
|
@@ -58,16 +58,26 @@ Specially optimized for the **Medallion Architecture** (Bronze, Silver, Gold) an
|
|
|
58
58
|
* **Transparent & Borderless**:Create clean, floating text labels without boxes.
|
|
59
59
|
* **Groups**: Create visual containers to group related nodes.
|
|
60
60
|
|
|
61
|
-
### 📊 Discovery & Analysis Tools
|
|
61
|
+
### 📊 Discovery & Analysis Tools
|
|
62
62
|
* **Business Rule Extraction**: Automatically detects and displays WHERE filters, CASE logic, HAVING clauses, and aggregations from each SQL model.
|
|
63
63
|
* **Complexity Scoring**: Weighted metric per node (JOINs×3, CTEs×2, Subqueries×3, Filters×1, CASE×2, Aggregations×1, UNIONs×2) with color-coded badges (🟢 Low, 🟡 Medium, 🟠 High, 🔴 Very High). Toggleable via ⚡ button.
|
|
64
64
|
* **Statistics Panel**: Centered popup with layer distribution bars, edge/source/sink/orphan counts, project/dataset tree, and architecture health validation.
|
|
65
65
|
* **Schema Preview**: Extracts columns from DDL, CTAS (`CREATE TABLE AS SELECT`), and `CREATE VIEW` statements.
|
|
66
66
|
|
|
67
|
+
### 🎨 Linear-Inspired UI (New in v0.4.0 ✨)
|
|
68
|
+
* **Design Token System**: ~80 CSS custom properties for consistent theming across all components.
|
|
69
|
+
* **Premium Dark Theme**: Deep `#0d0d0d` canvas with warm white text (`#e8e8e6`), never pure white.
|
|
70
|
+
* **Refined Light Theme**: Warm off-white `#f7f6f3` backgrounds — never harsh pure white.
|
|
71
|
+
* **Glassmorphism Toolbars**: `backdrop-filter: blur(16px)` on all floating panels.
|
|
72
|
+
* **Violet-Indigo Accent**: Premium `#7c6aef` accent color replacing generic blues/greens.
|
|
73
|
+
* **Smooth Animations**: `fadeIn` and `slideUp` micro-animations on popovers and modals.
|
|
74
|
+
* **Custom Scrollbars**: Subtle, styled scrollbars matching the theme.
|
|
75
|
+
* **Focus Rings**: Accessible focus indicators using the accent color.
|
|
76
|
+
|
|
67
77
|
### ⚙️ Customization
|
|
68
78
|
* **Premium UI**:
|
|
69
79
|
* **Themes**: Toggle between Light and Dark modes.
|
|
70
|
-
* **Palettes**: Choose from Standard
|
|
80
|
+
* **Palettes**: Choose from **Standard**, **Vivid**, **Pastel**, or **Linear** (new — muted, LCH-inspired tones) color schemes.
|
|
71
81
|
* **Styles**: Switch between "Full" (colored body) and "Minimal" (colored border) node styles.
|
|
72
82
|
* **Export**: Save high-resolution **PNG** or vector **SVG** diagrams for documentation.
|
|
73
83
|
|
|
@@ -77,14 +87,14 @@ Specially optimized for the **Medallion Architecture** (Bronze, Silver, Gold) an
|
|
|
77
87
|
|
|
78
88
|
SQL DAG Flow uses distinct colors to identify node types. You can switch between these palettes in the Settings.
|
|
79
89
|
|
|
80
|
-
| Node Type | Layer / Meaning | Standard | Vivid | Pastel |
|
|
81
|
-
| :--- | :--- | :--- | :--- | :--- |
|
|
82
|
-
| **Bronze** | Raw Ingestion | 🟤 Brown (`#8B4513`) | 🟠 Orange (`#FF5722`) | 🟤 Pale Brown (`#D7CCC8`) |
|
|
83
|
-
| **Silver** | Cleaned / Conformed | ⚪ Gray (`#708090`) | 🔵 Blue (`#29B6F6`) | ⚪ Blue Grey (`#CFD8DC`) |
|
|
84
|
-
| **Gold** | Business Aggregates | 🟡 Gold (`#DAA520`) | 🟡 Yellow (`#FFEB3B`) | 🟡 Pale Yellow (`#FFF9C4`) |
|
|
85
|
-
| **External** | Missing / Ghost Node | 🟠 Dark Orange (`#D35400`) | 🟠 Neon Orange (`#FF9800`) | 🟠 Peach (`#FFE0B2`) |
|
|
86
|
-
| **CTE** | Internal Common Table Expression | 💖 Pink (`#E91E63`) | 💗 Deep Pink (`#F50057`) | 🌸 Light Pink (`#F8BBD0`) |
|
|
87
|
-
| **Other** | Uncategorized | 🔵 Teal (`#4CA1AF`) | 💠 Cyan (`#00BCD4`) | 🧊 Pale Cyan (`#B2EBF2`) |
|
|
90
|
+
| Node Type | Layer / Meaning | Standard | Vivid | Pastel | Linear |
|
|
91
|
+
| :--- | :--- | :--- | :--- | :--- | :--- |
|
|
92
|
+
| **Bronze** | Raw Ingestion | 🟤 Brown (`#8B4513`) | 🟠 Orange (`#FF5722`) | 🟤 Pale Brown (`#D7CCC8`) | 🟤 Muted (`#B08968`) |
|
|
93
|
+
| **Silver** | Cleaned / Conformed | ⚪ Gray (`#708090`) | 🔵 Blue (`#29B6F6`) | ⚪ Blue Grey (`#CFD8DC`) | ⚪ Slate (`#8E99A4`) |
|
|
94
|
+
| **Gold** | Business Aggregates | 🟡 Gold (`#DAA520`) | 🟡 Yellow (`#FFEB3B`) | 🟡 Pale Yellow (`#FFF9C4`) | 🟡 Warm (`#D4A843`) |
|
|
95
|
+
| **External** | Missing / Ghost Node | 🟠 Dark Orange (`#D35400`) | 🟠 Neon Orange (`#FF9800`) | 🟠 Peach (`#FFE0B2`) | 🟠 Sand (`#CC8B5E`) |
|
|
96
|
+
| **CTE** | Internal Common Table Expression | 💖 Pink (`#E91E63`) | 💗 Deep Pink (`#F50057`) | 🌸 Light Pink (`#F8BBD0`) | 💜 Mauve (`#C77092`) |
|
|
97
|
+
| **Other** | Uncategorized | 🔵 Teal (`#4CA1AF`) | 💠 Cyan (`#00BCD4`) | 🧊 Pale Cyan (`#B2EBF2`) | 🔵 Ocean (`#6B9DAD`) |
|
|
88
98
|
|
|
89
99
|
---
|
|
90
100
|
|
|
@@ -96,7 +106,7 @@ Install easily via `pip`:
|
|
|
96
106
|
pip install sql-dag-flow
|
|
97
107
|
```
|
|
98
108
|
|
|
99
|
-
To update to the latest version (**v0.
|
|
109
|
+
To update to the latest version (**v0.4.0**):
|
|
100
110
|
|
|
101
111
|
```bash
|
|
102
112
|
pip install --upgrade sql-dag-flow
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import"https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,400;14..32,500;14..32,600;14..32,700;14..32,800&display=swap";:root,[data-theme=dark]{--surface-primary: #0d0d0d;--surface-secondary: #141414;--surface-elevated: #1c1c1c;--surface-inset: #0a0a0a;--surface-overlay: rgba(0, 0, 0, .6);--surface-tooltip: rgba(22, 22, 22, .95);--text-primary: #e8e8e6;--text-secondary: #8b8b8b;--text-tertiary: #5a5a5a;--text-inverse: #0d0d0d;--text-accent: #8d9eff;--border-default: rgba(255, 255, 255, .06);--border-emphasis: rgba(255, 255, 255, .12);--border-strong: rgba(255, 255, 255, .2);--interactive-hover: rgba(255, 255, 255, .04);--interactive-active: rgba(255, 255, 255, .08);--interactive-selected: rgba(255, 255, 255, .06);--accent-primary: #7c6aef;--accent-hover: #8d7df5;--accent-muted: rgba(124, 106, 239, .15);--accent-text: #a99eff;--shadow-sm: 0 1px 2px rgba(0, 0, 0, .3), 0 1px 3px rgba(0, 0, 0, .15);--shadow-md: 0 4px 12px rgba(0, 0, 0, .4), 0 2px 4px rgba(0, 0, 0, .2);--shadow-lg: 0 12px 40px rgba(0, 0, 0, .5), 0 4px 12px rgba(0, 0, 0, .3);--shadow-xl: 0 20px 60px rgba(0, 0, 0, .6), 0 8px 20px rgba(0, 0, 0, .35);--canvas-bg: #0d0d0d;--canvas-dots: #1a1a1a;--edge-default: #444;--edge-incoming: #4dc9f6;--edge-outgoing: #f67280;--edge-lineage: #9d7aff;--edge-dimmed: #333;--status-success: #34d399;--status-warning: #fbbf24;--status-error: #f87171;--status-info: #60a5fa;--minimap-bg: #141414;--scrollbar-thumb: rgba(255, 255, 255, .1);--scrollbar-track: transparent}[data-theme=light]{--surface-primary: #f7f6f3;--surface-secondary: #efeeeb;--surface-elevated: #ffffff;--surface-inset: #eae9e6;--surface-overlay: rgba(0, 0, 0, .4);--surface-tooltip: rgba(255, 255, 255, .97);--text-primary: #1a1a1a;--text-secondary: #5c5c5c;--text-tertiary: #8a8a8a;--text-inverse: #f7f6f3;--text-accent: #5b4cc4;--border-default: rgba(0, 0, 0, .06);--border-emphasis: rgba(0, 0, 0, .1);--border-strong: rgba(0, 0, 0, .18);--interactive-hover: rgba(0, 0, 0, .03);--interactive-active: rgba(0, 0, 0, .06);--interactive-selected: rgba(0, 0, 0, .04);--accent-primary: #6c5ce7;--accent-hover: #5a4bd6;--accent-muted: rgba(108, 92, 231, .1);--accent-text: #5b4cc4;--shadow-sm: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--shadow-md: 0 4px 12px rgba(0, 0, 0, .06), 0 2px 4px rgba(0, 0, 0, .04);--shadow-lg: 0 12px 40px rgba(0, 0, 0, .08), 0 4px 12px rgba(0, 0, 0, .04);--shadow-xl: 0 20px 60px rgba(0, 0, 0, .1), 0 8px 20px rgba(0, 0, 0, .05);--canvas-bg: #f7f6f3;--canvas-dots: #ddd;--edge-default: #b0b0b0;--edge-incoming: #0077b6;--edge-outgoing: #c9184a;--edge-lineage: #7b2cbf;--edge-dimmed: #ccc;--status-success: #059669;--status-warning: #d97706;--status-error: #dc2626;--status-info: #2563eb;--minimap-bg: #efeeeb;--scrollbar-thumb: rgba(0, 0, 0, .12);--scrollbar-track: transparent}:root{--layer-bronze-standard: #8B4513;--layer-silver-standard: #708090;--layer-gold-standard: #DAA520;--layer-external-standard: #D35400;--layer-cte-standard: #E91E63;--layer-other-standard: #4CA1AF;--layer-bronze-vivid: #FF5722;--layer-silver-vivid: #29B6F6;--layer-gold-vivid: #FFEB3B;--layer-external-vivid: #FF9800;--layer-cte-vivid: #F50057;--layer-other-vivid: #00BCD4;--layer-bronze-pastel: #D7CCC8;--layer-silver-pastel: #CFD8DC;--layer-gold-pastel: #FFF9C4;--layer-external-pastel: #FFE0B2;--layer-cte-pastel: #F8BBD0;--layer-other-pastel: #B2EBF2;--layer-bronze-linear: #B08968;--layer-silver-linear: #8E99A4;--layer-gold-linear: #D4A843;--layer-external-linear: #CC8B5E;--layer-cte-linear: #C77092;--layer-other-linear: #6B9DAD;--layer-dot-bronze: #cd7f32;--layer-dot-silver: #708090;--layer-dot-gold: #FFD700;--layer-dot-external: #ff9f1c;--layer-dot-cte: #E91E63;--layer-dot-other: #4CA1AF}body{margin:0;font-family:Inter,system-ui,-apple-system,BlinkMacSystemFont,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:100vw;height:100vh;overflow:hidden;background:var(--surface-primary);color:var(--text-primary);transition:background .3s ease,color .3s ease}code{font-family:SF Mono,Fira Code,Cascadia Code,Menlo,Monaco,Consolas,Courier New,monospace}.react-flow__attribution{display:none!important}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:var(--scrollbar-track)}::-webkit-scrollbar-thumb{background:var(--scrollbar-thumb);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--border-emphasis)}.heading-display{font-variation-settings:"opsz" 32;letter-spacing:-.02em}.transition-colors{transition:background-color .2s cubic-bezier(.25,.1,.25,1),color .2s cubic-bezier(.25,.1,.25,1),border-color .2s cubic-bezier(.25,.1,.25,1),box-shadow .2s cubic-bezier(.25,.1,.25,1)}.sidebar-item:hover{background:var(--interactive-hover)!important}@keyframes fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes slideUp{0%{opacity:0;transform:translate(-50%,8px)}to{opacity:1;transform:translate(-50%)}}.react-flow{direction:ltr;--xy-edge-stroke-default: #b1b1b7;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #555;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(255, 255, 255, .5);--xy-minimap-background-color-default: #fff;--xy-minimap-mask-background-color-default: rgba(240, 240, 240, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #e2e2e2;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: transparent;--xy-background-pattern-dots-color-default: #91919a;--xy-background-pattern-lines-color-default: #eee;--xy-background-pattern-cross-color-default: #e2e2e2;background-color:var(--xy-background-color, var(--xy-background-color-default));--xy-node-color-default: inherit;--xy-node-border-default: 1px solid #1a192b;--xy-node-background-color-default: #fff;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(0, 0, 0, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #1a192b;--xy-node-border-radius-default: 3px;--xy-handle-background-color-default: #1a192b;--xy-handle-border-color-default: #fff;--xy-selection-background-color-default: rgba(0, 89, 220, .08);--xy-selection-border-default: 1px dotted rgba(0, 89, 220, .8);--xy-controls-button-background-color-default: #fefefe;--xy-controls-button-background-color-hover-default: #f4f4f4;--xy-controls-button-color-default: inherit;--xy-controls-button-color-hover-default: inherit;--xy-controls-button-border-color-default: #eee;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #ffffff;--xy-edge-label-color-default: inherit;--xy-resize-background-color-default: #3367d9}.react-flow.dark{--xy-edge-stroke-default: #3e3e3e;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #727272;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(150, 150, 150, .25);--xy-minimap-background-color-default: #141414;--xy-minimap-mask-background-color-default: rgba(60, 60, 60, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #2b2b2b;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: #141414;--xy-background-pattern-dots-color-default: #777;--xy-background-pattern-lines-color-default: #777;--xy-background-pattern-cross-color-default: #777;--xy-node-color-default: #f8f8f8;--xy-node-border-default: 1px solid #3c3c3c;--xy-node-background-color-default: #1e1e1e;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(255, 255, 255, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #999;--xy-handle-background-color-default: #bebebe;--xy-handle-border-color-default: #1e1e1e;--xy-selection-background-color-default: rgba(200, 200, 220, .08);--xy-selection-border-default: 1px dotted rgba(200, 200, 220, .8);--xy-controls-button-background-color-default: #2b2b2b;--xy-controls-button-background-color-hover-default: #3e3e3e;--xy-controls-button-color-default: #f8f8f8;--xy-controls-button-color-hover-default: #fff;--xy-controls-button-border-color-default: #5b5b5b;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #141414;--xy-edge-label-color-default: #f8f8f8}.react-flow__background{background-color:var(--xy-background-color-props, var(--xy-background-color, var(--xy-background-color-default)));pointer-events:none;z-index:-1}.react-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.react-flow__pane{z-index:1}.react-flow__pane.draggable{cursor:grab}.react-flow__pane.dragging{cursor:grabbing}.react-flow__pane.selection{cursor:pointer}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow__edge-path{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width, var(--xy-edge-stroke-width-default));fill:none}.react-flow__connection-path{stroke:var(--xy-connectionline-stroke, var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width, var(--xy-connectionline-stroke-width-default));fill:none}.react-flow .react-flow__edges{position:absolute}.react-flow .react-flow__edges svg{overflow:visible;position:absolute;pointer-events:none}.react-flow__edge{pointer-events:visibleStroke}.react-flow__edge.selectable{cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selectable:focus .react-flow__edge-path,.react-flow__edge.selectable:focus-visible .react-flow__edge-path{stroke:var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default))}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__arrowhead polyline{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:dashdraw .5s linear infinite}svg.react-flow__connectionline{z-index:1001;overflow:visible;position:absolute}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default}.react-flow__node.selectable{cursor:pointer}.react-flow__node.draggable{cursor:grab;pointer-events:all}.react-flow__node.draggable.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.react-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:grab}.react-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;width:6px;height:6px;background-color:var(--xy-handle-background-color, var(--xy-handle-background-color-default));border:1px solid var(--xy-handle-border-color, var(--xy-handle-border-color-default));border-radius:100%}.react-flow__handle.connectingfrom{pointer-events:all}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;left:50%;bottom:0;transform:translate(-50%,50%)}.react-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.react-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.react-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__pane.selection .react-flow__panel{pointer-events:none}.react-flow__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.top.center,.react-flow__panel.bottom.center{left:50%;transform:translate(-15px) translate(-50%)}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.left.center,.react-flow__panel.right.center{top:50%;transform:translateY(-15px) translateY(-50%)}.react-flow__attribution{font-size:10px;background:var(--xy-attribution-background-color, var(--xy-attribution-background-color-default));padding:2px 3px;margin:0}.react-flow__attribution a{text-decoration:none;color:#999}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;left:0;top:0}.react-flow__viewport-portal{position:absolute;width:100%;height:100%;left:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__minimap{background:var( --xy-minimap-background-color-props, var(--xy-minimap-background-color, var(--xy-minimap-background-color-default)) )}.react-flow__minimap-svg{display:block}.react-flow__minimap-mask{fill:var( --xy-minimap-mask-background-color-props, var(--xy-minimap-mask-background-color, var(--xy-minimap-mask-background-color-default)) );stroke:var( --xy-minimap-mask-stroke-color-props, var(--xy-minimap-mask-stroke-color, var(--xy-minimap-mask-stroke-color-default)) );stroke-width:var( --xy-minimap-mask-stroke-width-props, var(--xy-minimap-mask-stroke-width, var(--xy-minimap-mask-stroke-width-default)) )}.react-flow__minimap-node{fill:var( --xy-minimap-node-background-color-props, var(--xy-minimap-node-background-color, var(--xy-minimap-node-background-color-default)) );stroke:var( --xy-minimap-node-stroke-color-props, var(--xy-minimap-node-stroke-color, var(--xy-minimap-node-stroke-color-default)) );stroke-width:var( --xy-minimap-node-stroke-width-props, var(--xy-minimap-node-stroke-width, var(--xy-minimap-node-stroke-width-default)) )}.react-flow__background-pattern.dots{fill:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-dots-color-default)) )}.react-flow__background-pattern.lines{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-lines-color-default)) )}.react-flow__background-pattern.cross{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-cross-color-default)) )}.react-flow__controls{display:flex;flex-direction:column;box-shadow:var(--xy-controls-box-shadow, var(--xy-controls-box-shadow-default))}.react-flow__controls.horizontal{flex-direction:row}.react-flow__controls-button{display:flex;justify-content:center;align-items:center;height:26px;width:26px;padding:4px;border:none;background:var(--xy-controls-button-background-color, var(--xy-controls-button-background-color-default));border-bottom:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) );color:var( --xy-controls-button-color-props, var(--xy-controls-button-color, var(--xy-controls-button-color-default)) );cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px;fill:currentColor}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-input,.react-flow__node-default,.react-flow__node-output,.react-flow__node-group{padding:10px;border-radius:var(--xy-node-border-radius, var(--xy-node-border-radius-default));width:150px;font-size:12px;color:var(--xy-node-color, var(--xy-node-color-default));text-align:center;border:var(--xy-node-border, var(--xy-node-border-default));background-color:var(--xy-node-background-color, var(--xy-node-background-color-default))}.react-flow__node-input.selectable:hover,.react-flow__node-default.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:var(--xy-node-boxshadow-hover, var(--xy-node-boxshadow-hover-default))}.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:var(--xy-node-boxshadow-selected, var(--xy-node-boxshadow-selected-default))}.react-flow__node-group{background-color:var(--xy-node-group-background-color, var(--xy-node-group-background-color-default))}.react-flow__nodesselection-rect,.react-flow__selection{background:var(--xy-selection-background-color, var(--xy-selection-background-color-default));border:var(--xy-selection-border, var(--xy-selection-border-default))}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls-button:hover{background:var( --xy-controls-button-background-color-hover-props, var(--xy-controls-button-background-color-hover, var(--xy-controls-button-background-color-hover-default)) );color:var( --xy-controls-button-color-hover-props, var(--xy-controls-button-color-hover, var(--xy-controls-button-color-hover-default)) )}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__controls-button:last-child{border-bottom:none}.react-flow__controls.horizontal .react-flow__controls-button{border-bottom:none;border-right:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) )}.react-flow__controls.horizontal .react-flow__controls-button:last-child{border-right:none}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{width:5px;height:5px;border:1px solid #fff;border-radius:1px;background-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));translate:-50% -50%}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));border-width:0;border-style:solid}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.react-flow__resize-control.line.left{left:0;border-left-width:1px}.react-flow__resize-control.line.right{left:100%;border-right-width:1px}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.react-flow__resize-control.line.top{top:0;border-top-width:1px}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.react-flow__edge-textbg{fill:var(--xy-edge-label-background-color, var(--xy-edge-label-background-color-default))}.react-flow__edge-text{fill:var(--xy-edge-label-color, var(--xy-edge-label-color-default))}
|