vortx-gl 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vortx-gl.css CHANGED
@@ -1 +1 @@
1
- .lucide-icon[data-v-6aa14fad]{display:inline-block;vertical-align:middle}.radial-menu[data-v-9d75fdc7]{position:fixed;width:0;height:0;z-index:2000;pointer-events:none}.radial-center[data-v-9d75fdc7]{position:absolute;width:52px;height:52px;border-radius:50%;display:flex;align-items:center;justify-content:center;transform:translate(-50%,-50%);animation:popIn-9d75fdc7 .4s cubic-bezier(.34,1.56,.64,1);pointer-events:auto;font-size:24px;border-color:var(--vortx-primary);box-shadow:0 0 20px #00ffd533}.radial-item[data-v-9d75fdc7]{position:absolute;width:64px;height:64px;pointer-events:none;animation:itemIn-9d75fdc7 .5s cubic-bezier(.34,1.56,.64,1) backwards;z-index:2001}.radial-item-inner[data-v-9d75fdc7]{width:100%;height:100%;border-radius:50%;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer;pointer-events:auto;transition:all .3s cubic-bezier(.175,.885,.32,1.275);border:1px solid var(--vortx-border);color:var(--vortx-text);outline:none;padding:0}.radial-item-inner[data-v-9d75fdc7]:hover{background:var(--vortx-primary);color:#fff;transform:scale(1.15);border-color:#fff;box-shadow:0 0 25px #00ffd580}.radial-icon[data-v-9d75fdc7]{font-size:20px}.radial-label[data-v-9d75fdc7]{font-size:9px;text-transform:uppercase;margin-top:2px;font-weight:700;letter-spacing:.5px}@keyframes popIn-9d75fdc7{0%{transform:translate(-50%,-50%) scale(0);opacity:0}to{transform:translate(-50%,-50%) scale(1);opacity:1}}@keyframes itemIn-9d75fdc7{0%{opacity:0;transform:translate(-50%,-50%) scale(0)}to{opacity:1}}@media(max-width:768px){.radial-item[data-v-9d75fdc7]{width:72px;height:72px}.radial-icon[data-v-9d75fdc7]{font-size:24px}.radial-label[data-v-9d75fdc7]{font-size:10px}}.top-right-controls[data-v-f90ff709]{position:absolute;top:var(--vortx-space-md);right:var(--vortx-space-md);display:flex;flex-direction:column;gap:var(--vortx-space-xs);padding:var(--vortx-space-xs);border-radius:var(--vortx-radius-md);z-index:1000;transition:transform .3s cubic-bezier(.34,1.56,.64,1)}.control-btn[data-v-f90ff709]{width:44px;height:44px;display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:var(--vortx-radius-sm);transition:all .2s cubic-bezier(.4,0,.2,1);font-size:20px;background:transparent;border:none;color:var(--vortx-text);outline:none;position:relative;overflow:hidden}.control-btn[data-v-f90ff709]:hover{background:var(--vortx-border);transform:translateY(-2px)}.control-btn[data-v-f90ff709]:active{transform:scale(.9)}.stress-btn[data-v-f90ff709]{color:var(--vortx-warning)}.divider[data-v-f90ff709]{width:24px;height:1px;background:var(--vortx-border);align-self:center;margin:4px 0}@media(max-width:768px){.top-right-controls[data-v-f90ff709]{flex-direction:row;top:auto;bottom:var(--vortx-space-xl);right:50%;transform:translate(50%);gap:var(--vortx-space-sm);padding:var(--vortx-space-sm)}.divider[data-v-f90ff709]{width:1px;height:24px;margin:0 4px}.control-btn[data-v-f90ff709]{width:48px;height:48px;font-size:22px}}.layout-controls[data-v-2650a643]{position:absolute;bottom:var(--vortx-space-lg);left:50%;transform:translate(-50%);width:auto;max-width:90vw;padding:6px;border-radius:var(--vortx-radius-lg);z-index:1000;overflow:hidden}.scroll-container[data-v-2650a643]{display:flex;gap:var(--vortx-space-xs);overflow-x:auto;padding:2px;scrollbar-width:none;-ms-overflow-style:none}.scroll-container[data-v-2650a643]::-webkit-scrollbar{display:none}.layout-btn[data-v-2650a643]{padding:10px 18px;border-radius:var(--vortx-radius-md);cursor:pointer;font-size:14px;font-weight:500;transition:all .3s cubic-bezier(.4,0,.2,1);background:transparent;border:none;display:flex;align-items:center;gap:8px;color:var(--vortx-text-dim);white-space:nowrap;outline:none}.layout-btn[data-v-2650a643]:hover{background:var(--vortx-border);color:var(--vortx-text);transform:translateY(-2px)}.layout-btn.active[data-v-2650a643]{background:var(--vortx-primary);color:#fff;box-shadow:0 4px 15px var(--vortx-primary-glow);border-color:var(--vortx-primary)}.btn-icon[data-v-2650a643]{font-size:18px}@media(max-width:768px){.layout-controls[data-v-2650a643]{bottom:calc(var(--vortx-space-xl) + 80px);max-width:95vw;border-radius:var(--vortx-radius-md)}.layout-btn[data-v-2650a643]{padding:12px 20px;font-size:15px}}.property-panel[data-v-205cc0b7]{position:absolute;top:var(--vortx-space-md);left:var(--vortx-space-md);width:320px;max-height:calc(100vh - var(--vortx-space-xl) * 2);border-radius:var(--vortx-radius-lg);z-index:1100;display:flex;flex-direction:column;animation:slideIn-205cc0b7 .4s cubic-bezier(.16,1,.3,1);overflow:hidden}@keyframes slideIn-205cc0b7{0%{transform:translate(-100%);opacity:0}to{transform:translate(0);opacity:1}}.panel-header[data-v-205cc0b7]{padding:var(--vortx-space-md);border-bottom:1px solid var(--vortx-border);display:flex;justify-content:space-between;align-items:center}.panel-header h3[data-v-205cc0b7]{margin:0;font-size:16px;font-weight:600;color:var(--vortx-primary);text-transform:uppercase;letter-spacing:.5px}.close-btn[data-v-205cc0b7]{background:transparent;border:none;color:var(--vortx-text-dim);cursor:pointer;padding:4px;font-size:18px;display:flex;align-items:center;justify-content:center;transition:color .2s}.close-btn[data-v-205cc0b7]:hover{color:var(--vortx-text)}.panel-content[data-v-205cc0b7]{padding:var(--vortx-space-md);overflow-y:auto;flex:1}.prop-group[data-v-205cc0b7]{margin-bottom:var(--vortx-space-md)}.prop-row[data-v-205cc0b7]{display:grid;grid-template-columns:1fr 1fr;gap:var(--vortx-space-sm)}.prop-group label[data-v-205cc0b7]{display:block;font-size:11px;font-weight:600;color:var(--vortx-text-dim);text-transform:uppercase;margin-bottom:var(--vortx-space-xs)}.id-badge[data-v-205cc0b7]{display:inline-block;background:var(--vortx-border);padding:4px 8px;border-radius:var(--vortx-radius-sm);font-family:monospace;font-size:13px}.val-container[data-v-205cc0b7]{font-size:14px}input[data-v-205cc0b7]{width:100%;background:var(--vortx-border);border:1px solid transparent;padding:8px 12px;border-radius:var(--vortx-radius-sm);color:var(--vortx-text);font-family:monospace;font-size:14px;transition:all .2s}input[data-v-205cc0b7]:focus{outline:none;border-color:var(--vortx-primary);background:transparent}.json-prop[data-v-205cc0b7]{font-size:11px;background:#0003;padding:8px;border-radius:var(--vortx-radius-sm);margin:0;max-height:150px;overflow:auto;white-space:pre-wrap;word-break:break-all;border:1px solid var(--vortx-border)}.member-list[data-v-205cc0b7]{background:var(--vortx-border);border-radius:var(--vortx-radius-sm);padding:var(--vortx-space-xs);max-height:200px;overflow-y:auto;display:flex;flex-direction:column;gap:2px}.member-item[data-v-205cc0b7]{display:flex;justify-content:space-between;align-items:center;padding:4px 8px;font-size:12px;border-radius:4px}.member-item[data-v-205cc0b7]:hover{background:var(--vortx-border)}.remove-btn[data-v-205cc0b7]{background:#ff00001a;border:none;color:var(--vortx-danger);width:20px;height:20px;border-radius:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:10px}.prop-image[data-v-205cc0b7]{width:64px;height:64px;object-fit:contain;padding:8px;background:var(--vortx-surface);border-radius:50%;border:1px solid var(--vortx-border);margin-top:4px;box-shadow:0 2px 8px #0003}.edge-panel .panel-header h3[data-v-205cc0b7]{color:var(--vortx-secondary)}.combo-panel .panel-header h3[data-v-205cc0b7]{color:var(--vortx-success)}@media(max-width:768px){.property-panel[data-v-205cc0b7]{inset:auto 0 0;width:100%;height:50vh;border-radius:var(--vortx-radius-lg) var(--vortx-radius-lg) 0 0;animation:vortxSlideUp .4s cubic-bezier(.16,1,.3,1)}}.search-wrapper[data-v-283de02c]{position:absolute;top:var(--vortx-space-md);left:50%;transform:translate(-50%);z-index:1200;transition:all .3s ease}.search-container[data-v-283de02c]{width:240px;max-width:90vw;border-radius:var(--vortx-radius-full);transition:all .3s cubic-bezier(.4,0,.2,1);padding:4px}.search-container.expanded[data-v-283de02c]{width:320px;border-radius:var(--vortx-radius-md)}.search-input-wrapper[data-v-283de02c]{display:flex;align-items:center;gap:8px;padding:4px 12px}.search-icon[data-v-283de02c]{opacity:.6}input[data-v-283de02c]{flex:1;background:transparent;border:none;border-radius:999px;padding:8px 4px;font-size:14px;color:var(--vortx-text);outline:none}.clear-btn[data-v-283de02c]{cursor:pointer;opacity:.5;padding:4px;display:flex;align-items:center}.results-panel[data-v-283de02c]{margin-top:4px;border-top:1px solid var(--vortx-border);padding:4px;max-height:250px;overflow-y:auto}.result-item[data-v-283de02c]{display:flex;align-items:center;gap:12px;padding:10px 12px;cursor:pointer;border-radius:var(--vortx-radius-sm);transition:background .2s}.result-item[data-v-283de02c]:hover{background:var(--vortx-border)}.node-icon[data-v-283de02c]{color:var(--vortx-primary)}.node-info[data-v-283de02c]{display:flex;flex-direction:column}.node-label[data-v-283de02c]{font-size:13px;font-weight:500}.node-id[data-v-283de02c]{font-size:11px;opacity:.6}.no-results[data-v-283de02c]{padding:12px;text-align:center;font-size:13px;color:var(--vortx-text-dim);border-top:1px solid var(--vortx-border)}.search-wrapper.is-mobile[data-v-283de02c]{top:auto;bottom:var(--vortx-space-md);left:var(--vortx-space-md);transform:none}.is-mobile .search-container[data-v-283de02c]{width:52px;height:52px;overflow:hidden;padding:0;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 20px #0000004d;border-color:var(--vortx-primary)}.is-mobile .search-input-wrapper[data-v-283de02c]{padding:0;width:100%;height:100%;justify-content:center}.is-mobile .search-icon[data-v-283de02c]{margin:0}.is-mobile input[data-v-283de02c]{display:none}.is-mobile .search-container.expanded[data-v-283de02c]{position:fixed;bottom:0;left:0;width:100vw;height:auto;max-width:none;border-radius:var(--vortx-radius-lg) var(--vortx-radius-lg) 0 0;transform:none;padding:var(--vortx-space-md);display:block}.is-mobile .search-wrapper.mobile-expanded[data-v-283de02c]{left:0;bottom:0;width:100%}.is-mobile .search-container.expanded .search-input-wrapper[data-v-283de02c]{height:auto;padding:4px 0;margin-bottom:var(--vortx-space-md);border-bottom:1px solid var(--vortx-border)}.is-mobile .search-container.expanded input[data-v-283de02c]{display:block;font-size:16px}.is-mobile .search-container.expanded .results-panel[data-v-283de02c]{max-height:60vh}.mobile-backdrop[data-v-283de02c]{position:fixed;inset:0;background:#00000080;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:-1}.container[data-v-d6f5f92c]{position:relative;width:100%;height:100%;transition:background-color .4s cubic-bezier(.4,0,.2,1);background:var(--vortx-bg);color:var(--vortx-text);overflow:hidden}.main-canvas[data-v-d6f5f92c],.overlay-canvas[data-v-d6f5f92c]{position:absolute;top:0;left:0;width:100%;height:100%;display:block}.overlay-canvas[data-v-d6f5f92c]{pointer-events:none}.mobile-menu[data-v-d6f5f92c]{position:fixed;bottom:var(--vortx-space-md);left:50%;transform:translate(-50%);display:flex;align-items:center;padding:6px;border-radius:var(--vortx-radius-full);z-index:1000;gap:4px}.menu-btn[data-v-d6f5f92c]{background:transparent;border:none;color:var(--vortx-text-dim);display:flex;flex-direction:column;align-items:center;gap:4px;padding:8px 16px;border-radius:var(--vortx-radius-full);cursor:pointer;transition:all .2s;min-width:70px}.menu-btn span[data-v-d6f5f92c]{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.menu-btn.active[data-v-d6f5f92c]{background:var(--vortx-primary);color:#fff;box-shadow:0 4px 12px var(--vortx-primary-glow)}.menu-divider[data-v-d6f5f92c]{width:1px;height:24px;background:var(--vortx-border);margin:0 4px}.drawer-overlay[data-v-d6f5f92c]{position:fixed;inset:0;background:#0006;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1300}.mobile-drawer[data-v-d6f5f92c]{position:absolute;bottom:0;left:0;width:100%;border-radius:var(--vortx-radius-lg) var(--vortx-radius-lg) 0 0;padding:var(--vortx-space-md);padding-bottom:env(safe-area-inset-bottom,var(--vortx-space-lg));animation:vortxSlideUp .3s cubic-bezier(.16,1,.3,1)}.drawer-handle[data-v-d6f5f92c]{width:40px;height:4px;background:var(--vortx-border);border-radius:2px;margin:0 auto var(--vortx-space-md)}.drawer-header[data-v-d6f5f92c]{display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--vortx-space-md)}.drawer-header h3[data-v-d6f5f92c]{margin:0;font-size:16px;font-weight:700}.drawer-close[data-v-d6f5f92c]{background:transparent;border:none;color:var(--vortx-text-dim);cursor:pointer}.drawer-content[data-v-d6f5f92c]{padding:var(--vortx-space-sm) 0}.drawer-content[data-v-d6f5f92c] .layout-controls,.drawer-content[data-v-d6f5f92c] .top-right-controls{position:static;transform:none;width:100%;max-width:none;padding:0;background:transparent;box-shadow:none;border:none;flex-direction:row;flex-wrap:wrap;justify-content:center}.drawer-content[data-v-d6f5f92c] .divider{display:none}.help-trigger[data-v-d6f5f92c]{position:absolute;bottom:var(--vortx-space-md);right:var(--vortx-space-md);width:32px;height:32px;background:var(--vortx-surface);border:1px solid var(--vortx-border);border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:14px;font-weight:700;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);z-index:1000;transition:all .2s;color:var(--vortx-text-dim)}.help-trigger[data-v-d6f5f92c]:hover{background:var(--vortx-primary);color:#fff;border-color:#fff;transform:scale(1.1)}.help-modal-overlay[data-v-d6f5f92c]{position:fixed;inset:0;background:#0006;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:2000;display:flex;align-items:center;justify-content:center}.help-modal[data-v-d6f5f92c]{width:340px;border-radius:var(--vortx-radius-lg);overflow:hidden;animation:vortxScaleIn .3s cubic-bezier(.34,1.56,.64,1)}.help-header[data-v-d6f5f92c]{padding:var(--vortx-space-md);border-bottom:1px solid var(--vortx-border);display:flex;justify-content:space-between;align-items:center}.help-header h3[data-v-d6f5f92c]{margin:0;font-size:16px}.shortcut-row[data-v-d6f5f92c]{display:flex;justify-content:space-between;align-items:center;padding:12px var(--vortx-space-md);border-bottom:1px solid var(--vortx-border)}.shortcut-row[data-v-d6f5f92c]:last-child{border-bottom:none}.key-badge[data-v-d6f5f92c]{background:var(--vortx-border);padding:4px 10px;border-radius:var(--vortx-radius-sm);font-family:monospace;font-size:12px}.action-desc[data-v-d6f5f92c]{font-size:13px;color:var(--vortx-text-dim)}.close-btn[data-v-d6f5f92c]{background:transparent;border:none;color:var(--vortx-text-dim);font-size:20px;cursor:pointer}@media(max-width:768px){.help-trigger[data-v-d6f5f92c]{display:none}}
1
+ .vortx-gl-root{--vortx-primary: hsl(190, 100%, 50%);--vortx-primary-glow: hsla(190, 100%, 50%, .3);--vortx-primary-hover: hsl(190, 100%, 40%);--vortx-secondary: hsl(260, 100%, 65%);--vortx-secondary-glow: hsla(260, 100%, 65%, .3);--vortx-success: hsl(145, 80%, 45%);--vortx-warning: hsl(35, 100%, 55%);--vortx-danger: hsl(0, 85%, 60%);--vortx-bg-dark: hsl(230, 20%, 5%);--vortx-surface-dark: hsla(230, 15%, 15%, .6);--vortx-border-dark: hsla(0, 0%, 100%, .12);--vortx-text-dark: hsl(0, 0%, 98%);--vortx-text-dim-dark: hsl(230, 10%, 75%);--vortx-bg-light: hsl(220, 20%, 97%);--vortx-surface-light: hsla(0, 0%, 100%, .7);--vortx-border-light: hsla(230, 20%, 0%, .08);--vortx-text-light: hsl(230, 20%, 10%);--vortx-text-dim-light: hsl(230, 15%, 45%);--vortx-bg: var(--vortx-bg-dark);--vortx-surface: var(--vortx-surface-dark);--vortx-border: var(--vortx-border-dark);--vortx-text: var(--vortx-text-dark);--vortx-text-dim: var(--vortx-text-dim-dark);--vortx-glass-blur: 24px;--vortx-glass-border: 1px solid var(--vortx-border);--vortx-glass-shadow: 0 4px 12px 0 rgba(0, 0, 0, .4), 0 1px 3px 0 rgba(0, 0, 0, .2);--vortx-radius-sm: 8px;--vortx-radius-md: 12px;--vortx-radius-lg: 24px;--vortx-radius-full: 9999px;--vortx-space-xs: 4px;--vortx-space-sm: 8px;--vortx-space-md: 16px;--vortx-space-lg: 32px;--vortx-space-xl: 48px;font-family:Outfit,Inter,system-ui,-apple-system,sans-serif;line-height:1.6;font-weight:400;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.vortx-gl-root.light{--vortx-bg: var(--vortx-bg-light);--vortx-surface: var(--vortx-surface-light);--vortx-border: var(--vortx-border-light);--vortx-text: var(--vortx-text-light);--vortx-text-dim: var(--vortx-text-dim-light);--vortx-glass-shadow: 0 4px 12px 0 rgba(0, 0, 0, .1), 0 1px 3px 0 rgba(0, 0, 0, .05)}.vortx-gl-root *{box-sizing:border-box;-webkit-tap-highlight-color:transparent}.vortx-gl-root .glass{background:var(--vortx-surface);backdrop-filter:blur(var(--vortx-glass-blur));-webkit-backdrop-filter:blur(var(--vortx-glass-blur));border:var(--vortx-glass-border);box-shadow:var(--vortx-glass-shadow);color:var(--vortx-text)}.vortx-gl-root .glass-interactive{background:var(--vortx-surface);backdrop-filter:blur(var(--vortx-glass-blur));-webkit-backdrop-filter:blur(var(--vortx-glass-blur));border:var(--vortx-glass-border);box-shadow:var(--vortx-glass-shadow);transition:all .3s cubic-bezier(.4,0,.2,1);color:var(--vortx-text)}.vortx-gl-root .glass-interactive:hover{background:#3d425c4d;border-color:#00d4ff66;transform:translateY(-2px);box-shadow:0 8px 24px #00000080}.vortx-gl-root.light .glass-interactive:hover{background:#fffc;border-color:#00d4ff66;box-shadow:0 8px 24px #0000001a}.vortx-gl-root ::-webkit-scrollbar{width:8px;height:8px}.vortx-gl-root ::-webkit-scrollbar-track{background:transparent}.vortx-gl-root ::-webkit-scrollbar-thumb{background:var(--vortx-border);border-radius:var(--vortx-radius-full)}.vortx-gl-root ::-webkit-scrollbar-thumb:hover{background:var(--vortx-text-dim)}@keyframes vortxFadeIn{0%{opacity:0}to{opacity:1}}@keyframes vortxSlideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes vortxScaleIn{0%{transform:scale(.95);opacity:0}to{transform:scale(1);opacity:1}}@media(max-width:768px){.vortx-gl-root{--vortx-space-md: 12px;--vortx-space-lg: 24px;--vortx-glass-blur: 16px}}.lucide-icon[data-v-6aa14fad]{display:inline-block;vertical-align:middle}.radial-menu[data-v-9d75fdc7]{position:fixed;width:0;height:0;z-index:2000;pointer-events:none}.radial-center[data-v-9d75fdc7]{position:absolute;width:52px;height:52px;border-radius:50%;display:flex;align-items:center;justify-content:center;transform:translate(-50%,-50%);animation:popIn-9d75fdc7 .4s cubic-bezier(.34,1.56,.64,1);pointer-events:auto;font-size:24px;border-color:var(--vortx-primary);box-shadow:0 0 20px #00ffd533}.radial-item[data-v-9d75fdc7]{position:absolute;width:64px;height:64px;pointer-events:none;animation:itemIn-9d75fdc7 .5s cubic-bezier(.34,1.56,.64,1) backwards;z-index:2001}.radial-item-inner[data-v-9d75fdc7]{width:100%;height:100%;border-radius:50%;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer;pointer-events:auto;transition:all .3s cubic-bezier(.175,.885,.32,1.275);border:1px solid var(--vortx-border);color:var(--vortx-text);outline:none;padding:0}.radial-item-inner[data-v-9d75fdc7]:hover{background:var(--vortx-primary);color:#fff;transform:scale(1.15);border-color:#fff;box-shadow:0 0 25px #00ffd580}.radial-icon[data-v-9d75fdc7]{font-size:20px}.radial-label[data-v-9d75fdc7]{font-size:9px;text-transform:uppercase;margin-top:2px;font-weight:700;letter-spacing:.5px}@keyframes popIn-9d75fdc7{0%{transform:translate(-50%,-50%) scale(0);opacity:0}to{transform:translate(-50%,-50%) scale(1);opacity:1}}@keyframes itemIn-9d75fdc7{0%{opacity:0;transform:translate(-50%,-50%) scale(0)}to{opacity:1}}@media(max-width:768px){.radial-item[data-v-9d75fdc7]{width:72px;height:72px}.radial-icon[data-v-9d75fdc7]{font-size:24px}.radial-label[data-v-9d75fdc7]{font-size:10px}}.top-right-controls[data-v-f90ff709]{position:absolute;top:var(--vortx-space-md);right:var(--vortx-space-md);display:flex;flex-direction:column;gap:var(--vortx-space-xs);padding:var(--vortx-space-xs);border-radius:var(--vortx-radius-md);z-index:1000;transition:transform .3s cubic-bezier(.34,1.56,.64,1)}.control-btn[data-v-f90ff709]{width:44px;height:44px;display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:var(--vortx-radius-sm);transition:all .2s cubic-bezier(.4,0,.2,1);font-size:20px;background:transparent;border:none;color:var(--vortx-text);outline:none;position:relative;overflow:hidden}.control-btn[data-v-f90ff709]:hover{background:var(--vortx-border);transform:translateY(-2px)}.control-btn[data-v-f90ff709]:active{transform:scale(.9)}.stress-btn[data-v-f90ff709]{color:var(--vortx-warning)}.divider[data-v-f90ff709]{width:24px;height:1px;background:var(--vortx-border);align-self:center;margin:4px 0}@media(max-width:768px){.top-right-controls[data-v-f90ff709]{flex-direction:row;top:auto;bottom:var(--vortx-space-xl);right:50%;transform:translate(50%);gap:var(--vortx-space-sm);padding:var(--vortx-space-sm)}.divider[data-v-f90ff709]{width:1px;height:24px;margin:0 4px}.control-btn[data-v-f90ff709]{width:48px;height:48px;font-size:22px}}.layout-controls[data-v-2650a643]{position:absolute;bottom:var(--vortx-space-lg);left:50%;transform:translate(-50%);width:auto;max-width:90vw;padding:6px;border-radius:var(--vortx-radius-lg);z-index:1000;overflow:hidden}.scroll-container[data-v-2650a643]{display:flex;gap:var(--vortx-space-xs);overflow-x:auto;padding:2px;scrollbar-width:none;-ms-overflow-style:none}.scroll-container[data-v-2650a643]::-webkit-scrollbar{display:none}.layout-btn[data-v-2650a643]{padding:10px 18px;border-radius:var(--vortx-radius-md);cursor:pointer;font-size:14px;font-weight:500;transition:all .3s cubic-bezier(.4,0,.2,1);background:transparent;border:none;display:flex;align-items:center;gap:8px;color:var(--vortx-text-dim);white-space:nowrap;outline:none}.layout-btn[data-v-2650a643]:hover{background:var(--vortx-border);color:var(--vortx-text);transform:translateY(-2px)}.layout-btn.active[data-v-2650a643]{background:var(--vortx-primary);color:#fff;box-shadow:0 4px 15px var(--vortx-primary-glow);border-color:var(--vortx-primary)}.btn-icon[data-v-2650a643]{font-size:18px}@media(max-width:768px){.layout-controls[data-v-2650a643]{bottom:calc(var(--vortx-space-xl) + 80px);max-width:95vw;border-radius:var(--vortx-radius-md)}.layout-btn[data-v-2650a643]{padding:12px 20px;font-size:15px}}.property-panel[data-v-205cc0b7]{position:absolute;top:var(--vortx-space-md);left:var(--vortx-space-md);width:320px;max-height:calc(100vh - var(--vortx-space-xl) * 2);border-radius:var(--vortx-radius-lg);z-index:1100;display:flex;flex-direction:column;animation:slideIn-205cc0b7 .4s cubic-bezier(.16,1,.3,1);overflow:hidden}@keyframes slideIn-205cc0b7{0%{transform:translate(-100%);opacity:0}to{transform:translate(0);opacity:1}}.panel-header[data-v-205cc0b7]{padding:var(--vortx-space-md);border-bottom:1px solid var(--vortx-border);display:flex;justify-content:space-between;align-items:center}.panel-header h3[data-v-205cc0b7]{margin:0;font-size:16px;font-weight:600;color:var(--vortx-primary);text-transform:uppercase;letter-spacing:.5px}.close-btn[data-v-205cc0b7]{background:transparent;border:none;color:var(--vortx-text-dim);cursor:pointer;padding:4px;font-size:18px;display:flex;align-items:center;justify-content:center;transition:color .2s}.close-btn[data-v-205cc0b7]:hover{color:var(--vortx-text)}.panel-content[data-v-205cc0b7]{padding:var(--vortx-space-md);overflow-y:auto;flex:1}.prop-group[data-v-205cc0b7]{margin-bottom:var(--vortx-space-md)}.prop-row[data-v-205cc0b7]{display:grid;grid-template-columns:1fr 1fr;gap:var(--vortx-space-sm)}.prop-group label[data-v-205cc0b7]{display:block;font-size:11px;font-weight:600;color:var(--vortx-text-dim);text-transform:uppercase;margin-bottom:var(--vortx-space-xs)}.id-badge[data-v-205cc0b7]{display:inline-block;background:var(--vortx-border);padding:4px 8px;border-radius:var(--vortx-radius-sm);font-family:monospace;font-size:13px}.val-container[data-v-205cc0b7]{font-size:14px}input[data-v-205cc0b7]{width:100%;background:var(--vortx-border);border:1px solid transparent;padding:8px 12px;border-radius:var(--vortx-radius-sm);color:var(--vortx-text);font-family:monospace;font-size:14px;transition:all .2s}input[data-v-205cc0b7]:focus{outline:none;border-color:var(--vortx-primary);background:transparent}.json-prop[data-v-205cc0b7]{font-size:11px;background:#0003;padding:8px;border-radius:var(--vortx-radius-sm);margin:0;max-height:150px;overflow:auto;white-space:pre-wrap;word-break:break-all;border:1px solid var(--vortx-border)}.member-list[data-v-205cc0b7]{background:var(--vortx-border);border-radius:var(--vortx-radius-sm);padding:var(--vortx-space-xs);max-height:200px;overflow-y:auto;display:flex;flex-direction:column;gap:2px}.member-item[data-v-205cc0b7]{display:flex;justify-content:space-between;align-items:center;padding:4px 8px;font-size:12px;border-radius:4px}.member-item[data-v-205cc0b7]:hover{background:var(--vortx-border)}.remove-btn[data-v-205cc0b7]{background:#ff00001a;border:none;color:var(--vortx-danger);width:20px;height:20px;border-radius:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:10px}.prop-image[data-v-205cc0b7]{width:64px;height:64px;object-fit:contain;padding:8px;background:var(--vortx-surface);border-radius:50%;border:1px solid var(--vortx-border);margin-top:4px;box-shadow:0 2px 8px #0003}.edge-panel .panel-header h3[data-v-205cc0b7]{color:var(--vortx-secondary)}.combo-panel .panel-header h3[data-v-205cc0b7]{color:var(--vortx-success)}@media(max-width:768px){.property-panel[data-v-205cc0b7]{inset:auto 0 0;width:100%;height:50vh;border-radius:var(--vortx-radius-lg) var(--vortx-radius-lg) 0 0;animation:vortxSlideUp .4s cubic-bezier(.16,1,.3,1)}}.search-wrapper[data-v-283de02c]{position:absolute;top:var(--vortx-space-md);left:50%;transform:translate(-50%);z-index:1200;transition:all .3s ease}.search-container[data-v-283de02c]{width:240px;max-width:90vw;border-radius:var(--vortx-radius-full);transition:all .3s cubic-bezier(.4,0,.2,1);padding:4px}.search-container.expanded[data-v-283de02c]{width:320px;border-radius:var(--vortx-radius-md)}.search-input-wrapper[data-v-283de02c]{display:flex;align-items:center;gap:8px;padding:4px 12px}.search-icon[data-v-283de02c]{opacity:.6}input[data-v-283de02c]{flex:1;background:transparent;border:none;border-radius:999px;padding:8px 4px;font-size:14px;color:var(--vortx-text);outline:none}.clear-btn[data-v-283de02c]{cursor:pointer;opacity:.5;padding:4px;display:flex;align-items:center}.results-panel[data-v-283de02c]{margin-top:4px;border-top:1px solid var(--vortx-border);padding:4px;max-height:250px;overflow-y:auto}.result-item[data-v-283de02c]{display:flex;align-items:center;gap:12px;padding:10px 12px;cursor:pointer;border-radius:var(--vortx-radius-sm);transition:background .2s}.result-item[data-v-283de02c]:hover{background:var(--vortx-border)}.node-icon[data-v-283de02c]{color:var(--vortx-primary)}.node-info[data-v-283de02c]{display:flex;flex-direction:column}.node-label[data-v-283de02c]{font-size:13px;font-weight:500}.node-id[data-v-283de02c]{font-size:11px;opacity:.6}.no-results[data-v-283de02c]{padding:12px;text-align:center;font-size:13px;color:var(--vortx-text-dim);border-top:1px solid var(--vortx-border)}.search-wrapper.is-mobile[data-v-283de02c]{top:auto;bottom:var(--vortx-space-md);left:var(--vortx-space-md);transform:none}.is-mobile .search-container[data-v-283de02c]{width:52px;height:52px;overflow:hidden;padding:0;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 20px #0000004d;border-color:var(--vortx-primary)}.is-mobile .search-input-wrapper[data-v-283de02c]{padding:0;width:100%;height:100%;justify-content:center}.is-mobile .search-icon[data-v-283de02c]{margin:0}.is-mobile input[data-v-283de02c]{display:none}.is-mobile .search-container.expanded[data-v-283de02c]{position:fixed;bottom:0;left:0;width:100vw;height:auto;max-width:none;border-radius:var(--vortx-radius-lg) var(--vortx-radius-lg) 0 0;transform:none;padding:var(--vortx-space-md);display:block}.is-mobile .search-wrapper.mobile-expanded[data-v-283de02c]{left:0;bottom:0;width:100%}.is-mobile .search-container.expanded .search-input-wrapper[data-v-283de02c]{height:auto;padding:4px 0;margin-bottom:var(--vortx-space-md);border-bottom:1px solid var(--vortx-border)}.is-mobile .search-container.expanded input[data-v-283de02c]{display:block;font-size:16px}.is-mobile .search-container.expanded .results-panel[data-v-283de02c]{max-height:60vh}.mobile-backdrop[data-v-283de02c]{position:fixed;inset:0;background:#00000080;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:-1}.container[data-v-d6f5f92c]{position:relative;width:100%;height:100%;transition:background-color .4s cubic-bezier(.4,0,.2,1);background:var(--vortx-bg);color:var(--vortx-text);overflow:hidden}.main-canvas[data-v-d6f5f92c],.overlay-canvas[data-v-d6f5f92c]{position:absolute;top:0;left:0;width:100%;height:100%;display:block}.overlay-canvas[data-v-d6f5f92c]{pointer-events:none}.mobile-menu[data-v-d6f5f92c]{position:fixed;bottom:var(--vortx-space-md);left:50%;transform:translate(-50%);display:flex;align-items:center;padding:6px;border-radius:var(--vortx-radius-full);z-index:1000;gap:4px}.menu-btn[data-v-d6f5f92c]{background:transparent;border:none;color:var(--vortx-text-dim);display:flex;flex-direction:column;align-items:center;gap:4px;padding:8px 16px;border-radius:var(--vortx-radius-full);cursor:pointer;transition:all .2s;min-width:70px}.menu-btn span[data-v-d6f5f92c]{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.menu-btn.active[data-v-d6f5f92c]{background:var(--vortx-primary);color:#fff;box-shadow:0 4px 12px var(--vortx-primary-glow)}.menu-divider[data-v-d6f5f92c]{width:1px;height:24px;background:var(--vortx-border);margin:0 4px}.drawer-overlay[data-v-d6f5f92c]{position:fixed;inset:0;background:#0006;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1300}.mobile-drawer[data-v-d6f5f92c]{position:absolute;bottom:0;left:0;width:100%;border-radius:var(--vortx-radius-lg) var(--vortx-radius-lg) 0 0;padding:var(--vortx-space-md);padding-bottom:env(safe-area-inset-bottom,var(--vortx-space-lg));animation:vortxSlideUp .3s cubic-bezier(.16,1,.3,1)}.drawer-handle[data-v-d6f5f92c]{width:40px;height:4px;background:var(--vortx-border);border-radius:2px;margin:0 auto var(--vortx-space-md)}.drawer-header[data-v-d6f5f92c]{display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--vortx-space-md)}.drawer-header h3[data-v-d6f5f92c]{margin:0;font-size:16px;font-weight:700}.drawer-close[data-v-d6f5f92c]{background:transparent;border:none;color:var(--vortx-text-dim);cursor:pointer}.drawer-content[data-v-d6f5f92c]{padding:var(--vortx-space-sm) 0}.drawer-content[data-v-d6f5f92c] .layout-controls,.drawer-content[data-v-d6f5f92c] .top-right-controls{position:static;transform:none;width:100%;max-width:none;padding:0;background:transparent;box-shadow:none;border:none;flex-direction:row;flex-wrap:wrap;justify-content:center}.drawer-content[data-v-d6f5f92c] .divider{display:none}.help-trigger[data-v-d6f5f92c]{position:absolute;bottom:var(--vortx-space-md);right:var(--vortx-space-md);width:32px;height:32px;background:var(--vortx-surface);border:1px solid var(--vortx-border);border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:14px;font-weight:700;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);z-index:1000;transition:all .2s;color:var(--vortx-text-dim)}.help-trigger[data-v-d6f5f92c]:hover{background:var(--vortx-primary);color:#fff;border-color:#fff;transform:scale(1.1)}.help-modal-overlay[data-v-d6f5f92c]{position:fixed;inset:0;background:#0006;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:2000;display:flex;align-items:center;justify-content:center}.help-modal[data-v-d6f5f92c]{width:340px;border-radius:var(--vortx-radius-lg);overflow:hidden;animation:vortxScaleIn .3s cubic-bezier(.34,1.56,.64,1)}.help-header[data-v-d6f5f92c]{padding:var(--vortx-space-md);border-bottom:1px solid var(--vortx-border);display:flex;justify-content:space-between;align-items:center}.help-header h3[data-v-d6f5f92c]{margin:0;font-size:16px}.shortcut-row[data-v-d6f5f92c]{display:flex;justify-content:space-between;align-items:center;padding:12px var(--vortx-space-md);border-bottom:1px solid var(--vortx-border)}.shortcut-row[data-v-d6f5f92c]:last-child{border-bottom:none}.key-badge[data-v-d6f5f92c]{background:var(--vortx-border);padding:4px 10px;border-radius:var(--vortx-radius-sm);font-family:monospace;font-size:12px}.action-desc[data-v-d6f5f92c]{font-size:13px;color:var(--vortx-text-dim)}.close-btn[data-v-d6f5f92c]{background:transparent;border:none;color:var(--vortx-text-dim);font-size:20px;cursor:pointer}@media(max-width:768px){.help-trigger[data-v-d6f5f92c]{display:none}}
@@ -0,0 +1 @@
1
+ .lucide-icon[data-v-6aa14fad]{display:inline-block;vertical-align:middle}.radial-menu[data-v-a2a68595]{position:fixed;width:0;height:0;z-index:2000;pointer-events:none}.radial-center[data-v-a2a68595]{position:absolute;width:52px;height:52px;border-radius:50%;display:flex;align-items:center;justify-content:center;transform:translate(-50%,-50%);animation:popIn-a2a68595 .4s cubic-bezier(.34,1.56,.64,1);pointer-events:auto;font-size:24px;border-color:var(--primary);box-shadow:0 0 20px #00ffd533}.radial-item[data-v-a2a68595]{position:absolute;width:64px;height:64px;pointer-events:none;animation:itemIn-a2a68595 .5s cubic-bezier(.34,1.56,.64,1) backwards;z-index:2001}.radial-item-inner[data-v-a2a68595]{width:100%;height:100%;border-radius:50%;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer;pointer-events:auto;transition:all .3s cubic-bezier(.175,.885,.32,1.275);border:1px solid var(--border);color:var(--text);outline:none;padding:0}.radial-item-inner[data-v-a2a68595]:hover{background:var(--primary);color:#fff;transform:scale(1.15);border-color:#fff;box-shadow:0 0 25px #00ffd580}.radial-icon[data-v-a2a68595]{font-size:20px}.radial-label[data-v-a2a68595]{font-size:9px;text-transform:uppercase;margin-top:2px;font-weight:700;letter-spacing:.5px}@keyframes popIn-a2a68595{0%{transform:translate(-50%,-50%) scale(0);opacity:0}to{transform:translate(-50%,-50%) scale(1);opacity:1}}@keyframes itemIn-a2a68595{0%{opacity:0;transform:translate(-50%,-50%) scale(0)}to{opacity:1}}@media(max-width:768px){.radial-item[data-v-a2a68595]{width:72px;height:72px}.radial-icon[data-v-a2a68595]{font-size:24px}.radial-label[data-v-a2a68595]{font-size:10px}}.top-right-controls[data-v-4a9f463d]{position:absolute;top:var(--space-md);right:var(--space-md);display:flex;flex-direction:column;gap:var(--space-xs);padding:var(--space-xs);border-radius:var(--radius-md);z-index:1000;transition:transform .3s cubic-bezier(.34,1.56,.64,1)}.control-btn[data-v-4a9f463d]{width:44px;height:44px;display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:var(--radius-sm);transition:all .2s cubic-bezier(.4,0,.2,1);font-size:20px;background:transparent;border:none;color:var(--text);outline:none;position:relative;overflow:hidden}.control-btn[data-v-4a9f463d]:hover{background:var(--border);transform:translateY(-2px)}.control-btn[data-v-4a9f463d]:active{transform:scale(.9)}.stress-btn[data-v-4a9f463d]{color:var(--warning)}.divider[data-v-4a9f463d]{width:24px;height:1px;background:var(--border);align-self:center;margin:4px 0}@media(max-width:768px){.top-right-controls[data-v-4a9f463d]{flex-direction:row;top:auto;bottom:var(--space-xl);right:50%;transform:translate(50%);gap:var(--space-sm);padding:var(--space-sm)}.divider[data-v-4a9f463d]{width:1px;height:24px;margin:0 4px}.control-btn[data-v-4a9f463d]{width:48px;height:48px;font-size:22px}}.layout-controls[data-v-ff660e6a]{position:absolute;bottom:var(--space-lg);left:50%;transform:translate(-50%);width:auto;max-width:90vw;padding:6px;border-radius:var(--radius-lg);z-index:1000;overflow:hidden}.scroll-container[data-v-ff660e6a]{display:flex;gap:var(--space-xs);overflow-x:auto;padding:2px;scrollbar-width:none;-ms-overflow-style:none}.scroll-container[data-v-ff660e6a]::-webkit-scrollbar{display:none}.layout-btn[data-v-ff660e6a]{padding:10px 18px;border-radius:var(--radius-md);cursor:pointer;font-size:14px;font-weight:500;transition:all .3s cubic-bezier(.4,0,.2,1);background:transparent;border:none;display:flex;align-items:center;gap:8px;color:var(--text-dim);white-space:nowrap;outline:none}.layout-btn[data-v-ff660e6a]:hover{background:var(--border);color:var(--text);transform:translateY(-2px)}.layout-btn.active[data-v-ff660e6a]{background:var(--primary);color:#fff;box-shadow:0 4px 15px var(--primary-glow);border-color:var(--primary)}.btn-icon[data-v-ff660e6a]{font-size:18px}@media(max-width:768px){.layout-controls[data-v-ff660e6a]{bottom:calc(var(--space-xl) + 80px);max-width:95vw;border-radius:var(--radius-md)}.layout-btn[data-v-ff660e6a]{padding:12px 20px;font-size:15px}}.property-panel[data-v-7c0e24e3]{position:absolute;top:var(--space-md);left:var(--space-md);width:320px;max-height:calc(100vh - var(--space-xl) * 2);border-radius:var(--radius-lg);z-index:1100;display:flex;flex-direction:column;animation:slideIn-7c0e24e3 .4s cubic-bezier(.16,1,.3,1);overflow:hidden}@keyframes slideIn-7c0e24e3{0%{transform:translate(-100%);opacity:0}to{transform:translate(0);opacity:1}}.panel-header[data-v-7c0e24e3]{padding:var(--space-md);border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center}.panel-header h3[data-v-7c0e24e3]{margin:0;font-size:16px;font-weight:600;color:var(--primary);text-transform:uppercase;letter-spacing:.5px}.close-btn[data-v-7c0e24e3]{background:transparent;border:none;color:var(--text-dim);cursor:pointer;padding:4px;font-size:18px;display:flex;align-items:center;justify-content:center;transition:color .2s}.close-btn[data-v-7c0e24e3]:hover{color:var(--text)}.panel-content[data-v-7c0e24e3]{padding:var(--space-md);overflow-y:auto;flex:1}.prop-group[data-v-7c0e24e3]{margin-bottom:var(--space-md)}.prop-row[data-v-7c0e24e3]{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-sm)}.prop-group label[data-v-7c0e24e3]{display:block;font-size:11px;font-weight:600;color:var(--text-dim);text-transform:uppercase;margin-bottom:var(--space-xs)}.id-badge[data-v-7c0e24e3]{display:inline-block;background:var(--border);padding:4px 8px;border-radius:var(--radius-sm);font-family:monospace;font-size:13px}.val-container[data-v-7c0e24e3]{font-size:14px}input[data-v-7c0e24e3]{width:100%;background:var(--border);border:1px solid transparent;padding:8px 12px;border-radius:var(--radius-sm);color:var(--text);font-family:monospace;font-size:14px;transition:all .2s}input[data-v-7c0e24e3]:focus{outline:none;border-color:var(--primary);background:transparent}.json-prop[data-v-7c0e24e3]{font-size:11px;background:#0003;padding:8px;border-radius:var(--radius-sm);margin:0;max-height:150px;overflow:auto;white-space:pre-wrap;word-break:break-all;border:1px solid var(--border)}.member-list[data-v-7c0e24e3]{background:var(--border);border-radius:var(--radius-sm);padding:var(--space-xs);max-height:200px;overflow-y:auto;display:flex;flex-direction:column;gap:2px}.member-item[data-v-7c0e24e3]{display:flex;justify-content:space-between;align-items:center;padding:4px 8px;font-size:12px;border-radius:4px}.member-item[data-v-7c0e24e3]:hover{background:var(--border)}.remove-btn[data-v-7c0e24e3]{background:#ff00001a;border:none;color:var(--danger);width:20px;height:20px;border-radius:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:10px}.prop-image[data-v-7c0e24e3]{width:64px;height:64px;object-fit:contain;padding:8px;background:var(--surface);border-radius:50%;border:1px solid var(--border);margin-top:4px;box-shadow:0 2px 8px #0003}.edge-panel .panel-header h3[data-v-7c0e24e3]{color:var(--secondary)}.combo-panel .panel-header h3[data-v-7c0e24e3]{color:var(--success)}@media(max-width:768px){.property-panel[data-v-7c0e24e3]{inset:auto 0 0;width:100%;height:50vh;border-radius:var(--radius-lg) var(--radius-lg) 0 0;animation:slideUp-7c0e24e3 .4s cubic-bezier(.16,1,.3,1)}@keyframes slideUp-7c0e24e3{0%{transform:translateY(100%)}to{transform:translateY(0)}}}.search-wrapper[data-v-3fda8a90]{position:absolute;top:var(--space-md);left:50%;transform:translate(-50%);z-index:1200;transition:all .3s ease}.search-container[data-v-3fda8a90]{width:240px;max-width:90vw;border-radius:var(--radius-full);transition:all .3s cubic-bezier(.4,0,.2,1);padding:4px}.search-container.expanded[data-v-3fda8a90]{width:320px;border-radius:var(--radius-md)}.search-input-wrapper[data-v-3fda8a90]{display:flex;align-items:center;gap:8px;padding:4px 12px}.search-icon[data-v-3fda8a90]{opacity:.6}input[data-v-3fda8a90]{flex:1;background:transparent;border:none;border-radius:999px;padding:8px 4px;font-size:14px;color:var(--text);outline:none}.clear-btn[data-v-3fda8a90]{cursor:pointer;opacity:.5;padding:4px;display:flex;align-items:center}.results-panel[data-v-3fda8a90]{margin-top:4px;border-top:1px solid var(--border);padding:4px;max-height:250px;overflow-y:auto}.result-item[data-v-3fda8a90]{display:flex;align-items:center;gap:12px;padding:10px 12px;cursor:pointer;border-radius:var(--radius-sm);transition:background .2s}.result-item[data-v-3fda8a90]:hover{background:var(--border)}.node-icon[data-v-3fda8a90]{color:var(--primary)}.node-info[data-v-3fda8a90]{display:flex;flex-direction:column}.node-label[data-v-3fda8a90]{font-size:13px;font-weight:500}.node-id[data-v-3fda8a90]{font-size:11px;opacity:.6}.no-results[data-v-3fda8a90]{padding:12px;text-align:center;font-size:13px;color:var(--text-dim);border-top:1px solid var(--border)}.search-wrapper.is-mobile[data-v-3fda8a90]{top:auto;bottom:var(--space-md);left:var(--space-md);transform:none}.is-mobile .search-container[data-v-3fda8a90]{width:52px;height:52px;overflow:hidden;padding:0;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 20px #0000004d;border-color:var(--primary)}.is-mobile .search-input-wrapper[data-v-3fda8a90]{padding:0;width:100%;height:100%;justify-content:center}.is-mobile .search-icon[data-v-3fda8a90]{margin:0}.is-mobile input[data-v-3fda8a90]{display:none}.is-mobile .search-container.expanded[data-v-3fda8a90]{position:fixed;bottom:0;left:0;width:100vw;height:auto;max-width:none;border-radius:var(--radius-lg) var(--radius-lg) 0 0;transform:none;padding:var(--space-md);display:block}.is-mobile .search-wrapper.mobile-expanded[data-v-3fda8a90]{left:0;bottom:0;width:100%}.is-mobile .search-container.expanded .search-input-wrapper[data-v-3fda8a90]{height:auto;padding:4px 0;margin-bottom:var(--space-md);border-bottom:1px solid var(--border)}.is-mobile .search-container.expanded input[data-v-3fda8a90]{display:block;font-size:16px}.is-mobile .search-container.expanded .results-panel[data-v-3fda8a90]{max-height:60vh}.mobile-backdrop[data-v-3fda8a90]{position:fixed;inset:0;background:#00000080;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:-1}.container[data-v-87730b5c]{position:relative;width:100vw;height:100vh;transition:background-color .4s cubic-bezier(.4,0,.2,1);background:var(--bg);color:var(--text);overflow:hidden}.main-canvas[data-v-87730b5c],.overlay-canvas[data-v-87730b5c]{position:absolute;top:0;left:0;width:100%;height:100%;display:block}.overlay-canvas[data-v-87730b5c]{pointer-events:none}.mobile-menu[data-v-87730b5c]{position:fixed;bottom:var(--space-md);left:50%;transform:translate(-50%);display:flex;align-items:center;padding:6px;border-radius:var(--radius-full);z-index:1000;gap:4px}.menu-btn[data-v-87730b5c]{background:transparent;border:none;color:var(--text-dim);display:flex;flex-direction:column;align-items:center;gap:4px;padding:8px 16px;border-radius:var(--radius-full);cursor:pointer;transition:all .2s;min-width:70px}.menu-btn span[data-v-87730b5c]{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.menu-btn.active[data-v-87730b5c]{background:var(--primary);color:#fff;box-shadow:0 4px 12px var(--primary-glow)}.menu-divider[data-v-87730b5c]{width:1px;height:24px;background:var(--border);margin:0 4px}.drawer-overlay[data-v-87730b5c]{position:fixed;inset:0;background:#0006;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1300}.mobile-drawer[data-v-87730b5c]{position:absolute;bottom:0;left:0;width:100%;border-radius:var(--radius-lg) var(--radius-lg) 0 0;padding:var(--space-md);padding-bottom:env(safe-area-inset-bottom,var(--space-lg));animation:slideUp-87730b5c .3s cubic-bezier(.16,1,.3,1)}@keyframes slideUp-87730b5c{0%{transform:translateY(100%)}to{transform:translateY(0)}}.drawer-handle[data-v-87730b5c]{width:40px;height:4px;background:var(--border);border-radius:2px;margin:0 auto var(--space-md)}.drawer-header[data-v-87730b5c]{display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--space-md)}.drawer-header h3[data-v-87730b5c]{margin:0;font-size:16px;font-weight:700}.drawer-close[data-v-87730b5c]{background:transparent;border:none;color:var(--text-dim);cursor:pointer}.drawer-content[data-v-87730b5c]{padding:var(--space-sm) 0}.drawer-content[data-v-87730b5c] .layout-controls,.drawer-content[data-v-87730b5c] .top-right-controls{position:static;transform:none;width:100%;max-width:none;padding:0;background:transparent;box-shadow:none;border:none;flex-direction:row;flex-wrap:wrap;justify-content:center}.drawer-content[data-v-87730b5c] .divider{display:none}.help-trigger[data-v-87730b5c]{position:absolute;bottom:var(--space-md);right:var(--space-md);width:32px;height:32px;background:var(--surface);border:1px solid var(--border);border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:14px;font-weight:700;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);z-index:1000;transition:all .2s;color:var(--text-dim)}.help-trigger[data-v-87730b5c]:hover{background:var(--primary);color:#fff;border-color:#fff;transform:scale(1.1)}.help-modal-overlay[data-v-87730b5c]{position:fixed;inset:0;background:#0006;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:2000;display:flex;align-items:center;justify-content:center}.help-modal[data-v-87730b5c]{width:340px;border-radius:var(--radius-lg);overflow:hidden;animation:modalPop-87730b5c .3s cubic-bezier(.34,1.56,.64,1)}@keyframes modalPop-87730b5c{0%{transform:scale(.9);opacity:0}to{transform:scale(1);opacity:1}}.help-header[data-v-87730b5c]{padding:var(--space-md);border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center}.help-header h3[data-v-87730b5c]{margin:0;font-size:16px}.shortcut-row[data-v-87730b5c]{display:flex;justify-content:space-between;align-items:center;padding:12px var(--space-md);border-bottom:1px solid var(--border)}.shortcut-row[data-v-87730b5c]:last-child{border-bottom:none}.key-badge[data-v-87730b5c]{background:var(--border);padding:4px 10px;border-radius:var(--radius-sm);font-family:monospace;font-size:12px}.action-desc[data-v-87730b5c]{font-size:13px;color:var(--text-dim)}.close-btn[data-v-87730b5c]{background:transparent;border:none;color:var(--text-dim);font-size:20px;cursor:pointer}@media(max-width:768px){.help-trigger[data-v-87730b5c]{display:none}}
@@ -0,0 +1 @@
1
+ import{mat3 as e,vec3 as t,vec2 as i}from"gl-matrix";import{defineComponent as a,computed as s,openBlock as n,createElementBlock as o,Fragment as l,renderList as r,withModifiers as c,normalizeStyle as d,createElementVNode as h,renderSlot as u,createBlock as v,createVNode as m,toDisplayString as g,createCommentVNode as p,ref as f,normalizeClass as M,onMounted as b,onUnmounted as w,withDirectives as y,withKeys as x,vModelText as k,watch as C,unref as E,vShow as I}from"vue";class _{gl;constructor(e){this.gl=e}pickNode(e){const t=this.gl,{mouseX:i,mouseY:a,canvas:s,program:n,pickingFramebuffer:o,vao:l,viewMatrix:r,pointSize:c,nodeCount:d}=e;t.bindFramebuffer(t.FRAMEBUFFER,o),t.viewport(0,0,s.width,s.height),t.clearColor(0,0,0,0),t.clear(t.COLOR_BUFFER_BIT),t.useProgram(n),t.uniformMatrix3fv(t.getUniformLocation(n,"u_matrix"),!1,r),t.uniform1f(t.getUniformLocation(n,"u_pointSize"),c),t.uniform1i(t.getUniformLocation(n,"u_pickingMode"),1),t.bindVertexArray(l),t.drawArrays(t.POINTS,0,d);const h=new Uint8Array(4),u=window.devicePixelRatio;if(t.readPixels(Math.floor(i*u),Math.floor(s.height-a*u),1,1,t.RGBA,t.UNSIGNED_BYTE,h),t.bindFramebuffer(t.FRAMEBUFFER,null),0===h[3])return null;return(h[0]<<16|h[1]<<8|h[2])-1}pickEdge(a){const{mouseX:s,mouseY:n,edgeIndices:o,positions:l,nodeCount:r,viewMatrix:c,canvasW:d,canvasH:h}=a;if(!o||!l)return null;const u=window.devicePixelRatio,v=s*u,m=n*u,g=5*u,p=e.invert(e.create(),c);if(!p)return null;const f=t.fromValues(v/d*2-1,-(m/h*2-1),1);t.transformMat3(f,f,p);const M=f[0],b=f[1],w=2*g/Math.abs(c[0]+c[4]);for(let e=0;e<o.length/2;e++){const t=o[2*e],a=o[2*e+1];if(t>=r||a>=r)continue;const s=l[2*t],n=l[2*t+1],u=l[2*a],p=l[2*a+1];if(M<(s<u?s:u)-w||M>(s>u?s:u)+w||b<(n<p?n:p)-w||b>(n>p?n:p)+w)continue;const f=this.project(s,n,c,d,h),y=this.project(u,p,c,d,h);if(this.distToSegment(i.fromValues(v,m),f,y)<g)return`${t}-${a}`}return null}pickCombo(e){const{mouseX:t,mouseY:i,combos:a,positions:s,nodeCount:n,viewMatrix:o,canvasW:l,canvasH:r}=e;if(!s)return null;const c=window.devicePixelRatio,d=t*c,h=i*c;for(const u of a.values()){let e=1/0,t=1/0,i=-1/0,a=-1/0,v=!1;for(const c of u.nodeIds){if(c>=n)continue;const d=this.project(s[2*c],s[2*c+1],o,l,r);e=Math.min(e,d[0]),t=Math.min(t,d[1]),i=Math.max(i,d[0]),a=Math.max(a,d[1]),v=!0}if(v){const s=30*c;if(d>=e-s&&d<=i+s&&h>=t-s&&h<=a+s)return u.id}}return null}distToSegment(e,t,a){const s=i.dist(t,a)**2;if(0===s)return i.dist(e,t);let n=((e[0]-t[0])*(a[0]-t[0])+(e[1]-t[1])*(a[1]-t[1]))/s;n=Math.max(0,Math.min(1,n));const o=i.fromValues(t[0]+n*(a[0]-t[0]),t[1]+n*(a[1]-t[1]));return i.dist(e,o)}project(e,a,s,n,o){const l=t.fromValues(e,a,1);return t.transformMat3(l,l,s),i.fromValues((.5*l[0]+.5)*n,(.5*-l[1]+.5)*o)}}class A{canvas;ctx;constructor(e,t){this.canvas=e,this.ctx=t}_posScratch=t.create();_spScratch=i.create();_s1Scratch=i.create();_s2Scratch=i.create();project(e,i,a,s){return t.set(this._posScratch,e,i,1),t.transformMat3(this._posScratch,this._posScratch,a),s[0]=(.5*this._posScratch[0]+.5)*this.canvas.width,s[1]=(.5*-this._posScratch[1]+.5)*this.canvas.height,s}render(i){const{ctx:a,canvas:s}=this,{positions:n,nodeCount:o,edgeCount:l,edgeIndices:r,metadata:c,combos:d,theme:h,zoom:u,viewMatrix:v,selectedNodeIds:m,selectedEdgeId:g,selectedComboId:p,hoveredNodeId:f,isBoxSelecting:M,selectionStart:b,selectionEnd:w,isFlowAnimating:y}=i;if(!n)return;const x=e.invert(e.create(),v);if(!x)return;const k=t.fromValues(-1.1,1.1,1),C=t.fromValues(1.1,-1.1,1);t.transformMat3(k,k,x),t.transformMat3(C,C,x);const E=Math.min(k[0],C[0]),I=Math.max(k[0],C[0]),_=Math.min(k[1],C[1]),A=Math.max(k[1],C[1]);a.clearRect(0,0,s.width,s.height);const S=window.devicePixelRatio,R=40*u*S;M&&this.drawMarquee(b,w,S),this.drawCombos(d,n,o,v,p,h,S),this.drawNodeHighlights(m,o,n,v,R,S),this.drawEdgeHighlight(g,r,n,v,S);const F=u<.1;y&&!(u<.3)&&l<5e4&&this.drawFlow(r,l,n,v,h,S,E,I,_,A),null!==f&&r&&this.drawHoverHighlight(f,r,l,n,v,h,S),F||this.drawNodeLabels(o,c,n,v,h,S,R,u,E,I,_,A)}drawMarquee(e,t,i){const a=Math.min(e[0],t[0]),s=Math.min(e[1],t[1]),n=Math.abs(e[0]-t[0]),o=Math.abs(e[1]-t[1]);this.ctx.strokeStyle="rgba(0, 255, 204, 0.8)",this.ctx.fillStyle="rgba(0, 255, 204, 0.1)",this.ctx.lineWidth=1*i,this.ctx.strokeRect(a,s,n,o),this.ctx.fillRect(a,s,n,o)}drawCombos(e,t,i,a,s,n,o){const l=this.ctx,r=this._spScratch;for(const c of e.values()){let e=1/0,d=1/0,h=-1/0,u=-1/0,v=!1;for(const s of c.nodeIds){if(s>=i)continue;const n=this.project(t[2*s],t[2*s+1],a,r);e=Math.min(e,n[0]),d=Math.min(d,n[1]),h=Math.max(h,n[0]),u=Math.max(u,n[1]),v=!0}if(v){const t=30*o,i=e-t,a=d-t,r=h-e+2*t,v=u-d+2*t;if(i+r<0||i>this.canvas.width||a+v<0||a>this.canvas.height)continue;const m=s===c.id;l.save(),l.beginPath();const g=16*o;l.moveTo(i+g,a),l.arcTo(i+r,a,i+r,a+v,g),l.arcTo(i+r,a+v,i,a+v,g),l.arcTo(i,a+v,i,a,g),l.arcTo(i,a,i+r,a,g),l.closePath(),l.fillStyle=m?"rgba(0, 255, 204, 0.15)":"dark"===n?"rgba(0, 255, 204, 0.05)":"rgba(0, 170, 136, 0.05)",l.strokeStyle=m?"rgba(0, 255, 204, 0.8)":"dark"===n?"rgba(0, 255, 204, 0.2)":"rgba(0, 170, 136, 0.2)",l.lineWidth=(m?3:2)*o,l.setLineDash(m?[]:[5*o,5*o]),l.fill(),l.stroke(),l.setLineDash([]),l.fillStyle=m||"dark"===n?"#00ffcc":"#00aa88",l.font=`bold ${14*o}px Inter, sans-serif`,l.fillText(c.label.toUpperCase(),i+10*o,a-10*o),l.restore()}}}drawNodeHighlights(e,t,i,a,s,n){const o=this.ctx,l=this._spScratch;o.strokeStyle="#00ffcc",o.lineWidth=2*n;for(const r of e)r>=t||(this.project(i[2*r],i[2*r+1],a,l),l[0]<-50||l[0]>this.canvas.width+50||l[1]<-50||l[1]>this.canvas.height+50||(o.beginPath(),o.arc(l[0],l[1],.7*s,0,2*Math.PI),o.stroke()))}drawEdgeHighlight(e,t,i,a,s){if(!e||!t)return;const n=this.ctx,o=e.split("-"),l=Number(o[0]),r=Number(o[1]);if(isNaN(l)||isNaN(r))return;const c=this._s1Scratch,d=this._s2Scratch;this.project(i[2*l],i[2*l+1],a,c),this.project(i[2*r],i[2*r+1],a,d);const h=Math.min(c[0],d[0]),u=Math.max(c[0],d[0]),v=Math.min(c[1],d[1]),m=Math.max(c[1],d[1]);u<-20||h>this.canvas.width+20||m<-20||v>this.canvas.height+20||(n.strokeStyle="#ff00ff",n.lineWidth=3*s,n.beginPath(),n.moveTo(c[0],c[1]),n.lineTo(d[0],d[1]),n.stroke())}drawFlow(e,t,i,a,s,n,o,l,r,c){if(!e)return;const d=this.ctx,h=.002*performance.now(),u=this._s1Scratch,v=this._s2Scratch,m=Math.max(1,Math.floor(t/15e3));for(let g=0;g<t/2;g+=m){const t=e[2*g],m=e[2*g+1],p=i[2*t],f=i[2*t+1],M=i[2*m],b=i[2*m+1];if((p>M?p:M)<o||(p<M?p:M)>l||(f>b?f:b)<r||(f<b?f:b)>c)continue;this.project(p,f,a,u),this.project(M,b,a,v);const w=Math.min(u[0],v[0]),y=Math.max(u[0],v[0]),x=Math.min(u[1],v[1]),k=Math.max(u[1],v[1]);if(y<-20||w>this.canvas.width+20||k<-20||x>this.canvas.height+20)continue;const C=(h+.1*g%1)%1,E=u[0]+(v[0]-u[0])*C,I=u[1]+(v[1]-u[1])*C;d.beginPath(),d.arc(E,I,2*n,0,2*Math.PI),d.fillStyle="dark"===s?"#00ffcc":"#00aa88",d.shadowBlur=4*n,d.shadowColor=d.fillStyle,d.fill(),d.shadowBlur=0}}drawHoverHighlight(e,t,i,a,s,n,o){const l=this.ctx;l.lineWidth=2*o,l.strokeStyle="dark"===n?"rgba(0, 255, 204, 0.6)":"rgba(0, 170, 136, 0.5)";const r=this._s1Scratch,c=this._s2Scratch;for(let d=0;d<i/2;d++){const i=t[2*d],n=t[2*d+1];i!==e&&n!==e||(this.project(a[2*i],a[2*i+1],s,r),this.project(a[2*n],a[2*n+1],s,c),l.beginPath(),l.moveTo(r[0],r[1]),l.lineTo(c[0],c[1]),l.stroke())}}drawNodeLabels(e,t,i,a,s,n,o,l,r,c,d,h){const u=this.ctx;u.textAlign="center",u.textBaseline="top";const v=this._spScratch;let m=0;for(let g=0;g<e&&!(m>200);g++){const e=i[2*g],p=i[2*g+1];if(e<r||e>c||p<d||p>h)continue;const f=t.get(g);if(!f)continue;this.project(e,p,a,v);const M=v[0],b=v[1];if(M<-50||M>this.canvas.width+50||b<-50||b>this.canvas.height+50)continue;m++;const w=.5*o,y=l>.6;if(o>12*n&&(u.beginPath(),u.arc(M,b,w,0,2*Math.PI),u.strokeStyle="dark"===s?"rgba(255, 255, 255, 0.8)":"rgba(0, 0, 0, 0.8)",u.lineWidth=1*n,u.stroke()),y)if(f.processedImageElement){const e=o*.7;u.drawImage(f.processedImageElement,M-e/2,b-e/2,e,e)}else if(f.imageElement&&f.imageElement.complete&&0!==f.imageElement.naturalWidth){const e=o*.7;u.save(),u.beginPath(),u.arc(M,b,.9*w,0,2*Math.PI),u.clip(),u.filter="grayscale(100%) brightness(1000%)",u.drawImage(f.imageElement,M-e/2,b-e/2,e,e),u.restore()}else f.icon&&(u.font=.6*o+"px serif",u.fillStyle="dark"===s?"white":"black",u.fillText(f.icon,M,b-.2*o));if(!(l<.5)&&f.label){const e=w+8*n;u.font=12*n+"px Inter, sans-serif",u.fillStyle="dark"===s?"white":"black",u.fillText(f.label,M,b+e)}}}}class S{lastMouse=i.create();isPanning=!1;engine;canvas;lastTouchDistance=0;lastTouchMidpoint=i.create();isTouching=!1;touchStartTime=0;touchStartPos=i.create();longPressTimer=null;isLongPress=!1;constructor(e,t){this.engine=e,this.canvas=t,this.setupListeners()}setupListeners(){this.canvas.addEventListener("mousedown",e=>this.handleMouseDown(e)),window.addEventListener("mousemove",e=>this.handleMouseMove(e)),window.addEventListener("mouseup",()=>this.handleMouseUp()),this.canvas.addEventListener("wheel",e=>this.handleWheel(e),{passive:!1}),this.canvas.addEventListener("touchstart",e=>this.handleTouchStart(e),{passive:!1}),this.canvas.addEventListener("touchmove",e=>this.handleTouchMove(e),{passive:!1}),this.canvas.addEventListener("touchend",e=>this.handleTouchEnd(e)),this.canvas.addEventListener("touchcancel",e=>this.handleTouchEnd(e))}handleMouseDown(e){const t=this.canvas.getBoundingClientRect(),a=e.clientX-t.left,s=e.clientY-t.top,n=this.engine.getState();if(e.shiftKey)return this.engine.updateInteractionState({isBoxSelecting:!0,selectionStart:i.fromValues(a,s),selectionEnd:i.fromValues(a,s)}),void this.engine.render();const o=this.engine.pick(a,s);if(null!==o){const t=n.selectedNodeIds.has(o);e.ctrlKey||e.metaKey||t||n.selectedNodeIds.clear(),n.selectedNodeIds.add(o),this.engine.updateInteractionState({isMultiDragging:!0,draggedNodeId:null}),this.engine.syncDragOffsets(a,s),this.canvas.dispatchEvent(new CustomEvent("node-selected",{detail:o})),this.canvas.dispatchEvent(new CustomEvent("nodes-selected",{detail:Array.from(n.selectedNodeIds)}))}else{n.selectedNodeIds.clear();const e=this.engine.getEdgeAt(a,s),t=this.engine.pickCombo(a,s);this.engine.updateInteractionState({selectedEdgeId:e,selectedComboId:t}),this.canvas.dispatchEvent(new CustomEvent("edge-selected",{detail:e})),this.canvas.dispatchEvent(new CustomEvent("combo-selected",{detail:t})),this.canvas.dispatchEvent(new CustomEvent("nodes-selected",{detail:[]})),this.canvas.dispatchEvent(new CustomEvent("node-selected",{detail:null})),e||t||(this.isPanning=!0)}i.set(this.lastMouse,e.clientX,e.clientY),this.engine.render()}handleMouseMove(e){const t=this.canvas.getBoundingClientRect(),a=e.clientX-t.left,s=e.clientY-t.top,n=this.engine.getState();if(n.isBoxSelecting)return this.engine.updateInteractionState({selectionEnd:i.fromValues(a,s)}),void this.engine.render();if(n.isMultiDragging||null!==n.draggedNodeId)this.engine.handleDragging(a,s);else if(this.isPanning){const t=(e.clientX-this.lastMouse[0])/(this.canvas.width/2),a=-(e.clientY-this.lastMouse[1])/(this.canvas.height/2);this.engine.pan(t,a),i.set(this.lastMouse,e.clientX,e.clientY)}else{const e=n.hoveredNodeId,t=this.engine.pick(a,s);t!==e&&(this.engine.updateInteractionState({hoveredNodeId:t}),this.engine.render(),this.canvas.dispatchEvent(new CustomEvent("node-hovered",{detail:t})))}}handleMouseUp(){this.engine.getState().isBoxSelecting&&this.engine.performBoxSelection(),this.isPanning=!1,this.engine.updateInteractionState({isBoxSelecting:!1,isMultiDragging:!1,draggedNodeId:null}),this.engine.render()}handleWheel(e){e.preventDefault();const t=this.canvas.getBoundingClientRect(),i=e.clientX-t.left,a=e.clientY-t.top,s=.001*-e.deltaY;this.engine.zoomAt(i,a,s)}handleTouchStart(e){if(e.preventDefault(),this.isTouching=!0,this.touchStartTime=Date.now(),this.isLongPress=!1,1===e.touches.length){const t=e.touches[0],a=this.canvas.getBoundingClientRect(),s=t.clientX-a.left,n=t.clientY-a.top;i.set(this.touchStartPos,s,n),i.set(this.lastMouse,t.clientX,t.clientY),this.longPressTimer=window.setTimeout(()=>{this.isLongPress=!0,this.triggerContextMenu(t.clientX,t.clientY)},500);const o=this.engine.pick(s,n),l=this.engine.getState();null!==o&&(l.selectedNodeIds.has(o)||(l.selectedNodeIds.clear(),l.selectedNodeIds.add(o)),this.engine.updateInteractionState({isMultiDragging:!0,draggedNodeId:null}),this.engine.syncDragOffsets(s,n),this.canvas.dispatchEvent(new CustomEvent("node-selected",{detail:o})))}else if(2===e.touches.length){this.clearLongPress();const t=e.touches[0],a=e.touches[1];this.lastTouchDistance=i.distance(i.fromValues(t.clientX,t.clientY),i.fromValues(a.clientX,a.clientY)),i.set(this.lastTouchMidpoint,(t.clientX+a.clientX)/2,(t.clientY+a.clientY)/2)}}handleTouchMove(e){if(e.preventDefault(),this.isTouching){if(1===e.touches.length){const t=e.touches[0],a=this.canvas.getBoundingClientRect(),s=t.clientX-a.left,n=t.clientY-a.top;if(i.distance(this.touchStartPos,i.fromValues(s,n))>10&&this.clearLongPress(),this.isLongPress)return;if(this.engine.getState().isMultiDragging)this.engine.handleDragging(s,n);else{const e=(t.clientX-this.lastMouse[0])/(this.canvas.width/2),i=-(t.clientY-this.lastMouse[1])/(this.canvas.height/2);this.engine.pan(e,i)}i.set(this.lastMouse,t.clientX,t.clientY)}else if(2===e.touches.length){this.clearLongPress();const t=e.touches[0],a=e.touches[1],s=i.distance(i.fromValues(t.clientX,t.clientY),i.fromValues(a.clientX,a.clientY)),n=i.fromValues((t.clientX+a.clientX)/2,(t.clientY+a.clientY)/2),o=s/this.lastTouchDistance,l=this.canvas.getBoundingClientRect(),r=n[0]-l.left,c=n[1]-l.top;this.engine.zoomAt(r,c,o-1);const d=(n[0]-this.lastTouchMidpoint[0])/(this.canvas.width/2),h=-(n[1]-this.lastTouchMidpoint[1])/(this.canvas.height/2);this.engine.pan(d,h),this.lastTouchDistance=s,i.copy(this.lastTouchMidpoint,n)}this.engine.render()}}handleTouchEnd(e){if(this.isTouching=!1,this.clearLongPress(),0===e.touches.length&&!this.isLongPress){const t=Date.now()-this.touchStartTime,a=e.changedTouches[0],s=this.canvas.getBoundingClientRect(),n=a.clientX-s.left,o=a.clientY-s.top,l=i.distance(this.touchStartPos,i.fromValues(n,o));if(t<250&&l<10){const e=this.engine.pick(n,o);this.engine.selectNode(e)}}this.engine.updateInteractionState({isMultiDragging:!1}),this.engine.render()}clearLongPress(){null!==this.longPressTimer&&(window.clearTimeout(this.longPressTimer),this.longPressTimer=null)}triggerContextMenu(e,t){const i=new MouseEvent("contextmenu",{clientX:e,clientY:t,bubbles:!0,cancelable:!0});this.canvas.dispatchEvent(i)}}class R{gl;pickingEngine;overlayManager;program=null;edgeProgram=null;viewMatrix=e.create();vao=null;edgeVao=null;positionBuffer=null;colorBuffer=null;idBuffer=null;edgeIndexBuffer=null;pickingFramebuffer=null;pickingTexture=null;uMatrixLoc=null;uPointSizeLoc=null;uPickingModeLoc=null;uEdgeMatrixLoc=null;uEdgeColorLoc=null;nodeCount=0;edgeCount=0;positions=null;metadata=/* @__PURE__ */new Map;edgeIndices=null;edgeMetadata=/* @__PURE__ */new Map;combos=/* @__PURE__ */new Map;theme="dark";static MAX_ZOOM=100;static MIN_ZOOM=1e-4;state={zoom:1,offset:i.fromValues(0,0),selectedNodeIds:/* @__PURE__ */new Set,selectedEdgeId:null,selectedComboId:null,hoveredNodeId:null,isBoxSelecting:!1,selectionStart:i.create(),selectionEnd:i.create(),isMultiDragging:!1,draggedNodeId:null};dragOffsets=/* @__PURE__ */new Map;isFlowAnimating=!1;canvas;overlayCanvas;constructor(e,t){this.canvas=e,this.overlayCanvas=t;const i=e.getContext("webgl2",{antialias:!0,stencil:!0});if(!i)throw new Error("WebGL2 not supported");this.gl=i;const a=t.getContext("2d");if(!a)throw new Error("Canvas 2D not supported");this.pickingEngine=new _(i),this.overlayManager=new A(t,a),this.initShaders(),this.initBuffers(),this.initPicking(),this.updateMatrix(),new S(this,e),this.handleResize(),window.addEventListener("resize",()=>this.handleResize())}setData(e,t,i,a,s,n){this.positions=e,this.nodeCount=i.length,this.metadata=a;const o=this.gl;o.bindBuffer(o.ARRAY_BUFFER,this.positionBuffer),o.bufferData(o.ARRAY_BUFFER,e,o.DYNAMIC_DRAW),o.bindBuffer(o.ARRAY_BUFFER,this.colorBuffer),o.bufferData(o.ARRAY_BUFFER,t,o.STATIC_DRAW),o.bindBuffer(o.ARRAY_BUFFER,this.idBuffer),o.bufferData(o.ARRAY_BUFFER,i,o.STATIC_DRAW),s&&(this.edgeIndices=s,this.edgeCount=s.length,o.bindBuffer(o.ELEMENT_ARRAY_BUFFER,this.edgeIndexBuffer),o.bufferData(o.ELEMENT_ARRAY_BUFFER,s,o.STATIC_DRAW)),n&&(this.edgeMetadata=n),this.render()}updatePositions(e){this.positions=e;const t=this.gl;t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,e),this.render()}setNodePosition(e,t,i){if(!this.positions||e>=this.nodeCount)return;this.positions[2*e]=t,this.positions[2*e+1]=i;const a=this.gl;a.bindBuffer(a.ARRAY_BUFFER,this.positionBuffer),a.bufferSubData(a.ARRAY_BUFFER,2*e*4,this.positions.subarray(2*e,2*e+2)),this.render()}getNodePosition(e){return!this.positions||e>=this.nodeCount?null:i.fromValues(this.positions[2*e],this.positions[2*e+1])}setFlowAnimation(e){if(this.isFlowAnimating=e,e){const e=()=>{this.isFlowAnimating&&(this.render(),requestAnimationFrame(e))};requestAnimationFrame(e)}else this.render()}setTheme(e){this.theme=e,this.render()}createCombo(e,t,i){this.combos.set(e,{id:e,label:t,nodeIds:new Set(i)}),this.render()}removeCombo(e){this.combos.delete(e),this.render()}updateCombo(e,t,i){const a=this.combos.get(e);a&&(a.label=t,a.nodeIds=new Set(i),this.render())}getCombo(e){return this.combos.get(e)}getSelectedNodeIds(){return Array.from(this.state.selectedNodeIds)}getNodeMetadata(e){return this.metadata.get(e)}getEdgeMetadata(e){return this.edgeMetadata.get(e)}addNodeToCombo(e,t){const i=this.combos.get(e);i&&(i.nodeIds.add(t),this.render())}removeNodeFromCombo(e,t){const i=this.combos.get(e);i&&(i.nodeIds.delete(t),this.render())}render(){const e=this.gl;if(!this.program)return;this.updateMatrix();const t="dark"===this.theme?.05:.95;e.clearColor(t,t,t,1),e.clear(e.COLOR_BUFFER_BIT),this.edgeCount>0&&this.edgeProgram&&(e.useProgram(this.edgeProgram),e.uniformMatrix3fv(this.uEdgeMatrixLoc,!1,this.viewMatrix),e.uniform4fv(this.uEdgeColorLoc,"dark"===this.theme?[1,1,1,.15]:[0,0,0,.1]),e.bindVertexArray(this.edgeVao),e.drawElements(e.LINES,this.edgeCount,e.UNSIGNED_INT,0)),e.useProgram(this.program),e.uniformMatrix3fv(this.uMatrixLoc,!1,this.viewMatrix),e.uniform1f(this.uPointSizeLoc,40*this.state.zoom*window.devicePixelRatio),e.uniform1i(this.uPickingModeLoc,0),e.bindVertexArray(this.vao),e.drawArrays(e.POINTS,0,this.nodeCount),this.renderOverlay()}renderOverlay(){this.overlayManager.render({...this.state,positions:this.positions,nodeCount:this.nodeCount,edgeCount:this.edgeCount,edgeIndices:this.edgeIndices,metadata:this.metadata,edgeMetadata:this.edgeMetadata,combos:this.combos,theme:this.theme,viewMatrix:this.viewMatrix,isFlowAnimating:this.isFlowAnimating})}getState(){return this.state}updateInteractionState(e){Object.assign(this.state,e)}pick(e,t){return this.program&&this.pickingFramebuffer&&this.vao?this.pickingEngine.pickNode({mouseX:e,mouseY:t,canvas:this.canvas,program:this.program,pickingFramebuffer:this.pickingFramebuffer,vao:this.vao,nodeCount:this.nodeCount,viewMatrix:this.viewMatrix,pointSize:40*this.state.zoom*window.devicePixelRatio}):null}getEdgeAt(e,t){return this.pickingEngine.pickEdge({mouseX:e,mouseY:t,edgeIndices:this.edgeIndices,positions:this.positions,nodeCount:this.nodeCount,viewMatrix:this.viewMatrix,canvasW:this.canvas.width,canvasH:this.canvas.height})}pickCombo(e,t){return this.pickingEngine.pickCombo({mouseX:e,mouseY:t,combos:this.combos,positions:this.positions,nodeCount:this.nodeCount,viewMatrix:this.viewMatrix,canvasW:this.canvas.width,canvasH:this.canvas.height})}fitToView(){if(!this.positions||0===this.nodeCount)return this.state.zoom=1,this.state.offset=i.fromValues(0,0),void this.render();let e=1/0,t=1/0,a=-1/0,s=-1/0;for(let i=0;i<this.nodeCount;i++){const n=this.positions[2*i],o=this.positions[2*i+1];n<e&&(e=n),n>a&&(a=n),o<t&&(t=o),o>s&&(s=o)}const n=a-e,o=s-t,l=(e+a)/2,r=(t+s)/2,c=2*(this.canvas.width/this.canvas.height)*.9/Math.max(n,.01),d=1.8/Math.max(o,.01);this.state.zoom=Math.min(c,d,100),this.state.offset=i.fromValues(-l,-r),this.render()}zoomIn(){this.state.zoom=Math.min(R.MAX_ZOOM,1.2*this.state.zoom),this.render()}zoomOut(){this.state.zoom=Math.max(R.MIN_ZOOM,this.state.zoom/1.2),this.render()}setCameraCenter(e,t){this.state.offset=i.fromValues(-e,-t),this.render()}setCameraZoom(e){this.state.zoom=Math.max(R.MIN_ZOOM,Math.min(R.MAX_ZOOM,e)),this.render()}selectNode(e){this.state.selectedNodeIds.clear(),null!==e&&this.state.selectedNodeIds.add(e),this.canvas.dispatchEvent(new CustomEvent("node-selected",{detail:e})),this.render()}zoomAt(e,t,a){const s=window.devicePixelRatio,n=this.unproject(e*s,t*s);this.state.zoom=Math.max(R.MIN_ZOOM,Math.min(R.MAX_ZOOM,this.state.zoom*(1+a))),this.updateMatrix();const o=this.unproject(e*s,t*s);i.add(this.state.offset,this.state.offset,i.sub(i.create(),o,n)),this.render()}pan(e,t){i.add(this.state.offset,this.state.offset,i.fromValues(e/this.state.zoom,t/this.state.zoom)),this.render()}syncDragOffsets(e,t){const a=window.devicePixelRatio,s=this.unproject(e*a,t*a);this.dragOffsets.clear();for(const n of this.state.selectedNodeIds){const e=this.getNodePosition(n);e&&this.dragOffsets.set(n,i.sub(i.create(),e,s))}}handleDragging(e,t){if(!this.positions)return;const a=window.devicePixelRatio,s=this.unproject(e*a,t*a),n=this.gl;n.bindBuffer(n.ARRAY_BUFFER,this.positionBuffer);for(const o of this.state.selectedNodeIds){const e=this.dragOffsets.get(o);if(e){const t=i.add(i.create(),s,e);this.positions[2*o]=t[0],this.positions[2*o+1]=t[1],n.bufferSubData(n.ARRAY_BUFFER,2*o*4,this.positions.subarray(2*o,2*o+2)),this.canvas.dispatchEvent(new CustomEvent("node-moved",{detail:{id:o,x:t[0],y:t[1]}}))}}this.render()}performBoxSelection(){if(!this.positions)return;const e=window.devicePixelRatio,t=this.unproject(this.state.selectionStart[0]*e,this.state.selectionStart[1]*e),i=this.unproject(this.state.selectionEnd[0]*e,this.state.selectionEnd[1]*e),a=Math.min(t[0],i[0]),s=Math.max(t[0],i[0]),n=Math.min(t[1],i[1]),o=Math.max(t[1],i[1]);this.state.selectedNodeIds.clear();for(let l=0;l<this.nodeCount;l++){const e=this.positions[2*l],t=this.positions[2*l+1];e>=a&&e<=s&&t>=n&&t<=o&&this.state.selectedNodeIds.add(l)}this.canvas.dispatchEvent(new CustomEvent("nodes-selected",{detail:Array.from(this.state.selectedNodeIds)}))}unproject(a,s){const n=a/this.canvas.width*2-1,o=-(s/this.canvas.height*2-1),l=e.invert(e.create(),this.viewMatrix);if(!l)return i.create();const r=t.fromValues(n,o,1);return t.transformMat3(r,r,l),i.fromValues(r[0],r[1])}initShaders(){const e=this.gl;this.program=this.createProgram("#version 300 es\nlayout(location = 0) in vec2 a_position;\nlayout(location = 1) in vec4 a_color;\nlayout(location = 2) in float a_id;\n\nuniform mat3 u_matrix;\nuniform float u_pointSize;\nuniform bool u_pickingMode;\n\nout vec4 v_color;\nflat out uint v_id;\n\nvoid main() {\n vec3 position = u_matrix * vec3(a_position, 1.0);\n gl_Position = vec4(position.xy, 0, 1);\n gl_PointSize = u_pointSize;\n v_color = a_color;\n v_id = uint(a_id);\n}\n","#version 300 es\nprecision highp float;\n\nin vec4 v_color;\nflat in uint v_id;\n\nuniform bool u_pickingMode;\nout vec4 outColor;\n\nvoid main() {\n float dist = distance(gl_PointCoord, vec2(0.5));\n if (dist > 0.5) discard;\n\n if (u_pickingMode) {\n uint id = v_id + 1u;\n float r = float((id >> 16) & 0xFFu) / 255.0;\n float g = float((id >> 8) & 0xFFu) / 255.0;\n float b = float(id & 0xFFu) / 255.0;\n outColor = vec4(r, g, b, 1.0);\n } else {\n outColor = v_color;\n }\n}\n"),this.uMatrixLoc=e.getUniformLocation(this.program,"u_matrix"),this.uPointSizeLoc=e.getUniformLocation(this.program,"u_pointSize"),this.uPickingModeLoc=e.getUniformLocation(this.program,"u_pickingMode"),this.edgeProgram=this.createProgram("#version 300 es\nlayout(location = 0) in vec2 a_position;\n\nuniform mat3 u_matrix;\n\nvoid main() {\n vec3 position = u_matrix * vec3(a_position, 1.0);\n gl_Position = vec4(position.xy, 0, 1);\n}\n","#version 300 es\nprecision highp float;\nuniform vec4 u_color;\nout vec4 outColor;\n\nvoid main() {\n outColor = u_color;\n}\n"),this.uEdgeMatrixLoc=e.getUniformLocation(this.edgeProgram,"u_matrix"),this.uEdgeColorLoc=e.getUniformLocation(this.edgeProgram,"u_color")}initBuffers(){const e=this.gl;this.vao=e.createVertexArray(),e.bindVertexArray(this.vao),this.positionBuffer=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.enableVertexAttribArray(0),e.vertexAttribPointer(0,2,e.FLOAT,!1,0,0),this.colorBuffer=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.colorBuffer),e.enableVertexAttribArray(1),e.vertexAttribPointer(1,4,e.FLOAT,!1,0,0),this.idBuffer=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.idBuffer),e.enableVertexAttribArray(2),e.vertexAttribPointer(2,1,e.FLOAT,!1,0,0),this.edgeVao=e.createVertexArray(),e.bindVertexArray(this.edgeVao),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.enableVertexAttribArray(0),e.vertexAttribPointer(0,2,e.FLOAT,!1,0,0),this.edgeIndexBuffer=e.createBuffer(),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.edgeIndexBuffer),e.bindVertexArray(null)}initPicking(){const e=this.gl;this.pickingFramebuffer=e.createFramebuffer(),this.pickingTexture=e.createTexture(),e.bindTexture(e.TEXTURE_2D,this.pickingTexture),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,this.canvas.width,this.canvas.height,0,e.RGBA,e.UNSIGNED_BYTE,null),e.bindFramebuffer(e.FRAMEBUFFER,this.pickingFramebuffer),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.pickingTexture,0),e.bindFramebuffer(e.FRAMEBUFFER,null)}handleResize(){const e=window.devicePixelRatio;this.canvas.width=this.canvas.clientWidth*e,this.canvas.height=this.canvas.clientHeight*e,this.overlayCanvas.width=this.overlayCanvas.clientWidth*e,this.overlayCanvas.height=this.overlayCanvas.clientHeight*e,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.initPicking(),this.render()}updateMatrix(){const t=this.canvas.width/this.canvas.height;e.identity(this.viewMatrix),e.scale(this.viewMatrix,this.viewMatrix,[this.state.zoom/t,this.state.zoom]),e.translate(this.viewMatrix,this.viewMatrix,this.state.offset)}createProgram(e,t){const i=this.gl,a=i.createShader(i.VERTEX_SHADER);i.shaderSource(a,e),i.compileShader(a);const s=i.createShader(i.FRAGMENT_SHADER);i.shaderSource(s,t),i.compileShader(s);const n=i.createProgram();return i.attachShader(n,a),i.attachShader(n,s),i.linkProgram(n),n}}const F=["width","height","stroke-width"],T=["d"],L=["cx","cy","r"],P=["x1","y1","x2","y2"],B=["x","y","width","height","rx","ry"],N=(e,t)=>{const i=e.__vccOpts||e;for(const[a,s]of t)i[a]=s;return i},z=/* @__PURE__ */N(/* @__PURE__ */a({__name:"LucideIcon",props:{name:{},size:{default:24},strokeWidth:{default:2}},setup(e){const t=e,i={sun:{paths:["M12 1v2","M12 21v2","M4.22 4.22l1.42 1.42","M18.36 18.36l1.42 1.42","M1 12h2","M21 12h2","M4.22 19.78l1.42-1.42","M18.36 5.64l1.42-1.42"],circles:[{cx:12,cy:12,r:4}]},moon:{paths:["M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"]},maximize:{paths:["M8 3H5a2 2 0 0 0-2 2v3","M21 8V5a2 2 0 0 0-2-2h-3","M3 16v3a2 2 0 0 0 2 2h3","M16 21h3a2 2 0 0 0 2-2v-3"]},plus:{paths:["M12 5v14","M5 12h14"]},minus:{paths:["M5 12h14"]},rocket:{paths:["M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z","m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z","M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0","M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"]},shrink:{paths:["M14 10l7-7","M3 21l7-7","M21 10h-7V3","M3 14h7v7"]},expand:{paths:["M15 3h6v6","M9 21H3v-6","M21 3l-7 7","M3 21l7-7"]},"layout-grid":{rects:[{x:3,y:3,width:7,height:7,rx:1},{x:14,y:3,width:7,height:7,rx:1},{x:14,y:14,width:7,height:7,rx:1},{x:3,y:14,width:7,height:7,rx:1}]},circle:{circles:[{cx:12,cy:12,r:10}]},dices:{rects:[{x:2,y:11,width:11,height:11,rx:2}],paths:["M7 15h.01","M7 19h.01","M11 19h.01","M22 5V2a1 1 0 0 0-1-1h-6a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2","M22 5h-4a1 1 0 0 0-1 1v4","M22 5c0-1.1-.9-2-2-2","M14 7h.01"]},spiral:{paths:["M12 12a1 1 0 1 0 1 1","M12 7a5 5 0 1 0 5 5","M12 2a10 10 0 1 0 10 10","M12 12a1 1 0 0 0-1-1"]},target:{circles:[{cx:12,cy:12,r:10},{cx:12,cy:12,r:6},{cx:12,cy:12,r:2}]},atom:{circles:[{cx:12,cy:12,r:1}],paths:["M12 2v2","M12 20v2","m4.93 4.93 1.41 1.41","m17.66 17.66 1.41 1.41","M2 12h2","M20 12h2","m6.34 17.66-1.41-1.41","m19.07 4.93-1.41 1.41"]},"git-branch":{circles:[{cx:6,cy:3,r:3},{cx:6,cy:21,r:3},{cx:18,cy:9,r:3}],paths:["M6 6v12","M18 12a6 6 0 0 1-6 6H6"]},sparkles:{paths:["m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z","M5 3L4 5.5 1.5 6.5 4 7.5 5 10l1-2.5 2.5-1L6 5.5 5 3Z","M19 19l-1 2.5-2.5 1L18 23.5l1 2.5 1-2.5 2.5-1-2.5-1-1-2.5Z"]},search:{circles:[{cx:11,cy:11,r:8}],lines:[{x1:21,y1:21,x2:16.65,y2:16.65}]},info:{circles:[{cx:12,cy:12,r:10}],paths:["M12 16v-4","M12 8h.01"]},"trash-2":{paths:["M3 6h18","M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6","M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2","M10 11v6","M14 11v6"]},palette:{circles:[{cx:13.5,cy:6.5,r:.5},{cx:17.5,cy:10.5,r:.5},{cx:8.5,cy:7.5,r:.5},{cx:6.5,cy:12.5,r:.5}],paths:["M12 2C6.47 2 2 6.47 2 12s4.47 10 9.99 10a3 3 0 0 0 3-3c0-.8-.34-1.56-.92-2.1l-.1-.08c-.53-.45-.88-1.1-.88-1.82 0-1.38 1.12-2.5 2.5-2.5H19a3 3 0 0 0 2-5c0-4.42-4.03-8-9-8Z"]},pin:{paths:["M15 4.5l-4 4L7 10l-1.5 1.5 7 7L14 17l1.5-4 4-4L15 4.5z","m9 21 3-3","M14 4.5L19.5 10"]},box:{paths:["M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z","m3.3 7 8.7 5 8.7-5","M12 22V12"]},eye:{paths:["M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"],circles:[{cx:12,cy:12,r:3}]},"eye-off":{paths:["M9.88 9.88a3 3 0 1 0 4.24 4.24","M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68","M6.61 6.61A13.52 13.52 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61","m2 2 20 20"]},"refresh-cw":{paths:["M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8","M21 3v5h-5","M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16","M3 21v-5h5"]},scale:{paths:["m16 16 3-8 3 8c-.87.62-1.92 1-3 1s-2.13-.38-3-1Z","m2 16 3-8 3 8c-.87.62-1.92 1-3 1s-2.13-.38-3-1Z","M7 21h10","M12 3v18","M3 7h18"]},zap:{paths:["M13 2 3 14h9l-1 8 10-12h-9l1-8z"]},x:{paths:["M18 6L6 18","M6 6l12 12"]}},a=s(()=>i[t.name]||i.search),c=s(()=>a.value.paths||[]),d=s(()=>a.value.circles||[]),h=s(()=>a.value.lines||[]),u=s(()=>a.value.rects||[]);return(t,i)=>(n(),o("svg",{xmlns:"http://www.w3.org/2000/svg",width:e.size,height:e.size,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":e.strokeWidth,"stroke-linecap":"round","stroke-linejoin":"round",class:"lucide-icon"},[(n(!0),o(l,null,r(c.value,(e,t)=>(n(),o("path",{key:t,d:e},null,8,T))),128)),(n(!0),o(l,null,r(d.value,(e,t)=>(n(),o("circle",{key:t,cx:e.cx,cy:e.cy,r:e.r},null,8,L))),128)),(n(!0),o(l,null,r(h.value,(e,t)=>(n(),o("line",{key:t,x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2},null,8,P))),128)),(n(!0),o(l,null,r(u.value,(e,t)=>(n(),o("rect",{key:t,x:e.x,y:e.y,width:e.width,height:e.height,rx:e.rx,ry:e.ry},null,8,B))),128))],8,F))}}),[["__scopeId","data-v-6aa14fad"]]),D={class:"radial-center glass shadow-glow"},Y=["onClick"],V={class:"radial-icon"},U={class:"radial-label"},O=/* @__PURE__ */N(/* @__PURE__ */a({__name:"RadialMenu",props:{show:{type:Boolean},x:{},y:{},type:{},items:{}},emits:["action"],setup(e){const t=(e,t)=>{const i=e/t*Math.PI*2-Math.PI/2,a=window.innerWidth<768?100:85;return{transform:`translate(-50%, -50%) translate(${Math.cos(i)*a}px, ${Math.sin(i)*a}px)`,transitionDelay:.05*e+"s"}};return(i,a)=>e.show?(n(),o("div",{key:0,class:"radial-menu",style:d({left:e.x+"px",top:e.y+"px"}),onMousedown:a[0]||(a[0]=c(()=>{},["stop"])),onTouchstart:a[1]||(a[1]=c(()=>{},["stop"]))},[h("div",D,[u(i.$slots,"center",{},()=>["node"===e.type?(n(),v(z,{key:0,name:"target",size:"24"})):"edge"===e.type?(n(),v(z,{key:1,name:"git-branch",size:"24"})):(n(),v(z,{key:2,name:"search",size:"24"}))],!0)]),(n(!0),o(l,null,r(e.items,(a,s)=>(n(),o("div",{key:s,class:"radial-item",style:d(t(s,e.items.length))},[h("button",{class:"radial-item-inner glass-interactive",onClick:e=>i.$emit("action",a.action)},[h("span",V,[m(z,{name:a.icon,size:"20"},null,8,["name"])]),h("span",U,g(a.label),1)],8,Y)],4))),128))],36)):p("",!0)}}),[["__scopeId","data-v-a2a68595"]]),X={class:"top-right-controls glass"},W=["title"],j=/* @__PURE__ */N(/* @__PURE__ */a({__name:"ViewControls",props:{theme:{}},emits:["toggleTheme","fit","zoomIn","zoomOut","stress"],setup(e){const t=f(!1),i=()=>{document.fullscreenElement?(document.exitFullscreen(),t.value=!1):(document.documentElement.requestFullscreen(),t.value=!0)};return(a,s)=>(n(),o("div",X,[h("button",{class:"control-btn glass-interactive",onClick:s[0]||(s[0]=e=>a.$emit("toggleTheme")),title:"dark"===e.theme?"Switch to Light":"Switch to Dark"},[m(z,{name:"dark"===e.theme?"moon":"sun",size:"20"},null,8,["name"])],8,W),s[5]||(s[5]=h("div",{class:"divider"},null,-1)),h("button",{class:"control-btn glass-interactive",onClick:s[1]||(s[1]=e=>a.$emit("fit")),title:"Fit View"},[m(z,{name:"maximize",size:"20"})]),h("button",{class:"control-btn glass-interactive",onClick:s[2]||(s[2]=e=>a.$emit("zoomIn")),title:"Zoom In"},[m(z,{name:"plus",size:"20"})]),h("button",{class:"control-btn glass-interactive",onClick:s[3]||(s[3]=e=>a.$emit("zoomOut")),title:"Zoom Out"},[m(z,{name:"minus",size:"20"})]),s[6]||(s[6]=h("div",{class:"divider"},null,-1)),h("button",{class:"control-btn glass-interactive stress-btn",onClick:s[4]||(s[4]=e=>a.$emit("stress")),title:"Stress Test (100k Nodes)"},[m(z,{name:"rocket",size:"20"})]),s[7]||(s[7]=h("div",{class:"divider"},null,-1)),h("button",{class:"control-btn glass-interactive",onClick:i,title:"Toggle Fullscreen"},[m(z,{name:t.value?"shrink":"expand",size:"20"},null,8,["name"])])]))}}),[["__scopeId","data-v-4a9f463d"]]),Z={class:"layout-controls glass"},H={class:"scroll-container"},$=["onClick"],G={class:"btn-icon"},q={class:"btn-name"},K=/* @__PURE__ */N(/* @__PURE__ */a({__name:"LayoutControls",props:{layouts:{},currentLayout:{},flowEnabled:{type:Boolean}},emits:["runLayout","toggleFlow"],setup:e=>(t,i)=>(n(),o("div",Z,[h("div",H,[(n(!0),o(l,null,r(e.layouts,i=>(n(),o("button",{key:i.id,class:M(["layout-btn glass-interactive",{active:e.currentLayout===i.id}]),onClick:e=>t.$emit("runLayout",i.id)},[h("span",G,[m(z,{name:i.icon,size:"16"},null,8,["name"])]),h("span",q,g(i.name),1)],10,$))),128))])]))}),[["__scopeId","data-v-ff660e6a"]]),J={key:0,class:"property-panel glass node-panel"},Q={class:"panel-header"},ee={class:"panel-content"},te={key:0,class:"val-container"},ie=["src"],ae={key:1},se={key:1,class:"json-prop"},ne={key:1,class:"property-panel glass edge-panel"},oe={class:"panel-header"},le={class:"panel-content"},re={class:"prop-group"},ce={class:"id-badge"},de={key:0,class:"val-container"},he=["src"],ue={key:1},ve={key:1,class:"json-prop"},me={key:2,class:"property-panel glass combo-panel"},ge={class:"panel-header"},pe={class:"panel-content"},fe={class:"prop-group shadow-sm"},Me=["value"],be={class:"prop-group"},we={class:"member-list"},ye=["onClick"],xe={key:0,class:"more-hint"},ke=/* @__PURE__ */N(/* @__PURE__ */a({__name:"PropertyPanel",props:{nodeId:{},nodeMetadata:{},nodeX:{},nodeY:{},edgeId:{},edgeMetadata:{},combo:{}},emits:["update:nodeX","update:nodeY","update:nodeId","update:edgeId","update:combo","update:comboLabel","removeFromCombo"],setup(e,{emit:t}){const i=e=>"string"==typeof e&&e.startsWith("data:image/");return(t,a)=>null!==e.nodeId?(n(),o("div",J,[h("div",Q,[a[4]||(a[4]=h("h3",null,"Node Properties",-1)),h("button",{class:"close-btn",onClick:a[0]||(a[0]=e=>t.$emit("update:nodeId",null))},[m(z,{name:"x",size:"18"})])]),h("div",ee,[e.nodeMetadata&&e.nodeMetadata.data?(n(!0),o(l,{key:0},r(e.nodeMetadata.data,(t,a)=>(n(),o("div",{key:a,class:"prop-group"},[h("label",null,g(a),1),"object"!=typeof t?(n(),o("div",te,[i(t)?(n(),o("img",{key:0,src:t,class:"prop-image",style:d("backgroundImage"===a?{backgroundColor:e.nodeMetadata.data.color||"var(--primary)"}:{})},null,12,ie)):(n(),o("span",ae,g(t),1))])):(n(),o("pre",se,g(JSON.stringify(t,null,2)),1))]))),128)):p("",!0)])])):null!==e.edgeId?(n(),o("div",ne,[h("div",oe,[a[5]||(a[5]=h("h3",null,"Edge Properties",-1)),h("button",{class:"close-btn",onClick:a[1]||(a[1]=e=>t.$emit("update:edgeId",null))},[m(z,{name:"x",size:"18"})])]),h("div",le,[h("div",re,[a[6]||(a[6]=h("label",null,"ID",-1)),h("span",ce,g(e.edgeId),1)]),e.edgeMetadata&&e.edgeMetadata.data?(n(!0),o(l,{key:0},r(e.edgeMetadata.data,(t,a)=>(n(),o("div",{key:a,class:"prop-group"},[h("label",null,g(a),1),"object"!=typeof t?(n(),o("div",de,[i(t)?(n(),o("img",{key:0,src:t,class:"prop-image",style:d("backgroundImage"===a?{backgroundColor:e.edgeMetadata.data.color||"var(--secondary)"}:{})},null,12,he)):(n(),o("span",ue,g(t),1))])):(n(),o("pre",ve,g(JSON.stringify(t,null,2)),1))]))),128)):p("",!0)])])):e.combo?(n(),o("div",me,[h("div",ge,[a[7]||(a[7]=h("h3",null,"Group Properties",-1)),h("button",{class:"close-btn",onClick:a[2]||(a[2]=e=>t.$emit("update:combo",null))},[m(z,{name:"x",size:"18"})])]),h("div",pe,[h("div",fe,[a[8]||(a[8]=h("label",null,"Label",-1)),h("input",{type:"text",value:e.combo.label,class:"full-width",onInput:a[3]||(a[3]=e=>t.$emit("update:comboLabel",e.target.value))},null,40,Me)]),h("div",be,[h("label",null,"Members ("+g(e.combo.nodeIds.size)+")",1),h("div",we,[(n(!0),o(l,null,r(Array.from(e.combo.nodeIds).slice(0,50),e=>(n(),o("div",{key:e,class:"member-item"},[h("span",null,"Node "+g(e),1),h("button",{class:"remove-btn",onClick:i=>t.$emit("removeFromCombo",e)},[m(z,{name:"trash-2",size:"12"})],8,ye)]))),128)),e.combo.nodeIds.size>50?(n(),o("div",xe," + "+g(e.combo.nodeIds.size-50)+" more ",1)):p("",!0)])])])])):p("",!0)}}),[["__scopeId","data-v-7c0e24e3"]]),Ce={class:"search-icon"},Ee={key:0,class:"results-panel"},Ie=["onMousedown","onTouchstart"],_e={class:"node-icon"},Ae={class:"node-info"},Se={class:"node-label"},Re={class:"node-id"},Fe={key:1,class:"no-results"},Te=/* @__PURE__ */N(/* @__PURE__ */a({__name:"SearchBar",props:{nodes:{}},emits:["select"],setup(e,{emit:t}){const i=e,a=t,d=f(""),u=f(!1),v=f(null),C=f(window.innerWidth<768),E=()=>{C.value=window.innerWidth<768};b(()=>{window.addEventListener("resize",E)}),w(()=>{window.removeEventListener("resize",E)});const I=s(()=>{if(!d.value)return[];const e=d.value.toLowerCase();return i.nodes.filter(t=>t.label?.toLowerCase().includes(e)||t.id.toString().includes(e)).slice(0,10)}),_=e=>{a("select",e),d.value="",u.value=!1},A=()=>{C.value&&!u.value&&(u.value=!0,setTimeout(()=>v.value?.focus(),100))},S=()=>{d.value="",u.value=!1,v.value?.blur()},R=()=>{C.value||setTimeout(()=>{u.value=!1},200)};return(e,t)=>(n(),o("div",{class:M(["search-wrapper",{"mobile-expanded":u.value&&C.value,"is-mobile":C.value}])},[h("div",{class:M(["search-container glass",{expanded:u.value,"has-query":d.value.length>0}])},[h("div",{class:"search-input-wrapper",onClick:A},[h("span",Ce,[m(z,{name:"search",size:C.value?20:14},null,8,["size"])]),y(h("input",{ref_key:"inputRef",ref:v,"onUpdate:modelValue":t[0]||(t[0]=e=>d.value=e),placeholder:"Search nodes...",onFocus:t[1]||(t[1]=e=>u.value=!0),onBlur:R,onKeydown:t[2]||(t[2]=x(e=>u.value=!1,["esc"]))},null,544),[[k,d.value]]),d.value||C.value&&u.value?(n(),o("div",{key:0,class:"clear-btn",onClick:c(S,["stop"])},[m(z,{name:d.value?"x":"chevron-down",size:C.value?20:12},null,8,["name","size"])])):p("",!0)]),u.value&&I.value.length>0?(n(),o("div",Ee,[(n(!0),o(l,null,r(I.value,e=>(n(),o("div",{key:e.id,class:"result-item",onMousedown:t=>_(e.id),onTouchstart:t=>_(e.id)},[h("span",_e,[m(z,{name:"circle",size:"8"})]),h("div",Ae,[h("div",Se,g(e.label),1),h("div",Re,"ID: "+g(e.id),1)])],40,Ie))),128))])):u.value&&d.value?(n(),o("div",Fe," No nodes found ")):p("",!0)],2),C.value&&u.value?(n(),o("div",{key:0,class:"mobile-backdrop",onClick:S})):p("",!0)],2))}}),[["__scopeId","data-v-3fda8a90"]]),Le={key:0,class:"mobile-menu glass shadow-lg"},Pe={class:"drawer-header"},Be={key:0,class:"drawer-content"},Ne={key:1,class:"drawer-content"},ze={class:"help-header"},De={class:"help-content"},Ye={class:"key-badge"},Ve={class:"action-desc"},Ue=/* @__PURE__ */N(/* @__PURE__ */a({__name:"GraphCanvas",props:{data:{}},setup(e){const t=e,i=f(null),a=f(null),s=f(1e4),d=f(null),u=f(null),x=f(null),k=f(null),_=f(0),A=f("dark"),S=f(null),F=f(0),T=f(0),L=f(null),P=f(null),B=f("random"),N=f(!1),D=f(0),Y=f([]),V=f(!1),U=f(window.innerWidth<768),X=f(null),W=f(!1),Z=f(null),H=e=>{X.value===e?X.value=null:X.value=e},$=e=>{ge(e),X.value=null},G=()=>{W.value=!0,setTimeout(()=>{Z.value?.handleWrapperClick?.()},50)},q=()=>{U.value=window.innerWidth<768},J=[{key:"Shift + Drag",action:"Box Selection"},{key:"Ctrl + Click",action:"Multi Selection"},{key:"Right Click",action:"Radial Menu"},{key:"Scroll",action:"Zoom In/Out"},{key:"Drag",action:"Pan View"}],Q=[{id:"random",name:"Random",icon:"dices"},{id:"grid",name:"Grid",icon:"layout-grid"},{id:"circle",name:"Circle",icon:"circle"},{id:"spiral",name:"Spiral",icon:"spiral"},{id:"concentric",name:"Concentric",icon:"target"},{id:"radial",name:"Radial",icon:"atom"},{id:"hierarchy",name:"Hierarchy",icon:"git-branch"},{id:"force",name:"Force",icon:"sparkles"}];let ee,te,ie,ae=null;const se=()=>{A.value="dark"===A.value?"light":"dark",ee&&ee.setTheme(A.value),document.documentElement.classList.toggle("light","light"===A.value)},ne=()=>{null!==u.value&&ee&&ee.setNodePosition(u.value,F.value,T.value)};C(u,()=>(()=>{if(null!==u.value&&ee){const e=ee.getNodePosition(u.value);e&&(F.value=Number(e[0].toFixed(3)),T.value=Number(e[1].toFixed(3))),L.value=ee.getNodeMetadata(u.value)}else L.value=null})()),C(F,()=>ne()),C(T,()=>ne()),C(k,e=>{S.value=e&&ee?ee.getCombo(e):null}),C(S,e=>{null===e&&(k.value=null)});const oe=e=>{if(k.value&&ee){const t=ee.getCombo(k.value);t&&(ee.updateCombo(t.id,e,Array.from(t.nodeIds)),S.value={...t,label:e})}},le=e=>{if(k.value&&ee){ee.removeNodeFromCombo(k.value,e);const t=ee.getCombo(k.value);t&&(S.value={...t,nodeIds:new Set(t.nodeIds)})}},re=()=>{N.value=!N.value,ee&&ee.setFlowAnimation(N.value)},ce=e=>{if(ee){ee.selectNode(e);const t=ee.getNodePosition(e);t&&(ee.setCameraCenter(t[0],t[1]),ee.setCameraZoom(2))}W.value=!1},de=f({show:!1,x:0,y:0,type:"none",target:null}),he=f([]),ue=e=>{const t=i.value?.getBoundingClientRect();if(!t||!ee)return;const a=e.clientX-t.left,s=e.clientY-t.top,n=ee.pick(a,s);if(null!==n)de.value={show:!0,x:e.clientX,y:e.clientY,type:"node",target:n},he.value=[{label:"Delete",icon:"trash-2",action:"delete"},{label:"Color",icon:"palette",action:"color"},{label:"Pin",icon:"pin",action:"pin"},{label:"Info",icon:"info",action:"info"}],_.value>1&&he.value.push({label:"Group",icon:"box",action:"create-combo"});else{const t=ee.getEdgeAt(a,s);if(t)de.value={show:!0,x:e.clientX,y:e.clientY,type:"edge",target:t},he.value=[{label:"Hide",icon:"eye-off",action:"hide"},{label:"Weight",icon:"scale",action:"weight"},{label:"Reverse",icon:"refresh-cw",action:"reverse"}];else{const t=ee.pickCombo(a,s);t?(de.value={show:!0,x:e.clientX,y:e.clientY,type:"none",target:t},he.value=[{label:"Dissolve",icon:"zap",action:"dissolve-combo"},{label:"Add Selected",icon:"plus",action:"add-to-group"}]):de.value.show=!1}}},ve=e=>{if(ee)if("create-combo"===e){const e=ee.getSelectedNodeIds(),t=`combo-${Date.now()}`;ee.createCombo(t,`Group ${t.split("-")[1]}`,e),D.value++}else if("dissolve-combo"===e)de.value.target&&(ee.removeCombo(de.value.target),D.value--);else if("add-to-group"===e){const e=ee.getSelectedNodeIds();if(de.value.target)for(const t of e)ee.addNodeToCombo(de.value.target,t)}de.value.show=!1},me=e=>{if(!ee)return;s.value=e;const t=new Float32Array(2*e),i=new Float32Array(4*e),a=new Float32Array(e);te=new Float32Array(e);const n=/* @__PURE__ */new Map;for(let s=0;s<e;s++)t[2*s]=50*(Math.random()-.5),t[2*s+1]=50*(Math.random()-.5),i[4*s]=Math.random(),i[4*s+1]=Math.random(),i[4*s+2]=Math.random(),i[4*s+3]=1,a[s]=s,te[s]=.05,n.set(s,{label:`S-${s}`,width:50,height:50});const o=[];for(let s=0;s<5e4;s++)o.push(Math.floor(Math.random()*e)),o.push(Math.floor(Math.random()*e));ie=new Uint32Array(o),ee.setData(t,i,a,n,ie,/* @__PURE__ */new Map),ae&&ae.postMessage({type:"init",data:{nodeCount:e,positions:t,nodeRadii:te,edgeIndices:ie}}),ee.fitToView()},ge=e=>{B.value=e,ae&&ae.postMessage({type:"layout",data:{layoutType:e,nodeRadii:te,edgeIndices:ie}})};return b(()=>{if(window.addEventListener("resize",q),i.value&&a.value){ee=new R(i.value,a.value);const e=t.data.nodes||[],n=t.data.edges||[],o=e.length;s.value=o;const l=new Float32Array(2*o),r=new Float32Array(4*o),c=new Float32Array(o);te=new Float32Array(o);const h=/* @__PURE__ */new Map,v=/* @__PURE__ */new Map,m=e=>{const t=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return t?[parseInt(t[1],16)/255,parseInt(t[2],16)/255,parseInt(t[3],16)/255]:[Math.random(),Math.random(),Math.random()]};e.forEach((e,t)=>{const i=e.data,a=e.position||{x:0,y:0};v.set(i.id,t),l[2*t]=((a.x??2500)-2500)/500,l[2*t+1]=((a.y??2500)-2500)/500;const s=i.color||"#000000",n=m(s);r[4*t]=n[0],r[4*t+1]=n[1],r[4*t+2]=n[2],r[4*t+3]=1,c[t]=t;const o=i.width||50,d=i.height||50;te[t]=Math.max(o,d)/1e3;const u={label:i.label||i.code||`Node ${i.id}`,image:i.backgroundImage,width:o,height:d,data:i};if(i.backgroundImage){const e=new Image;e.src=i.backgroundImage,e.onload=()=>{const t=document.createElement("canvas"),i=128;t.width=i,t.height=i;const a=t.getContext("2d");a&&(a.beginPath(),a.arc(64,64,64,0,2*Math.PI),a.clip(),a.filter="grayscale(100%) brightness(1000%)",a.drawImage(e,0,0,i,i),u.processedImageElement=t)},u.imageElement=e}h.set(t,u)}),Y.value=Array.from(h.entries()).map(([e,t])=>({id:e,label:t.label}));const g=[],p=/* @__PURE__ */new Map;n.forEach(e=>{const t=e.data.source,i=e.data.target,a=v.get(t),s=v.get(i);if(void 0!==a&&void 0!==s){g.push(a),g.push(s);const t=`${a}-${s}`;p.set(t,{label:e.data.label,data:e.data})}}),ie=new Uint32Array(g),ee.setData(l,r,c,h,ie,p),ae=new Worker(new URL("/assets/layout.worker-CBxeMMC3.js",import.meta.url),{type:"module"}),ae.postMessage({type:"init",data:{nodeCount:o,positions:l,nodeRadii:te,edgeIndices:ie}}),ae.onmessage=e=>{"layout-complete"===e.data.type&&(e=>{if(!ee)return;const t=s.value,i=new Float32Array(2*t);for(let s=0;s<t;s++){const e=ee.getNodePosition(s);e&&(i[2*s]=e[0],i[2*s+1]=e[1])}const a=performance.now(),n=new Float32Array(2*t),o=s=>{const l=s-a,r=Math.min(l/1e3,1),c=r<.5?4*r**3:1-Math.pow(-2*r+2,3)/2;if(i&&e)for(let a=0;a<2*t;a++)n[a]=i[a]+(e[a]-i[a])*c;ee.updatePositions(n),r<1?requestAnimationFrame(o):ee.fitToView()};requestAnimationFrame(o)})(e.data.positions)},window.addEventListener("mousedown",()=>{de.value.show=!1}),i.value.addEventListener("node-picked",e=>{d.value=e.detail}),i.value.addEventListener("node-selected",e=>{u.value=e.detail,null!==e.detail&&(x.value=null,k.value=null)}),i.value.addEventListener("edge-selected",e=>{x.value=e.detail,null!==e.detail?(u.value=null,k.value=null,P.value=ee.getEdgeMetadata(e.detail)):P.value=null}),i.value.addEventListener("combo-selected",e=>{k.value=e.detail,null!==e.detail&&(u.value=null,x.value=null)}),i.value.addEventListener("nodes-selected",e=>{_.value=e.detail.length}),i.value.addEventListener("node-moved",e=>{e.detail.id===u.value&&(F.value=Number(e.detail.x.toFixed(3)),T.value=Number(e.detail.y.toFixed(3)))})}}),w(()=>{window.removeEventListener("resize",q),ae&&ae.terminate()}),(e,t)=>(n(),o("div",{class:M(["container",A.value])},[h("canvas",{ref_key:"canvasRef",ref:i,class:"main-canvas",onContextmenu:c(ue,["prevent"])},null,544),h("canvas",{ref_key:"overlayCanvasRef",ref:a,class:"overlay-canvas"},null,512),U.value?(n(),o("div",Le,[h("button",{class:M(["menu-btn",{active:"layouts"===X.value}]),onClick:t[0]||(t[0]=e=>H("layouts"))},[m(z,{name:"layout",size:"20"}),t[22]||(t[22]=h("span",null,"Layout",-1))],2),h("button",{class:M(["menu-btn",{active:"view"===X.value}]),onClick:t[1]||(t[1]=e=>H("view"))},[m(z,{name:"eye",size:"20"}),t[23]||(t[23]=h("span",null,"View",-1))],2),t[25]||(t[25]=h("div",{class:"menu-divider"},null,-1)),h("button",{class:"menu-btn search-trigger",onClick:G},[m(z,{name:"search",size:"20"}),t[24]||(t[24]=h("span",null,"Search",-1))])])):p("",!0),U.value&&X.value?(n(),o("div",{key:1,class:"drawer-overlay",onClick:t[8]||(t[8]=e=>X.value=null)},[h("div",{class:"mobile-drawer glass shadow-2xl",onClick:t[7]||(t[7]=c(()=>{},["stop"]))},[t[26]||(t[26]=h("div",{class:"drawer-handle"},null,-1)),h("div",Pe,[h("h3",null,g("layouts"===X.value?"Graph Layouts":"View Controls"),1),h("button",{class:"drawer-close",onClick:t[2]||(t[2]=e=>X.value=null)},[m(z,{name:"x",size:"20"})])]),"layouts"===X.value?(n(),o("div",Be,[m(K,{layouts:Q,currentLayout:B.value,flowEnabled:N.value,onRunLayout:$,onToggleFlow:re},null,8,["currentLayout","flowEnabled"])])):p("",!0),"view"===X.value?(n(),o("div",Ne,[m(j,{theme:A.value,onToggleTheme:se,onFit:t[3]||(t[3]=e=>E(ee)?.fitToView()),onZoomIn:t[4]||(t[4]=e=>E(ee)?.zoomIn()),onZoomOut:t[5]||(t[5]=e=>E(ee)?.zoomOut()),onStress:t[6]||(t[6]=e=>me(1e5))},null,8,["theme"])])):p("",!0)])])):p("",!0),y(m(Te,{ref_key:"searchBarRef",ref:Z,nodes:Y.value,onSelect:ce},null,8,["nodes"]),[[I,!U.value||W.value]]),U.value?p("",!0):(n(),v(j,{key:2,theme:A.value,onToggleTheme:se,onFit:t[9]||(t[9]=e=>E(ee)?.fitToView()),onZoomIn:t[10]||(t[10]=e=>E(ee)?.zoomIn()),onZoomOut:t[11]||(t[11]=e=>E(ee)?.zoomOut()),onStress:t[12]||(t[12]=e=>me(1e5))},null,8,["theme"])),U.value?p("",!0):(n(),v(K,{key:3,layouts:Q,currentLayout:B.value,flowEnabled:N.value,onRunLayout:ge,onToggleFlow:re},null,8,["currentLayout","flowEnabled"])),m(O,{show:de.value.show,x:de.value.x,y:de.value.y,type:de.value.type,items:he.value,onAction:ve},null,8,["show","x","y","type","items"]),m(ke,{nodeId:u.value,"onUpdate:nodeId":t[13]||(t[13]=e=>u.value=e),nodeMetadata:L.value,nodeX:F.value,"onUpdate:nodeX":t[14]||(t[14]=e=>F.value=e),nodeY:T.value,"onUpdate:nodeY":t[15]||(t[15]=e=>T.value=e),edgeId:x.value,"onUpdate:edgeId":t[16]||(t[16]=e=>x.value=e),edgeMetadata:P.value,combo:S.value,"onUpdate:combo":t[17]||(t[17]=e=>S.value=e),"onUpdate:comboLabel":oe,onRemoveFromCombo:le},null,8,["nodeId","nodeMetadata","nodeX","nodeY","edgeId","edgeMetadata","combo"]),U.value?p("",!0):(n(),o("div",{key:4,class:"help-trigger glass-interactive",onClick:t[18]||(t[18]=e=>V.value=!0),title:"Keyboard Shortcuts"},[m(z,{name:"info",size:"18"})])),V.value?(n(),o("div",{key:5,class:"help-modal-overlay",onClick:t[21]||(t[21]=e=>V.value=!1)},[h("div",{class:"help-modal glass",onClick:t[20]||(t[20]=c(()=>{},["stop"]))},[h("div",ze,[t[27]||(t[27]=h("h3",null,"Keyboard Shortcuts",-1)),h("button",{class:"close-btn",onClick:t[19]||(t[19]=e=>V.value=!1)},[m(z,{name:"x",size:"20"})])]),h("div",De,[(n(),o(l,null,r(J,e=>h("div",{key:e.key,class:"shortcut-row"},[h("span",Ye,g(e.key),1),h("span",Ve,g(e.action),1)])),64))])])])):p("",!0)],2))}}),[["__scopeId","data-v-87730b5c"]]),Oe=(e,t)=>({nodes:e,edges:t});export{Ue as GraphCanvas,R as GraphEngine,Oe as createGraphData};
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("gl-matrix"),require("vue")):"function"==typeof define&&define.amd?define(["exports","gl-matrix","vue"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).WebGLGraph={},e.glMatrix,e.Vue)}(this,function(e,t,n){"use strict";var a="undefined"!=typeof document?document.currentScript:null;class o{gl;constructor(e){this.gl=e}pickNode(e){const t=this.gl,{mouseX:n,mouseY:a,canvas:o,program:i,pickingFramebuffer:s,vao:l,viewMatrix:r,pointSize:c,nodeCount:d}=e;t.bindFramebuffer(t.FRAMEBUFFER,s),t.viewport(0,0,o.width,o.height),t.clearColor(0,0,0,0),t.clear(t.COLOR_BUFFER_BIT),t.useProgram(i),t.uniformMatrix3fv(t.getUniformLocation(i,"u_matrix"),!1,r),t.uniform1f(t.getUniformLocation(i,"u_pointSize"),c),t.uniform1i(t.getUniformLocation(i,"u_pickingMode"),1),t.bindVertexArray(l),t.drawArrays(t.POINTS,0,d);const h=new Uint8Array(4),u=window.devicePixelRatio;if(t.readPixels(Math.floor(n*u),Math.floor(o.height-a*u),1,1,t.RGBA,t.UNSIGNED_BYTE,h),t.bindFramebuffer(t.FRAMEBUFFER,null),0===h[3])return null;return(h[0]<<16|h[1]<<8|h[2])-1}pickEdge(e){const{mouseX:n,mouseY:a,edgeIndices:o,positions:i,nodeCount:s,viewMatrix:l,canvasW:r,canvasH:c}=e;if(!o||!i)return null;const d=window.devicePixelRatio,h=n*d,u=a*d,m=5*d,v=t.mat3.invert(t.mat3.create(),l);if(!v)return null;const g=t.vec3.fromValues(h/r*2-1,-(u/c*2-1),1);t.vec3.transformMat3(g,g,v);const p=g[0],f=g[1],M=2*m/Math.abs(l[0]+l[4]);for(let k=0;k<o.length/2;k++){const e=o[2*k],n=o[2*k+1];if(e>=s||n>=s)continue;const a=i[2*e],d=i[2*e+1],v=i[2*n],g=i[2*n+1];if(p<(a<v?a:v)-M||p>(a>v?a:v)+M||f<(d<g?d:g)-M||f>(d>g?d:g)+M)continue;const w=this.project(a,d,l,r,c),y=this.project(v,g,l,r,c);if(this.distToSegment(t.vec2.fromValues(h,u),w,y)<m)return`${e}-${n}`}return null}pickCombo(e){const{mouseX:t,mouseY:n,combos:a,positions:o,nodeCount:i,viewMatrix:s,canvasW:l,canvasH:r}=e;if(!o)return null;const c=window.devicePixelRatio,d=t*c,h=n*c;for(const u of a.values()){let e=1/0,t=1/0,n=-1/0,a=-1/0,m=!1;for(const c of u.nodeIds){if(c>=i)continue;const d=this.project(o[2*c],o[2*c+1],s,l,r);e=Math.min(e,d[0]),t=Math.min(t,d[1]),n=Math.max(n,d[0]),a=Math.max(a,d[1]),m=!0}if(m){const o=30*c;if(d>=e-o&&d<=n+o&&h>=t-o&&h<=a+o)return u.id}}return null}distToSegment(e,n,a){const o=t.vec2.dist(n,a)**2;if(0===o)return t.vec2.dist(e,n);let i=((e[0]-n[0])*(a[0]-n[0])+(e[1]-n[1])*(a[1]-n[1]))/o;i=Math.max(0,Math.min(1,i));const s=t.vec2.fromValues(n[0]+i*(a[0]-n[0]),n[1]+i*(a[1]-n[1]));return t.vec2.dist(e,s)}project(e,n,a,o,i){const s=t.vec3.fromValues(e,n,1);return t.vec3.transformMat3(s,s,a),t.vec2.fromValues((.5*s[0]+.5)*o,(.5*-s[1]+.5)*i)}}class i{canvas;ctx;constructor(e,t){this.canvas=e,this.ctx=t}_posScratch=t.vec3.create();_spScratch=t.vec2.create();_s1Scratch=t.vec2.create();_s2Scratch=t.vec2.create();project(e,n,a,o){return t.vec3.set(this._posScratch,e,n,1),t.vec3.transformMat3(this._posScratch,this._posScratch,a),o[0]=(.5*this._posScratch[0]+.5)*this.canvas.width,o[1]=(.5*-this._posScratch[1]+.5)*this.canvas.height,o}render(e){const{ctx:n,canvas:a}=this,{positions:o,nodeCount:i,edgeCount:s,edgeIndices:l,metadata:r,combos:c,theme:d,zoom:h,viewMatrix:u,selectedNodeIds:m,selectedEdgeId:v,selectedComboId:g,hoveredNodeId:p,isBoxSelecting:f,selectionStart:M,selectionEnd:k,isFlowAnimating:w}=e;if(!o)return;const y=t.mat3.invert(t.mat3.create(),u);if(!y)return;const b=t.vec3.fromValues(-1.1,1.1,1),E=t.vec3.fromValues(1.1,-1.1,1);t.vec3.transformMat3(b,b,y),t.vec3.transformMat3(E,E,y);const x=Math.min(b[0],E[0]),B=Math.max(b[0],E[0]),N=Math.min(b[1],E[1]),C=Math.max(b[1],E[1]);n.clearRect(0,0,a.width,a.height);const V=window.devicePixelRatio,S=40*h*V;f&&this.drawMarquee(M,k,V),this.drawCombos(c,o,i,u,g,d,V),this.drawNodeHighlights(m,i,o,u,S,V),this.drawEdgeHighlight(v,l,o,u,V);const I=h<.1;w&&!(h<.3)&&s<5e4&&this.drawFlow(l,s,o,u,d,V,x,B,N,C),null!==p&&l&&this.drawHoverHighlight(p,l,s,o,u,d,V),I||this.drawNodeLabels(i,r,o,u,d,V,S,h,x,B,N,C)}drawMarquee(e,t,n){const a=Math.min(e[0],t[0]),o=Math.min(e[1],t[1]),i=Math.abs(e[0]-t[0]),s=Math.abs(e[1]-t[1]);this.ctx.strokeStyle="rgba(0, 255, 204, 0.8)",this.ctx.fillStyle="rgba(0, 255, 204, 0.1)",this.ctx.lineWidth=1*n,this.ctx.strokeRect(a,o,i,s),this.ctx.fillRect(a,o,i,s)}drawCombos(e,t,n,a,o,i,s){const l=this.ctx,r=this._spScratch;for(const c of e.values()){let e=1/0,d=1/0,h=-1/0,u=-1/0,m=!1;for(const o of c.nodeIds){if(o>=n)continue;const i=this.project(t[2*o],t[2*o+1],a,r);e=Math.min(e,i[0]),d=Math.min(d,i[1]),h=Math.max(h,i[0]),u=Math.max(u,i[1]),m=!0}if(m){const t=30*s,n=e-t,a=d-t,r=h-e+2*t,m=u-d+2*t;if(n+r<0||n>this.canvas.width||a+m<0||a>this.canvas.height)continue;const v=o===c.id;l.save(),l.beginPath();const g=16*s;l.moveTo(n+g,a),l.arcTo(n+r,a,n+r,a+m,g),l.arcTo(n+r,a+m,n,a+m,g),l.arcTo(n,a+m,n,a,g),l.arcTo(n,a,n+r,a,g),l.closePath(),l.fillStyle=v?"rgba(0, 255, 204, 0.15)":"dark"===i?"rgba(0, 255, 204, 0.05)":"rgba(0, 170, 136, 0.05)",l.strokeStyle=v?"rgba(0, 255, 204, 0.8)":"dark"===i?"rgba(0, 255, 204, 0.2)":"rgba(0, 170, 136, 0.2)",l.lineWidth=(v?3:2)*s,l.setLineDash(v?[]:[5*s,5*s]),l.fill(),l.stroke(),l.setLineDash([]),l.fillStyle=v||"dark"===i?"#00ffcc":"#00aa88",l.font=`bold ${14*s}px Inter, sans-serif`,l.fillText(c.label.toUpperCase(),n+10*s,a-10*s),l.restore()}}}drawNodeHighlights(e,t,n,a,o,i){const s=this.ctx,l=this._spScratch;s.strokeStyle="#00ffcc",s.lineWidth=2*i;for(const r of e)r>=t||(this.project(n[2*r],n[2*r+1],a,l),l[0]<-50||l[0]>this.canvas.width+50||l[1]<-50||l[1]>this.canvas.height+50||(s.beginPath(),s.arc(l[0],l[1],.7*o,0,2*Math.PI),s.stroke()))}drawEdgeHighlight(e,t,n,a,o){if(!e||!t)return;const i=this.ctx,s=e.split("-"),l=Number(s[0]),r=Number(s[1]);if(isNaN(l)||isNaN(r))return;const c=this._s1Scratch,d=this._s2Scratch;this.project(n[2*l],n[2*l+1],a,c),this.project(n[2*r],n[2*r+1],a,d);const h=Math.min(c[0],d[0]),u=Math.max(c[0],d[0]),m=Math.min(c[1],d[1]),v=Math.max(c[1],d[1]);u<-20||h>this.canvas.width+20||v<-20||m>this.canvas.height+20||(i.strokeStyle="#ff00ff",i.lineWidth=3*o,i.beginPath(),i.moveTo(c[0],c[1]),i.lineTo(d[0],d[1]),i.stroke())}drawFlow(e,t,n,a,o,i,s,l,r,c){if(!e)return;const d=this.ctx,h=.002*performance.now(),u=this._s1Scratch,m=this._s2Scratch,v=Math.max(1,Math.floor(t/15e3));for(let g=0;g<t/2;g+=v){const t=e[2*g],v=e[2*g+1],p=n[2*t],f=n[2*t+1],M=n[2*v],k=n[2*v+1];if((p>M?p:M)<s||(p<M?p:M)>l||(f>k?f:k)<r||(f<k?f:k)>c)continue;this.project(p,f,a,u),this.project(M,k,a,m);const w=Math.min(u[0],m[0]),y=Math.max(u[0],m[0]),b=Math.min(u[1],m[1]),E=Math.max(u[1],m[1]);if(y<-20||w>this.canvas.width+20||E<-20||b>this.canvas.height+20)continue;const x=(h+.1*g%1)%1,B=u[0]+(m[0]-u[0])*x,N=u[1]+(m[1]-u[1])*x;d.beginPath(),d.arc(B,N,2*i,0,2*Math.PI),d.fillStyle="dark"===o?"#00ffcc":"#00aa88",d.shadowBlur=4*i,d.shadowColor=d.fillStyle,d.fill(),d.shadowBlur=0}}drawHoverHighlight(e,t,n,a,o,i,s){const l=this.ctx;l.lineWidth=2*s,l.strokeStyle="dark"===i?"rgba(0, 255, 204, 0.6)":"rgba(0, 170, 136, 0.5)";const r=this._s1Scratch,c=this._s2Scratch;for(let d=0;d<n/2;d++){const n=t[2*d],i=t[2*d+1];n!==e&&i!==e||(this.project(a[2*n],a[2*n+1],o,r),this.project(a[2*i],a[2*i+1],o,c),l.beginPath(),l.moveTo(r[0],r[1]),l.lineTo(c[0],c[1]),l.stroke())}}drawNodeLabels(e,t,n,a,o,i,s,l,r,c,d,h){const u=this.ctx;u.textAlign="center",u.textBaseline="top";const m=this._spScratch;let v=0;for(let g=0;g<e&&!(v>200);g++){const e=n[2*g],p=n[2*g+1];if(e<r||e>c||p<d||p>h)continue;const f=t.get(g);if(!f)continue;this.project(e,p,a,m);const M=m[0],k=m[1];if(M<-50||M>this.canvas.width+50||k<-50||k>this.canvas.height+50)continue;v++;const w=.5*s,y=l>.6;if(s>12*i&&(u.beginPath(),u.arc(M,k,w,0,2*Math.PI),u.strokeStyle="dark"===o?"rgba(255, 255, 255, 0.8)":"rgba(0, 0, 0, 0.8)",u.lineWidth=1*i,u.stroke()),y)if(f.processedImageElement){const e=s*.7;u.drawImage(f.processedImageElement,M-e/2,k-e/2,e,e)}else if(f.imageElement&&f.imageElement.complete&&0!==f.imageElement.naturalWidth){const e=s*.7;u.save(),u.beginPath(),u.arc(M,k,.9*w,0,2*Math.PI),u.clip(),u.filter="grayscale(100%) brightness(1000%)",u.drawImage(f.imageElement,M-e/2,k-e/2,e,e),u.restore()}else f.icon&&(u.font=.6*s+"px serif",u.fillStyle="dark"===o?"white":"black",u.fillText(f.icon,M,k-.2*s));if(!(l<.5)&&f.label){const e=w+8*i;u.font=12*i+"px Inter, sans-serif",u.fillStyle="dark"===o?"white":"black",u.fillText(f.label,M,k+e)}}}}class s{lastMouse=t.vec2.create();isPanning=!1;engine;canvas;lastTouchDistance=0;lastTouchMidpoint=t.vec2.create();isTouching=!1;touchStartTime=0;touchStartPos=t.vec2.create();longPressTimer=null;isLongPress=!1;constructor(e,t){this.engine=e,this.canvas=t,this.setupListeners()}setupListeners(){this.canvas.addEventListener("mousedown",e=>this.handleMouseDown(e)),window.addEventListener("mousemove",e=>this.handleMouseMove(e)),window.addEventListener("mouseup",()=>this.handleMouseUp()),this.canvas.addEventListener("wheel",e=>this.handleWheel(e),{passive:!1}),this.canvas.addEventListener("touchstart",e=>this.handleTouchStart(e),{passive:!1}),this.canvas.addEventListener("touchmove",e=>this.handleTouchMove(e),{passive:!1}),this.canvas.addEventListener("touchend",e=>this.handleTouchEnd(e)),this.canvas.addEventListener("touchcancel",e=>this.handleTouchEnd(e))}handleMouseDown(e){const n=this.canvas.getBoundingClientRect(),a=e.clientX-n.left,o=e.clientY-n.top,i=this.engine.getState();if(e.shiftKey)return this.engine.updateInteractionState({isBoxSelecting:!0,selectionStart:t.vec2.fromValues(a,o),selectionEnd:t.vec2.fromValues(a,o)}),void this.engine.render();const s=this.engine.pick(a,o);if(null!==s){const t=i.selectedNodeIds.has(s);e.ctrlKey||e.metaKey||t||i.selectedNodeIds.clear(),i.selectedNodeIds.add(s),this.engine.updateInteractionState({isMultiDragging:!0,draggedNodeId:null}),this.engine.syncDragOffsets(a,o),this.canvas.dispatchEvent(new CustomEvent("node-selected",{detail:s})),this.canvas.dispatchEvent(new CustomEvent("nodes-selected",{detail:Array.from(i.selectedNodeIds)}))}else{i.selectedNodeIds.clear();const e=this.engine.getEdgeAt(a,o),t=this.engine.pickCombo(a,o);this.engine.updateInteractionState({selectedEdgeId:e,selectedComboId:t}),this.canvas.dispatchEvent(new CustomEvent("edge-selected",{detail:e})),this.canvas.dispatchEvent(new CustomEvent("combo-selected",{detail:t})),this.canvas.dispatchEvent(new CustomEvent("nodes-selected",{detail:[]})),this.canvas.dispatchEvent(new CustomEvent("node-selected",{detail:null})),e||t||(this.isPanning=!0)}t.vec2.set(this.lastMouse,e.clientX,e.clientY),this.engine.render()}handleMouseMove(e){const n=this.canvas.getBoundingClientRect(),a=e.clientX-n.left,o=e.clientY-n.top,i=this.engine.getState();if(i.isBoxSelecting)return this.engine.updateInteractionState({selectionEnd:t.vec2.fromValues(a,o)}),void this.engine.render();if(i.isMultiDragging||null!==i.draggedNodeId)this.engine.handleDragging(a,o);else if(this.isPanning){const n=(e.clientX-this.lastMouse[0])/(this.canvas.width/2),a=-(e.clientY-this.lastMouse[1])/(this.canvas.height/2);this.engine.pan(n,a),t.vec2.set(this.lastMouse,e.clientX,e.clientY)}else{const e=i.hoveredNodeId,t=this.engine.pick(a,o);t!==e&&(this.engine.updateInteractionState({hoveredNodeId:t}),this.engine.render(),this.canvas.dispatchEvent(new CustomEvent("node-hovered",{detail:t})))}}handleMouseUp(){this.engine.getState().isBoxSelecting&&this.engine.performBoxSelection(),this.isPanning=!1,this.engine.updateInteractionState({isBoxSelecting:!1,isMultiDragging:!1,draggedNodeId:null}),this.engine.render()}handleWheel(e){e.preventDefault();const t=this.canvas.getBoundingClientRect(),n=e.clientX-t.left,a=e.clientY-t.top,o=.001*-e.deltaY;this.engine.zoomAt(n,a,o)}handleTouchStart(e){if(e.preventDefault(),this.isTouching=!0,this.touchStartTime=Date.now(),this.isLongPress=!1,1===e.touches.length){const n=e.touches[0],a=this.canvas.getBoundingClientRect(),o=n.clientX-a.left,i=n.clientY-a.top;t.vec2.set(this.touchStartPos,o,i),t.vec2.set(this.lastMouse,n.clientX,n.clientY),this.longPressTimer=window.setTimeout(()=>{this.isLongPress=!0,this.triggerContextMenu(n.clientX,n.clientY)},500);const s=this.engine.pick(o,i),l=this.engine.getState();null!==s&&(l.selectedNodeIds.has(s)||(l.selectedNodeIds.clear(),l.selectedNodeIds.add(s)),this.engine.updateInteractionState({isMultiDragging:!0,draggedNodeId:null}),this.engine.syncDragOffsets(o,i),this.canvas.dispatchEvent(new CustomEvent("node-selected",{detail:s})))}else if(2===e.touches.length){this.clearLongPress();const n=e.touches[0],a=e.touches[1];this.lastTouchDistance=t.vec2.distance(t.vec2.fromValues(n.clientX,n.clientY),t.vec2.fromValues(a.clientX,a.clientY)),t.vec2.set(this.lastTouchMidpoint,(n.clientX+a.clientX)/2,(n.clientY+a.clientY)/2)}}handleTouchMove(e){if(e.preventDefault(),this.isTouching){if(1===e.touches.length){const n=e.touches[0],a=this.canvas.getBoundingClientRect(),o=n.clientX-a.left,i=n.clientY-a.top;if(t.vec2.distance(this.touchStartPos,t.vec2.fromValues(o,i))>10&&this.clearLongPress(),this.isLongPress)return;if(this.engine.getState().isMultiDragging)this.engine.handleDragging(o,i);else{const e=(n.clientX-this.lastMouse[0])/(this.canvas.width/2),t=-(n.clientY-this.lastMouse[1])/(this.canvas.height/2);this.engine.pan(e,t)}t.vec2.set(this.lastMouse,n.clientX,n.clientY)}else if(2===e.touches.length){this.clearLongPress();const n=e.touches[0],a=e.touches[1],o=t.vec2.distance(t.vec2.fromValues(n.clientX,n.clientY),t.vec2.fromValues(a.clientX,a.clientY)),i=t.vec2.fromValues((n.clientX+a.clientX)/2,(n.clientY+a.clientY)/2),s=o/this.lastTouchDistance,l=this.canvas.getBoundingClientRect(),r=i[0]-l.left,c=i[1]-l.top;this.engine.zoomAt(r,c,s-1);const d=(i[0]-this.lastTouchMidpoint[0])/(this.canvas.width/2),h=-(i[1]-this.lastTouchMidpoint[1])/(this.canvas.height/2);this.engine.pan(d,h),this.lastTouchDistance=o,t.vec2.copy(this.lastTouchMidpoint,i)}this.engine.render()}}handleTouchEnd(e){if(this.isTouching=!1,this.clearLongPress(),0===e.touches.length&&!this.isLongPress){const n=Date.now()-this.touchStartTime,a=e.changedTouches[0],o=this.canvas.getBoundingClientRect(),i=a.clientX-o.left,s=a.clientY-o.top,l=t.vec2.distance(this.touchStartPos,t.vec2.fromValues(i,s));if(n<250&&l<10){const e=this.engine.pick(i,s);this.engine.selectNode(e)}}this.engine.updateInteractionState({isMultiDragging:!1}),this.engine.render()}clearLongPress(){null!==this.longPressTimer&&(window.clearTimeout(this.longPressTimer),this.longPressTimer=null)}triggerContextMenu(e,t){const n=new MouseEvent("contextmenu",{clientX:e,clientY:t,bubbles:!0,cancelable:!0});this.canvas.dispatchEvent(n)}}class l{gl;pickingEngine;overlayManager;program=null;edgeProgram=null;viewMatrix=t.mat3.create();vao=null;edgeVao=null;positionBuffer=null;colorBuffer=null;idBuffer=null;edgeIndexBuffer=null;pickingFramebuffer=null;pickingTexture=null;uMatrixLoc=null;uPointSizeLoc=null;uPickingModeLoc=null;uEdgeMatrixLoc=null;uEdgeColorLoc=null;nodeCount=0;edgeCount=0;positions=null;metadata=new Map;edgeIndices=null;edgeMetadata=new Map;combos=new Map;theme="dark";static MAX_ZOOM=100;static MIN_ZOOM=1e-4;state={zoom:1,offset:t.vec2.fromValues(0,0),selectedNodeIds:new Set,selectedEdgeId:null,selectedComboId:null,hoveredNodeId:null,isBoxSelecting:!1,selectionStart:t.vec2.create(),selectionEnd:t.vec2.create(),isMultiDragging:!1,draggedNodeId:null};dragOffsets=new Map;isFlowAnimating=!1;canvas;overlayCanvas;constructor(e,t){this.canvas=e,this.overlayCanvas=t;const n=e.getContext("webgl2",{antialias:!0,stencil:!0});if(!n)throw new Error("WebGL2 not supported");this.gl=n;const a=t.getContext("2d");if(!a)throw new Error("Canvas 2D not supported");this.pickingEngine=new o(n),this.overlayManager=new i(t,a),this.initShaders(),this.initBuffers(),this.initPicking(),this.updateMatrix(),new s(this,e),this.handleResize(),window.addEventListener("resize",()=>this.handleResize())}setData(e,t,n,a,o,i){this.positions=e,this.nodeCount=n.length,this.metadata=a;const s=this.gl;s.bindBuffer(s.ARRAY_BUFFER,this.positionBuffer),s.bufferData(s.ARRAY_BUFFER,e,s.DYNAMIC_DRAW),s.bindBuffer(s.ARRAY_BUFFER,this.colorBuffer),s.bufferData(s.ARRAY_BUFFER,t,s.STATIC_DRAW),s.bindBuffer(s.ARRAY_BUFFER,this.idBuffer),s.bufferData(s.ARRAY_BUFFER,n,s.STATIC_DRAW),o&&(this.edgeIndices=o,this.edgeCount=o.length,s.bindBuffer(s.ELEMENT_ARRAY_BUFFER,this.edgeIndexBuffer),s.bufferData(s.ELEMENT_ARRAY_BUFFER,o,s.STATIC_DRAW)),i&&(this.edgeMetadata=i),this.render()}updatePositions(e){this.positions=e;const t=this.gl;t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer),t.bufferSubData(t.ARRAY_BUFFER,0,e),this.render()}setNodePosition(e,t,n){if(!this.positions||e>=this.nodeCount)return;this.positions[2*e]=t,this.positions[2*e+1]=n;const a=this.gl;a.bindBuffer(a.ARRAY_BUFFER,this.positionBuffer),a.bufferSubData(a.ARRAY_BUFFER,2*e*4,this.positions.subarray(2*e,2*e+2)),this.render()}getNodePosition(e){return!this.positions||e>=this.nodeCount?null:t.vec2.fromValues(this.positions[2*e],this.positions[2*e+1])}setFlowAnimation(e){if(this.isFlowAnimating=e,e){const e=()=>{this.isFlowAnimating&&(this.render(),requestAnimationFrame(e))};requestAnimationFrame(e)}else this.render()}setTheme(e){this.theme=e,this.render()}createCombo(e,t,n){this.combos.set(e,{id:e,label:t,nodeIds:new Set(n)}),this.render()}removeCombo(e){this.combos.delete(e),this.render()}updateCombo(e,t,n){const a=this.combos.get(e);a&&(a.label=t,a.nodeIds=new Set(n),this.render())}getCombo(e){return this.combos.get(e)}getSelectedNodeIds(){return Array.from(this.state.selectedNodeIds)}getNodeMetadata(e){return this.metadata.get(e)}getEdgeMetadata(e){return this.edgeMetadata.get(e)}addNodeToCombo(e,t){const n=this.combos.get(e);n&&(n.nodeIds.add(t),this.render())}removeNodeFromCombo(e,t){const n=this.combos.get(e);n&&(n.nodeIds.delete(t),this.render())}render(){const e=this.gl;if(!this.program)return;this.updateMatrix();const t="dark"===this.theme?.05:.95;e.clearColor(t,t,t,1),e.clear(e.COLOR_BUFFER_BIT),this.edgeCount>0&&this.edgeProgram&&(e.useProgram(this.edgeProgram),e.uniformMatrix3fv(this.uEdgeMatrixLoc,!1,this.viewMatrix),e.uniform4fv(this.uEdgeColorLoc,"dark"===this.theme?[1,1,1,.15]:[0,0,0,.1]),e.bindVertexArray(this.edgeVao),e.drawElements(e.LINES,this.edgeCount,e.UNSIGNED_INT,0)),e.useProgram(this.program),e.uniformMatrix3fv(this.uMatrixLoc,!1,this.viewMatrix),e.uniform1f(this.uPointSizeLoc,40*this.state.zoom*window.devicePixelRatio),e.uniform1i(this.uPickingModeLoc,0),e.bindVertexArray(this.vao),e.drawArrays(e.POINTS,0,this.nodeCount),this.renderOverlay()}renderOverlay(){this.overlayManager.render({...this.state,positions:this.positions,nodeCount:this.nodeCount,edgeCount:this.edgeCount,edgeIndices:this.edgeIndices,metadata:this.metadata,edgeMetadata:this.edgeMetadata,combos:this.combos,theme:this.theme,viewMatrix:this.viewMatrix,isFlowAnimating:this.isFlowAnimating})}getState(){return this.state}updateInteractionState(e){Object.assign(this.state,e)}pick(e,t){return this.program&&this.pickingFramebuffer&&this.vao?this.pickingEngine.pickNode({mouseX:e,mouseY:t,canvas:this.canvas,program:this.program,pickingFramebuffer:this.pickingFramebuffer,vao:this.vao,nodeCount:this.nodeCount,viewMatrix:this.viewMatrix,pointSize:40*this.state.zoom*window.devicePixelRatio}):null}getEdgeAt(e,t){return this.pickingEngine.pickEdge({mouseX:e,mouseY:t,edgeIndices:this.edgeIndices,positions:this.positions,nodeCount:this.nodeCount,viewMatrix:this.viewMatrix,canvasW:this.canvas.width,canvasH:this.canvas.height})}pickCombo(e,t){return this.pickingEngine.pickCombo({mouseX:e,mouseY:t,combos:this.combos,positions:this.positions,nodeCount:this.nodeCount,viewMatrix:this.viewMatrix,canvasW:this.canvas.width,canvasH:this.canvas.height})}fitToView(){if(!this.positions||0===this.nodeCount)return this.state.zoom=1,this.state.offset=t.vec2.fromValues(0,0),void this.render();let e=1/0,n=1/0,a=-1/0,o=-1/0;for(let t=0;t<this.nodeCount;t++){const i=this.positions[2*t],s=this.positions[2*t+1];i<e&&(e=i),i>a&&(a=i),s<n&&(n=s),s>o&&(o=s)}const i=a-e,s=o-n,l=(e+a)/2,r=(n+o)/2,c=2*(this.canvas.width/this.canvas.height)*.9/Math.max(i,.01),d=1.8/Math.max(s,.01);this.state.zoom=Math.min(c,d,100),this.state.offset=t.vec2.fromValues(-l,-r),this.render()}zoomIn(){this.state.zoom=Math.min(l.MAX_ZOOM,1.2*this.state.zoom),this.render()}zoomOut(){this.state.zoom=Math.max(l.MIN_ZOOM,this.state.zoom/1.2),this.render()}setCameraCenter(e,n){this.state.offset=t.vec2.fromValues(-e,-n),this.render()}setCameraZoom(e){this.state.zoom=Math.max(l.MIN_ZOOM,Math.min(l.MAX_ZOOM,e)),this.render()}selectNode(e){this.state.selectedNodeIds.clear(),null!==e&&this.state.selectedNodeIds.add(e),this.canvas.dispatchEvent(new CustomEvent("node-selected",{detail:e})),this.render()}zoomAt(e,n,a){const o=window.devicePixelRatio,i=this.unproject(e*o,n*o);this.state.zoom=Math.max(l.MIN_ZOOM,Math.min(l.MAX_ZOOM,this.state.zoom*(1+a))),this.updateMatrix();const s=this.unproject(e*o,n*o);t.vec2.add(this.state.offset,this.state.offset,t.vec2.sub(t.vec2.create(),s,i)),this.render()}pan(e,n){t.vec2.add(this.state.offset,this.state.offset,t.vec2.fromValues(e/this.state.zoom,n/this.state.zoom)),this.render()}syncDragOffsets(e,n){const a=window.devicePixelRatio,o=this.unproject(e*a,n*a);this.dragOffsets.clear();for(const i of this.state.selectedNodeIds){const e=this.getNodePosition(i);e&&this.dragOffsets.set(i,t.vec2.sub(t.vec2.create(),e,o))}}handleDragging(e,n){if(!this.positions)return;const a=window.devicePixelRatio,o=this.unproject(e*a,n*a),i=this.gl;i.bindBuffer(i.ARRAY_BUFFER,this.positionBuffer);for(const s of this.state.selectedNodeIds){const e=this.dragOffsets.get(s);if(e){const n=t.vec2.add(t.vec2.create(),o,e);this.positions[2*s]=n[0],this.positions[2*s+1]=n[1],i.bufferSubData(i.ARRAY_BUFFER,2*s*4,this.positions.subarray(2*s,2*s+2)),this.canvas.dispatchEvent(new CustomEvent("node-moved",{detail:{id:s,x:n[0],y:n[1]}}))}}this.render()}performBoxSelection(){if(!this.positions)return;const e=window.devicePixelRatio,t=this.unproject(this.state.selectionStart[0]*e,this.state.selectionStart[1]*e),n=this.unproject(this.state.selectionEnd[0]*e,this.state.selectionEnd[1]*e),a=Math.min(t[0],n[0]),o=Math.max(t[0],n[0]),i=Math.min(t[1],n[1]),s=Math.max(t[1],n[1]);this.state.selectedNodeIds.clear();for(let l=0;l<this.nodeCount;l++){const e=this.positions[2*l],t=this.positions[2*l+1];e>=a&&e<=o&&t>=i&&t<=s&&this.state.selectedNodeIds.add(l)}this.canvas.dispatchEvent(new CustomEvent("nodes-selected",{detail:Array.from(this.state.selectedNodeIds)}))}unproject(e,n){const a=e/this.canvas.width*2-1,o=-(n/this.canvas.height*2-1),i=t.mat3.invert(t.mat3.create(),this.viewMatrix);if(!i)return t.vec2.create();const s=t.vec3.fromValues(a,o,1);return t.vec3.transformMat3(s,s,i),t.vec2.fromValues(s[0],s[1])}initShaders(){const e=this.gl;this.program=this.createProgram("#version 300 es\nlayout(location = 0) in vec2 a_position;\nlayout(location = 1) in vec4 a_color;\nlayout(location = 2) in float a_id;\n\nuniform mat3 u_matrix;\nuniform float u_pointSize;\nuniform bool u_pickingMode;\n\nout vec4 v_color;\nflat out uint v_id;\n\nvoid main() {\n vec3 position = u_matrix * vec3(a_position, 1.0);\n gl_Position = vec4(position.xy, 0, 1);\n gl_PointSize = u_pointSize;\n v_color = a_color;\n v_id = uint(a_id);\n}\n","#version 300 es\nprecision highp float;\n\nin vec4 v_color;\nflat in uint v_id;\n\nuniform bool u_pickingMode;\nout vec4 outColor;\n\nvoid main() {\n float dist = distance(gl_PointCoord, vec2(0.5));\n if (dist > 0.5) discard;\n\n if (u_pickingMode) {\n uint id = v_id + 1u;\n float r = float((id >> 16) & 0xFFu) / 255.0;\n float g = float((id >> 8) & 0xFFu) / 255.0;\n float b = float(id & 0xFFu) / 255.0;\n outColor = vec4(r, g, b, 1.0);\n } else {\n outColor = v_color;\n }\n}\n"),this.uMatrixLoc=e.getUniformLocation(this.program,"u_matrix"),this.uPointSizeLoc=e.getUniformLocation(this.program,"u_pointSize"),this.uPickingModeLoc=e.getUniformLocation(this.program,"u_pickingMode"),this.edgeProgram=this.createProgram("#version 300 es\nlayout(location = 0) in vec2 a_position;\n\nuniform mat3 u_matrix;\n\nvoid main() {\n vec3 position = u_matrix * vec3(a_position, 1.0);\n gl_Position = vec4(position.xy, 0, 1);\n}\n","#version 300 es\nprecision highp float;\nuniform vec4 u_color;\nout vec4 outColor;\n\nvoid main() {\n outColor = u_color;\n}\n"),this.uEdgeMatrixLoc=e.getUniformLocation(this.edgeProgram,"u_matrix"),this.uEdgeColorLoc=e.getUniformLocation(this.edgeProgram,"u_color")}initBuffers(){const e=this.gl;this.vao=e.createVertexArray(),e.bindVertexArray(this.vao),this.positionBuffer=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.enableVertexAttribArray(0),e.vertexAttribPointer(0,2,e.FLOAT,!1,0,0),this.colorBuffer=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.colorBuffer),e.enableVertexAttribArray(1),e.vertexAttribPointer(1,4,e.FLOAT,!1,0,0),this.idBuffer=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.idBuffer),e.enableVertexAttribArray(2),e.vertexAttribPointer(2,1,e.FLOAT,!1,0,0),this.edgeVao=e.createVertexArray(),e.bindVertexArray(this.edgeVao),e.bindBuffer(e.ARRAY_BUFFER,this.positionBuffer),e.enableVertexAttribArray(0),e.vertexAttribPointer(0,2,e.FLOAT,!1,0,0),this.edgeIndexBuffer=e.createBuffer(),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.edgeIndexBuffer),e.bindVertexArray(null)}initPicking(){const e=this.gl;this.pickingFramebuffer=e.createFramebuffer(),this.pickingTexture=e.createTexture(),e.bindTexture(e.TEXTURE_2D,this.pickingTexture),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,this.canvas.width,this.canvas.height,0,e.RGBA,e.UNSIGNED_BYTE,null),e.bindFramebuffer(e.FRAMEBUFFER,this.pickingFramebuffer),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.pickingTexture,0),e.bindFramebuffer(e.FRAMEBUFFER,null)}handleResize(){const e=window.devicePixelRatio;this.canvas.width=this.canvas.clientWidth*e,this.canvas.height=this.canvas.clientHeight*e,this.overlayCanvas.width=this.overlayCanvas.clientWidth*e,this.overlayCanvas.height=this.overlayCanvas.clientHeight*e,this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.initPicking(),this.render()}updateMatrix(){const e=this.canvas.width/this.canvas.height;t.mat3.identity(this.viewMatrix),t.mat3.scale(this.viewMatrix,this.viewMatrix,[this.state.zoom/e,this.state.zoom]),t.mat3.translate(this.viewMatrix,this.viewMatrix,this.state.offset)}createProgram(e,t){const n=this.gl,a=n.createShader(n.VERTEX_SHADER);n.shaderSource(a,e),n.compileShader(a);const o=n.createShader(n.FRAGMENT_SHADER);n.shaderSource(o,t),n.compileShader(o);const i=n.createProgram();return n.attachShader(i,a),n.attachShader(i,o),n.linkProgram(i),i}}const r=["width","height","stroke-width"],c=["d"],d=["cx","cy","r"],h=["x1","y1","x2","y2"],u=["x","y","width","height","rx","ry"],m=(e,t)=>{const n=e.__vccOpts||e;for(const[a,o]of t)n[a]=o;return n},v=m(n.defineComponent({__name:"LucideIcon",props:{name:{},size:{default:24},strokeWidth:{default:2}},setup(e){const t=e,a={sun:{paths:["M12 1v2","M12 21v2","M4.22 4.22l1.42 1.42","M18.36 18.36l1.42 1.42","M1 12h2","M21 12h2","M4.22 19.78l1.42-1.42","M18.36 5.64l1.42-1.42"],circles:[{cx:12,cy:12,r:4}]},moon:{paths:["M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"]},maximize:{paths:["M8 3H5a2 2 0 0 0-2 2v3","M21 8V5a2 2 0 0 0-2-2h-3","M3 16v3a2 2 0 0 0 2 2h3","M16 21h3a2 2 0 0 0 2-2v-3"]},plus:{paths:["M12 5v14","M5 12h14"]},minus:{paths:["M5 12h14"]},rocket:{paths:["M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z","m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z","M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0","M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"]},shrink:{paths:["M14 10l7-7","M3 21l7-7","M21 10h-7V3","M3 14h7v7"]},expand:{paths:["M15 3h6v6","M9 21H3v-6","M21 3l-7 7","M3 21l7-7"]},"layout-grid":{rects:[{x:3,y:3,width:7,height:7,rx:1},{x:14,y:3,width:7,height:7,rx:1},{x:14,y:14,width:7,height:7,rx:1},{x:3,y:14,width:7,height:7,rx:1}]},circle:{circles:[{cx:12,cy:12,r:10}]},dices:{rects:[{x:2,y:11,width:11,height:11,rx:2}],paths:["M7 15h.01","M7 19h.01","M11 19h.01","M22 5V2a1 1 0 0 0-1-1h-6a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2","M22 5h-4a1 1 0 0 0-1 1v4","M22 5c0-1.1-.9-2-2-2","M14 7h.01"]},spiral:{paths:["M12 12a1 1 0 1 0 1 1","M12 7a5 5 0 1 0 5 5","M12 2a10 10 0 1 0 10 10","M12 12a1 1 0 0 0-1-1"]},target:{circles:[{cx:12,cy:12,r:10},{cx:12,cy:12,r:6},{cx:12,cy:12,r:2}]},atom:{circles:[{cx:12,cy:12,r:1}],paths:["M12 2v2","M12 20v2","m4.93 4.93 1.41 1.41","m17.66 17.66 1.41 1.41","M2 12h2","M20 12h2","m6.34 17.66-1.41-1.41","m19.07 4.93-1.41 1.41"]},"git-branch":{circles:[{cx:6,cy:3,r:3},{cx:6,cy:21,r:3},{cx:18,cy:9,r:3}],paths:["M6 6v12","M18 12a6 6 0 0 1-6 6H6"]},sparkles:{paths:["m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z","M5 3L4 5.5 1.5 6.5 4 7.5 5 10l1-2.5 2.5-1L6 5.5 5 3Z","M19 19l-1 2.5-2.5 1L18 23.5l1 2.5 1-2.5 2.5-1-2.5-1-1-2.5Z"]},search:{circles:[{cx:11,cy:11,r:8}],lines:[{x1:21,y1:21,x2:16.65,y2:16.65}]},info:{circles:[{cx:12,cy:12,r:10}],paths:["M12 16v-4","M12 8h.01"]},"trash-2":{paths:["M3 6h18","M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6","M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2","M10 11v6","M14 11v6"]},palette:{circles:[{cx:13.5,cy:6.5,r:.5},{cx:17.5,cy:10.5,r:.5},{cx:8.5,cy:7.5,r:.5},{cx:6.5,cy:12.5,r:.5}],paths:["M12 2C6.47 2 2 6.47 2 12s4.47 10 9.99 10a3 3 0 0 0 3-3c0-.8-.34-1.56-.92-2.1l-.1-.08c-.53-.45-.88-1.1-.88-1.82 0-1.38 1.12-2.5 2.5-2.5H19a3 3 0 0 0 2-5c0-4.42-4.03-8-9-8Z"]},pin:{paths:["M15 4.5l-4 4L7 10l-1.5 1.5 7 7L14 17l1.5-4 4-4L15 4.5z","m9 21 3-3","M14 4.5L19.5 10"]},box:{paths:["M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z","m3.3 7 8.7 5 8.7-5","M12 22V12"]},eye:{paths:["M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"],circles:[{cx:12,cy:12,r:3}]},"eye-off":{paths:["M9.88 9.88a3 3 0 1 0 4.24 4.24","M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68","M6.61 6.61A13.52 13.52 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61","m2 2 20 20"]},"refresh-cw":{paths:["M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8","M21 3v5h-5","M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16","M3 21v-5h5"]},scale:{paths:["m16 16 3-8 3 8c-.87.62-1.92 1-3 1s-2.13-.38-3-1Z","m2 16 3-8 3 8c-.87.62-1.92 1-3 1s-2.13-.38-3-1Z","M7 21h10","M12 3v18","M3 7h18"]},zap:{paths:["M13 2 3 14h9l-1 8 10-12h-9l1-8z"]},x:{paths:["M18 6L6 18","M6 6l12 12"]}},o=n.computed(()=>a[t.name]||a.search),i=n.computed(()=>o.value.paths||[]),s=n.computed(()=>o.value.circles||[]),l=n.computed(()=>o.value.lines||[]),m=n.computed(()=>o.value.rects||[]);return(t,a)=>(n.openBlock(),n.createElementBlock("svg",{xmlns:"http://www.w3.org/2000/svg",width:e.size,height:e.size,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":e.strokeWidth,"stroke-linecap":"round","stroke-linejoin":"round",class:"lucide-icon"},[(n.openBlock(!0),n.createElementBlock(n.Fragment,null,n.renderList(i.value,(e,t)=>(n.openBlock(),n.createElementBlock("path",{key:t,d:e},null,8,c))),128)),(n.openBlock(!0),n.createElementBlock(n.Fragment,null,n.renderList(s.value,(e,t)=>(n.openBlock(),n.createElementBlock("circle",{key:t,cx:e.cx,cy:e.cy,r:e.r},null,8,d))),128)),(n.openBlock(!0),n.createElementBlock(n.Fragment,null,n.renderList(l.value,(e,t)=>(n.openBlock(),n.createElementBlock("line",{key:t,x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2},null,8,h))),128)),(n.openBlock(!0),n.createElementBlock(n.Fragment,null,n.renderList(m.value,(e,t)=>(n.openBlock(),n.createElementBlock("rect",{key:t,x:e.x,y:e.y,width:e.width,height:e.height,rx:e.rx,ry:e.ry},null,8,u))),128))],8,r))}}),[["__scopeId","data-v-6aa14fad"]]),g={class:"radial-center glass shadow-glow"},p=["onClick"],f={class:"radial-icon"},M={class:"radial-label"},k=m(n.defineComponent({__name:"RadialMenu",props:{show:{type:Boolean},x:{},y:{},type:{},items:{}},emits:["action"],setup(e){const t=(e,t)=>{const n=e/t*Math.PI*2-Math.PI/2,a=window.innerWidth<768?100:85;return{transform:`translate(-50%, -50%) translate(${Math.cos(n)*a}px, ${Math.sin(n)*a}px)`,transitionDelay:.05*e+"s"}};return(a,o)=>e.show?(n.openBlock(),n.createElementBlock("div",{key:0,class:"radial-menu",style:n.normalizeStyle({left:e.x+"px",top:e.y+"px"}),onMousedown:o[0]||(o[0]=n.withModifiers(()=>{},["stop"])),onTouchstart:o[1]||(o[1]=n.withModifiers(()=>{},["stop"]))},[n.createElementVNode("div",g,[n.renderSlot(a.$slots,"center",{},()=>["node"===e.type?(n.openBlock(),n.createBlock(v,{key:0,name:"target",size:"24"})):"edge"===e.type?(n.openBlock(),n.createBlock(v,{key:1,name:"git-branch",size:"24"})):(n.openBlock(),n.createBlock(v,{key:2,name:"search",size:"24"}))],!0)]),(n.openBlock(!0),n.createElementBlock(n.Fragment,null,n.renderList(e.items,(o,i)=>(n.openBlock(),n.createElementBlock("div",{key:i,class:"radial-item",style:n.normalizeStyle(t(i,e.items.length))},[n.createElementVNode("button",{class:"radial-item-inner glass-interactive",onClick:e=>a.$emit("action",o.action)},[n.createElementVNode("span",f,[n.createVNode(v,{name:o.icon,size:"20"},null,8,["name"])]),n.createElementVNode("span",M,n.toDisplayString(o.label),1)],8,p)],4))),128))],36)):n.createCommentVNode("",!0)}}),[["__scopeId","data-v-a2a68595"]]),w={class:"top-right-controls glass"},y=["title"],b=m(n.defineComponent({__name:"ViewControls",props:{theme:{}},emits:["toggleTheme","fit","zoomIn","zoomOut","stress"],setup(e){const t=n.ref(!1),a=()=>{document.fullscreenElement?(document.exitFullscreen(),t.value=!1):(document.documentElement.requestFullscreen(),t.value=!0)};return(o,i)=>(n.openBlock(),n.createElementBlock("div",w,[n.createElementVNode("button",{class:"control-btn glass-interactive",onClick:i[0]||(i[0]=e=>o.$emit("toggleTheme")),title:"dark"===e.theme?"Switch to Light":"Switch to Dark"},[n.createVNode(v,{name:"dark"===e.theme?"moon":"sun",size:"20"},null,8,["name"])],8,y),i[5]||(i[5]=n.createElementVNode("div",{class:"divider"},null,-1)),n.createElementVNode("button",{class:"control-btn glass-interactive",onClick:i[1]||(i[1]=e=>o.$emit("fit")),title:"Fit View"},[n.createVNode(v,{name:"maximize",size:"20"})]),n.createElementVNode("button",{class:"control-btn glass-interactive",onClick:i[2]||(i[2]=e=>o.$emit("zoomIn")),title:"Zoom In"},[n.createVNode(v,{name:"plus",size:"20"})]),n.createElementVNode("button",{class:"control-btn glass-interactive",onClick:i[3]||(i[3]=e=>o.$emit("zoomOut")),title:"Zoom Out"},[n.createVNode(v,{name:"minus",size:"20"})]),i[6]||(i[6]=n.createElementVNode("div",{class:"divider"},null,-1)),n.createElementVNode("button",{class:"control-btn glass-interactive stress-btn",onClick:i[4]||(i[4]=e=>o.$emit("stress")),title:"Stress Test (100k Nodes)"},[n.createVNode(v,{name:"rocket",size:"20"})]),i[7]||(i[7]=n.createElementVNode("div",{class:"divider"},null,-1)),n.createElementVNode("button",{class:"control-btn glass-interactive",onClick:a,title:"Toggle Fullscreen"},[n.createVNode(v,{name:t.value?"shrink":"expand",size:"20"},null,8,["name"])])]))}}),[["__scopeId","data-v-4a9f463d"]]),E={class:"layout-controls glass"},x={class:"scroll-container"},B=["onClick"],N={class:"btn-icon"},C={class:"btn-name"},V=m(n.defineComponent({__name:"LayoutControls",props:{layouts:{},currentLayout:{},flowEnabled:{type:Boolean}},emits:["runLayout","toggleFlow"],setup:e=>(t,a)=>(n.openBlock(),n.createElementBlock("div",E,[n.createElementVNode("div",x,[(n.openBlock(!0),n.createElementBlock(n.Fragment,null,n.renderList(e.layouts,a=>(n.openBlock(),n.createElementBlock("button",{key:a.id,class:n.normalizeClass(["layout-btn glass-interactive",{active:e.currentLayout===a.id}]),onClick:e=>t.$emit("runLayout",a.id)},[n.createElementVNode("span",N,[n.createVNode(v,{name:a.icon,size:"16"},null,8,["name"])]),n.createElementVNode("span",C,n.toDisplayString(a.name),1)],10,B))),128))])]))}),[["__scopeId","data-v-ff660e6a"]]),S={key:0,class:"property-panel glass node-panel"},I={class:"panel-header"},_={class:"panel-content"},F={key:0,class:"val-container"},A=["src"],R={key:1},L={key:1,class:"json-prop"},T={key:1,class:"property-panel glass edge-panel"},P={class:"panel-header"},z={class:"panel-content"},D={class:"prop-group"},U={class:"id-badge"},Y={key:0,class:"val-container"},O=["src"],X={key:1},W={key:1,class:"json-prop"},j={key:2,class:"property-panel glass combo-panel"},Z={class:"panel-header"},H={class:"panel-content"},$={class:"prop-group shadow-sm"},G=["value"],q={class:"prop-group"},K={class:"member-list"},J=["onClick"],Q={key:0,class:"more-hint"},ee=m(n.defineComponent({__name:"PropertyPanel",props:{nodeId:{},nodeMetadata:{},nodeX:{},nodeY:{},edgeId:{},edgeMetadata:{},combo:{}},emits:["update:nodeX","update:nodeY","update:nodeId","update:edgeId","update:combo","update:comboLabel","removeFromCombo"],setup(e,{emit:t}){const a=e=>"string"==typeof e&&e.startsWith("data:image/");return(t,o)=>null!==e.nodeId?(n.openBlock(),n.createElementBlock("div",S,[n.createElementVNode("div",I,[o[4]||(o[4]=n.createElementVNode("h3",null,"Node Properties",-1)),n.createElementVNode("button",{class:"close-btn",onClick:o[0]||(o[0]=e=>t.$emit("update:nodeId",null))},[n.createVNode(v,{name:"x",size:"18"})])]),n.createElementVNode("div",_,[e.nodeMetadata&&e.nodeMetadata.data?(n.openBlock(!0),n.createElementBlock(n.Fragment,{key:0},n.renderList(e.nodeMetadata.data,(t,o)=>(n.openBlock(),n.createElementBlock("div",{key:o,class:"prop-group"},[n.createElementVNode("label",null,n.toDisplayString(o),1),"object"!=typeof t?(n.openBlock(),n.createElementBlock("div",F,[a(t)?(n.openBlock(),n.createElementBlock("img",{key:0,src:t,class:"prop-image",style:n.normalizeStyle("backgroundImage"===o?{backgroundColor:e.nodeMetadata.data.color||"var(--primary)"}:{})},null,12,A)):(n.openBlock(),n.createElementBlock("span",R,n.toDisplayString(t),1))])):(n.openBlock(),n.createElementBlock("pre",L,n.toDisplayString(JSON.stringify(t,null,2)),1))]))),128)):n.createCommentVNode("",!0)])])):null!==e.edgeId?(n.openBlock(),n.createElementBlock("div",T,[n.createElementVNode("div",P,[o[5]||(o[5]=n.createElementVNode("h3",null,"Edge Properties",-1)),n.createElementVNode("button",{class:"close-btn",onClick:o[1]||(o[1]=e=>t.$emit("update:edgeId",null))},[n.createVNode(v,{name:"x",size:"18"})])]),n.createElementVNode("div",z,[n.createElementVNode("div",D,[o[6]||(o[6]=n.createElementVNode("label",null,"ID",-1)),n.createElementVNode("span",U,n.toDisplayString(e.edgeId),1)]),e.edgeMetadata&&e.edgeMetadata.data?(n.openBlock(!0),n.createElementBlock(n.Fragment,{key:0},n.renderList(e.edgeMetadata.data,(t,o)=>(n.openBlock(),n.createElementBlock("div",{key:o,class:"prop-group"},[n.createElementVNode("label",null,n.toDisplayString(o),1),"object"!=typeof t?(n.openBlock(),n.createElementBlock("div",Y,[a(t)?(n.openBlock(),n.createElementBlock("img",{key:0,src:t,class:"prop-image",style:n.normalizeStyle("backgroundImage"===o?{backgroundColor:e.edgeMetadata.data.color||"var(--secondary)"}:{})},null,12,O)):(n.openBlock(),n.createElementBlock("span",X,n.toDisplayString(t),1))])):(n.openBlock(),n.createElementBlock("pre",W,n.toDisplayString(JSON.stringify(t,null,2)),1))]))),128)):n.createCommentVNode("",!0)])])):e.combo?(n.openBlock(),n.createElementBlock("div",j,[n.createElementVNode("div",Z,[o[7]||(o[7]=n.createElementVNode("h3",null,"Group Properties",-1)),n.createElementVNode("button",{class:"close-btn",onClick:o[2]||(o[2]=e=>t.$emit("update:combo",null))},[n.createVNode(v,{name:"x",size:"18"})])]),n.createElementVNode("div",H,[n.createElementVNode("div",$,[o[8]||(o[8]=n.createElementVNode("label",null,"Label",-1)),n.createElementVNode("input",{type:"text",value:e.combo.label,class:"full-width",onInput:o[3]||(o[3]=e=>t.$emit("update:comboLabel",e.target.value))},null,40,G)]),n.createElementVNode("div",q,[n.createElementVNode("label",null,"Members ("+n.toDisplayString(e.combo.nodeIds.size)+")",1),n.createElementVNode("div",K,[(n.openBlock(!0),n.createElementBlock(n.Fragment,null,n.renderList(Array.from(e.combo.nodeIds).slice(0,50),e=>(n.openBlock(),n.createElementBlock("div",{key:e,class:"member-item"},[n.createElementVNode("span",null,"Node "+n.toDisplayString(e),1),n.createElementVNode("button",{class:"remove-btn",onClick:n=>t.$emit("removeFromCombo",e)},[n.createVNode(v,{name:"trash-2",size:"12"})],8,J)]))),128)),e.combo.nodeIds.size>50?(n.openBlock(),n.createElementBlock("div",Q," + "+n.toDisplayString(e.combo.nodeIds.size-50)+" more ",1)):n.createCommentVNode("",!0)])])])])):n.createCommentVNode("",!0)}}),[["__scopeId","data-v-7c0e24e3"]]),te={class:"search-icon"},ne={key:0,class:"results-panel"},ae=["onMousedown","onTouchstart"],oe={class:"node-icon"},ie={class:"node-info"},se={class:"node-label"},le={class:"node-id"},re={key:1,class:"no-results"},ce=m(n.defineComponent({__name:"SearchBar",props:{nodes:{}},emits:["select"],setup(e,{emit:t}){const a=e,o=t,i=n.ref(""),s=n.ref(!1),l=n.ref(null),r=n.ref(window.innerWidth<768),c=()=>{r.value=window.innerWidth<768};n.onMounted(()=>{window.addEventListener("resize",c)}),n.onUnmounted(()=>{window.removeEventListener("resize",c)});const d=n.computed(()=>{if(!i.value)return[];const e=i.value.toLowerCase();return a.nodes.filter(t=>t.label?.toLowerCase().includes(e)||t.id.toString().includes(e)).slice(0,10)}),h=e=>{o("select",e),i.value="",s.value=!1},u=()=>{r.value&&!s.value&&(s.value=!0,setTimeout(()=>l.value?.focus(),100))},m=()=>{i.value="",s.value=!1,l.value?.blur()},g=()=>{r.value||setTimeout(()=>{s.value=!1},200)};return(e,t)=>(n.openBlock(),n.createElementBlock("div",{class:n.normalizeClass(["search-wrapper",{"mobile-expanded":s.value&&r.value,"is-mobile":r.value}])},[n.createElementVNode("div",{class:n.normalizeClass(["search-container glass",{expanded:s.value,"has-query":i.value.length>0}])},[n.createElementVNode("div",{class:"search-input-wrapper",onClick:u},[n.createElementVNode("span",te,[n.createVNode(v,{name:"search",size:r.value?20:14},null,8,["size"])]),n.withDirectives(n.createElementVNode("input",{ref_key:"inputRef",ref:l,"onUpdate:modelValue":t[0]||(t[0]=e=>i.value=e),placeholder:"Search nodes...",onFocus:t[1]||(t[1]=e=>s.value=!0),onBlur:g,onKeydown:t[2]||(t[2]=n.withKeys(e=>s.value=!1,["esc"]))},null,544),[[n.vModelText,i.value]]),i.value||r.value&&s.value?(n.openBlock(),n.createElementBlock("div",{key:0,class:"clear-btn",onClick:n.withModifiers(m,["stop"])},[n.createVNode(v,{name:i.value?"x":"chevron-down",size:r.value?20:12},null,8,["name","size"])])):n.createCommentVNode("",!0)]),s.value&&d.value.length>0?(n.openBlock(),n.createElementBlock("div",ne,[(n.openBlock(!0),n.createElementBlock(n.Fragment,null,n.renderList(d.value,e=>(n.openBlock(),n.createElementBlock("div",{key:e.id,class:"result-item",onMousedown:t=>h(e.id),onTouchstart:t=>h(e.id)},[n.createElementVNode("span",oe,[n.createVNode(v,{name:"circle",size:"8"})]),n.createElementVNode("div",ie,[n.createElementVNode("div",se,n.toDisplayString(e.label),1),n.createElementVNode("div",le,"ID: "+n.toDisplayString(e.id),1)])],40,ae))),128))])):s.value&&i.value?(n.openBlock(),n.createElementBlock("div",re," No nodes found ")):n.createCommentVNode("",!0)],2),r.value&&s.value?(n.openBlock(),n.createElementBlock("div",{key:0,class:"mobile-backdrop",onClick:m})):n.createCommentVNode("",!0)],2))}}),[["__scopeId","data-v-3fda8a90"]]),de={key:0,class:"mobile-menu glass shadow-lg"},he={class:"drawer-header"},ue={key:0,class:"drawer-content"},me={key:1,class:"drawer-content"},ve={class:"help-header"},ge={class:"help-content"},pe={class:"key-badge"},fe={class:"action-desc"},Me=m(n.defineComponent({__name:"GraphCanvas",props:{data:{}},setup(e){const t=e,o=n.ref(null),i=n.ref(null),s=n.ref(1e4),r=n.ref(null),c=n.ref(null),d=n.ref(null),h=n.ref(null),u=n.ref(0),m=n.ref("dark"),g=n.ref(null),p=n.ref(0),f=n.ref(0),M=n.ref(null),w=n.ref(null),y=n.ref("random"),E=n.ref(!1),x=n.ref(0),B=n.ref([]),N=n.ref(!1),C=n.ref(window.innerWidth<768),S=n.ref(null),I=n.ref(!1),_=n.ref(null),F=e=>{S.value===e?S.value=null:S.value=e},A=e=>{Q(e),S.value=null},R=()=>{I.value=!0,setTimeout(()=>{_.value?.handleWrapperClick?.()},50)},L=()=>{C.value=window.innerWidth<768},T=[{key:"Shift + Drag",action:"Box Selection"},{key:"Ctrl + Click",action:"Multi Selection"},{key:"Right Click",action:"Radial Menu"},{key:"Scroll",action:"Zoom In/Out"},{key:"Drag",action:"Pan View"}],P=[{id:"random",name:"Random",icon:"dices"},{id:"grid",name:"Grid",icon:"layout-grid"},{id:"circle",name:"Circle",icon:"circle"},{id:"spiral",name:"Spiral",icon:"spiral"},{id:"concentric",name:"Concentric",icon:"target"},{id:"radial",name:"Radial",icon:"atom"},{id:"hierarchy",name:"Hierarchy",icon:"git-branch"},{id:"force",name:"Force",icon:"sparkles"}];let z,D,U,Y=null;const O=()=>{m.value="dark"===m.value?"light":"dark",z&&z.setTheme(m.value),document.documentElement.classList.toggle("light","light"===m.value)},X=()=>{null!==c.value&&z&&z.setNodePosition(c.value,p.value,f.value)};n.watch(c,()=>(()=>{if(null!==c.value&&z){const e=z.getNodePosition(c.value);e&&(p.value=Number(e[0].toFixed(3)),f.value=Number(e[1].toFixed(3))),M.value=z.getNodeMetadata(c.value)}else M.value=null})()),n.watch(p,()=>X()),n.watch(f,()=>X()),n.watch(h,e=>{g.value=e&&z?z.getCombo(e):null}),n.watch(g,e=>{null===e&&(h.value=null)});const W=e=>{if(h.value&&z){const t=z.getCombo(h.value);t&&(z.updateCombo(t.id,e,Array.from(t.nodeIds)),g.value={...t,label:e})}},j=e=>{if(h.value&&z){z.removeNodeFromCombo(h.value,e);const t=z.getCombo(h.value);t&&(g.value={...t,nodeIds:new Set(t.nodeIds)})}},Z=()=>{E.value=!E.value,z&&z.setFlowAnimation(E.value)},H=e=>{if(z){z.selectNode(e);const t=z.getNodePosition(e);t&&(z.setCameraCenter(t[0],t[1]),z.setCameraZoom(2))}I.value=!1},$=n.ref({show:!1,x:0,y:0,type:"none",target:null}),G=n.ref([]),q=e=>{const t=o.value?.getBoundingClientRect();if(!t||!z)return;const n=e.clientX-t.left,a=e.clientY-t.top,i=z.pick(n,a);if(null!==i)$.value={show:!0,x:e.clientX,y:e.clientY,type:"node",target:i},G.value=[{label:"Delete",icon:"trash-2",action:"delete"},{label:"Color",icon:"palette",action:"color"},{label:"Pin",icon:"pin",action:"pin"},{label:"Info",icon:"info",action:"info"}],u.value>1&&G.value.push({label:"Group",icon:"box",action:"create-combo"});else{const t=z.getEdgeAt(n,a);if(t)$.value={show:!0,x:e.clientX,y:e.clientY,type:"edge",target:t},G.value=[{label:"Hide",icon:"eye-off",action:"hide"},{label:"Weight",icon:"scale",action:"weight"},{label:"Reverse",icon:"refresh-cw",action:"reverse"}];else{const t=z.pickCombo(n,a);t?($.value={show:!0,x:e.clientX,y:e.clientY,type:"none",target:t},G.value=[{label:"Dissolve",icon:"zap",action:"dissolve-combo"},{label:"Add Selected",icon:"plus",action:"add-to-group"}]):$.value.show=!1}}},K=e=>{if(z)if("create-combo"===e){const e=z.getSelectedNodeIds(),t=`combo-${Date.now()}`;z.createCombo(t,`Group ${t.split("-")[1]}`,e),x.value++}else if("dissolve-combo"===e)$.value.target&&(z.removeCombo($.value.target),x.value--);else if("add-to-group"===e){const e=z.getSelectedNodeIds();if($.value.target)for(const t of e)z.addNodeToCombo($.value.target,t)}$.value.show=!1},J=e=>{if(!z)return;s.value=e;const t=new Float32Array(2*e),n=new Float32Array(4*e),a=new Float32Array(e);D=new Float32Array(e);const o=new Map;for(let s=0;s<e;s++)t[2*s]=50*(Math.random()-.5),t[2*s+1]=50*(Math.random()-.5),n[4*s]=Math.random(),n[4*s+1]=Math.random(),n[4*s+2]=Math.random(),n[4*s+3]=1,a[s]=s,D[s]=.05,o.set(s,{label:`S-${s}`,width:50,height:50});const i=[];for(let s=0;s<5e4;s++)i.push(Math.floor(Math.random()*e)),i.push(Math.floor(Math.random()*e));U=new Uint32Array(i),z.setData(t,n,a,o,U,new Map),Y&&Y.postMessage({type:"init",data:{nodeCount:e,positions:t,nodeRadii:D,edgeIndices:U}}),z.fitToView()},Q=e=>{y.value=e,Y&&Y.postMessage({type:"layout",data:{layoutType:e,nodeRadii:D,edgeIndices:U}})};return n.onMounted(()=>{if(window.addEventListener("resize",L),o.value&&i.value){z=new l(o.value,i.value);const e=t.data.nodes||[],n=t.data.edges||[],m=e.length;s.value=m;const v=new Float32Array(2*m),g=new Float32Array(4*m),M=new Float32Array(m);D=new Float32Array(m);const k=new Map,y=new Map,b=e=>{const t=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return t?[parseInt(t[1],16)/255,parseInt(t[2],16)/255,parseInt(t[3],16)/255]:[Math.random(),Math.random(),Math.random()]};e.forEach((e,t)=>{const n=e.data,a=e.position||{x:0,y:0};y.set(n.id,t),v[2*t]=((a.x??2500)-2500)/500,v[2*t+1]=((a.y??2500)-2500)/500;const o=n.color||"#000000",i=b(o);g[4*t]=i[0],g[4*t+1]=i[1],g[4*t+2]=i[2],g[4*t+3]=1,M[t]=t;const s=n.width||50,l=n.height||50;D[t]=Math.max(s,l)/1e3;const r={label:n.label||n.code||`Node ${n.id}`,image:n.backgroundImage,width:s,height:l,data:n};if(n.backgroundImage){const e=new Image;e.src=n.backgroundImage,e.onload=()=>{const t=document.createElement("canvas"),n=128;t.width=n,t.height=n;const a=t.getContext("2d");a&&(a.beginPath(),a.arc(64,64,64,0,2*Math.PI),a.clip(),a.filter="grayscale(100%) brightness(1000%)",a.drawImage(e,0,0,n,n),r.processedImageElement=t)},r.imageElement=e}k.set(t,r)}),B.value=Array.from(k.entries()).map(([e,t])=>({id:e,label:t.label}));const E=[],x=new Map;n.forEach(e=>{const t=e.data.source,n=e.data.target,a=y.get(t),o=y.get(n);if(void 0!==a&&void 0!==o){E.push(a),E.push(o);const t=`${a}-${o}`;x.set(t,{label:e.data.label,data:e.data})}}),U=new Uint32Array(E),z.setData(v,g,M,k,U,x),Y=new Worker(new URL("/assets/layout.worker-CBxeMMC3.js","undefined"==typeof document&&"undefined"==typeof location?require("url").pathToFileURL(__filename).href:"undefined"==typeof document?location.href:a&&"SCRIPT"===a.tagName.toUpperCase()&&a.src||new URL("webgl-graph.umd.js",document.baseURI).href),{type:"module"}),Y.postMessage({type:"init",data:{nodeCount:m,positions:v,nodeRadii:D,edgeIndices:U}}),Y.onmessage=e=>{"layout-complete"===e.data.type&&(e=>{if(!z)return;const t=s.value,n=new Float32Array(2*t);for(let s=0;s<t;s++){const e=z.getNodePosition(s);e&&(n[2*s]=e[0],n[2*s+1]=e[1])}const a=performance.now(),o=new Float32Array(2*t),i=s=>{const l=s-a,r=Math.min(l/1e3,1),c=r<.5?4*r**3:1-Math.pow(-2*r+2,3)/2;if(n&&e)for(let a=0;a<2*t;a++)o[a]=n[a]+(e[a]-n[a])*c;z.updatePositions(o),r<1?requestAnimationFrame(i):z.fitToView()};requestAnimationFrame(i)})(e.data.positions)},window.addEventListener("mousedown",()=>{$.value.show=!1}),o.value.addEventListener("node-picked",e=>{r.value=e.detail}),o.value.addEventListener("node-selected",e=>{c.value=e.detail,null!==e.detail&&(d.value=null,h.value=null)}),o.value.addEventListener("edge-selected",e=>{d.value=e.detail,null!==e.detail?(c.value=null,h.value=null,w.value=z.getEdgeMetadata(e.detail)):w.value=null}),o.value.addEventListener("combo-selected",e=>{h.value=e.detail,null!==e.detail&&(c.value=null,d.value=null)}),o.value.addEventListener("nodes-selected",e=>{u.value=e.detail.length}),o.value.addEventListener("node-moved",e=>{e.detail.id===c.value&&(p.value=Number(e.detail.x.toFixed(3)),f.value=Number(e.detail.y.toFixed(3)))})}}),n.onUnmounted(()=>{window.removeEventListener("resize",L),Y&&Y.terminate()}),(e,t)=>(n.openBlock(),n.createElementBlock("div",{class:n.normalizeClass(["container",m.value])},[n.createElementVNode("canvas",{ref_key:"canvasRef",ref:o,class:"main-canvas",onContextmenu:n.withModifiers(q,["prevent"])},null,544),n.createElementVNode("canvas",{ref_key:"overlayCanvasRef",ref:i,class:"overlay-canvas"},null,512),C.value?(n.openBlock(),n.createElementBlock("div",de,[n.createElementVNode("button",{class:n.normalizeClass(["menu-btn",{active:"layouts"===S.value}]),onClick:t[0]||(t[0]=e=>F("layouts"))},[n.createVNode(v,{name:"layout",size:"20"}),t[22]||(t[22]=n.createElementVNode("span",null,"Layout",-1))],2),n.createElementVNode("button",{class:n.normalizeClass(["menu-btn",{active:"view"===S.value}]),onClick:t[1]||(t[1]=e=>F("view"))},[n.createVNode(v,{name:"eye",size:"20"}),t[23]||(t[23]=n.createElementVNode("span",null,"View",-1))],2),t[25]||(t[25]=n.createElementVNode("div",{class:"menu-divider"},null,-1)),n.createElementVNode("button",{class:"menu-btn search-trigger",onClick:R},[n.createVNode(v,{name:"search",size:"20"}),t[24]||(t[24]=n.createElementVNode("span",null,"Search",-1))])])):n.createCommentVNode("",!0),C.value&&S.value?(n.openBlock(),n.createElementBlock("div",{key:1,class:"drawer-overlay",onClick:t[8]||(t[8]=e=>S.value=null)},[n.createElementVNode("div",{class:"mobile-drawer glass shadow-2xl",onClick:t[7]||(t[7]=n.withModifiers(()=>{},["stop"]))},[t[26]||(t[26]=n.createElementVNode("div",{class:"drawer-handle"},null,-1)),n.createElementVNode("div",he,[n.createElementVNode("h3",null,n.toDisplayString("layouts"===S.value?"Graph Layouts":"View Controls"),1),n.createElementVNode("button",{class:"drawer-close",onClick:t[2]||(t[2]=e=>S.value=null)},[n.createVNode(v,{name:"x",size:"20"})])]),"layouts"===S.value?(n.openBlock(),n.createElementBlock("div",ue,[n.createVNode(V,{layouts:P,currentLayout:y.value,flowEnabled:E.value,onRunLayout:A,onToggleFlow:Z},null,8,["currentLayout","flowEnabled"])])):n.createCommentVNode("",!0),"view"===S.value?(n.openBlock(),n.createElementBlock("div",me,[n.createVNode(b,{theme:m.value,onToggleTheme:O,onFit:t[3]||(t[3]=e=>n.unref(z)?.fitToView()),onZoomIn:t[4]||(t[4]=e=>n.unref(z)?.zoomIn()),onZoomOut:t[5]||(t[5]=e=>n.unref(z)?.zoomOut()),onStress:t[6]||(t[6]=e=>J(1e5))},null,8,["theme"])])):n.createCommentVNode("",!0)])])):n.createCommentVNode("",!0),n.withDirectives(n.createVNode(ce,{ref_key:"searchBarRef",ref:_,nodes:B.value,onSelect:H},null,8,["nodes"]),[[n.vShow,!C.value||I.value]]),C.value?n.createCommentVNode("",!0):(n.openBlock(),n.createBlock(b,{key:2,theme:m.value,onToggleTheme:O,onFit:t[9]||(t[9]=e=>n.unref(z)?.fitToView()),onZoomIn:t[10]||(t[10]=e=>n.unref(z)?.zoomIn()),onZoomOut:t[11]||(t[11]=e=>n.unref(z)?.zoomOut()),onStress:t[12]||(t[12]=e=>J(1e5))},null,8,["theme"])),C.value?n.createCommentVNode("",!0):(n.openBlock(),n.createBlock(V,{key:3,layouts:P,currentLayout:y.value,flowEnabled:E.value,onRunLayout:Q,onToggleFlow:Z},null,8,["currentLayout","flowEnabled"])),n.createVNode(k,{show:$.value.show,x:$.value.x,y:$.value.y,type:$.value.type,items:G.value,onAction:K},null,8,["show","x","y","type","items"]),n.createVNode(ee,{nodeId:c.value,"onUpdate:nodeId":t[13]||(t[13]=e=>c.value=e),nodeMetadata:M.value,nodeX:p.value,"onUpdate:nodeX":t[14]||(t[14]=e=>p.value=e),nodeY:f.value,"onUpdate:nodeY":t[15]||(t[15]=e=>f.value=e),edgeId:d.value,"onUpdate:edgeId":t[16]||(t[16]=e=>d.value=e),edgeMetadata:w.value,combo:g.value,"onUpdate:combo":t[17]||(t[17]=e=>g.value=e),"onUpdate:comboLabel":W,onRemoveFromCombo:j},null,8,["nodeId","nodeMetadata","nodeX","nodeY","edgeId","edgeMetadata","combo"]),C.value?n.createCommentVNode("",!0):(n.openBlock(),n.createElementBlock("div",{key:4,class:"help-trigger glass-interactive",onClick:t[18]||(t[18]=e=>N.value=!0),title:"Keyboard Shortcuts"},[n.createVNode(v,{name:"info",size:"18"})])),N.value?(n.openBlock(),n.createElementBlock("div",{key:5,class:"help-modal-overlay",onClick:t[21]||(t[21]=e=>N.value=!1)},[n.createElementVNode("div",{class:"help-modal glass",onClick:t[20]||(t[20]=n.withModifiers(()=>{},["stop"]))},[n.createElementVNode("div",ve,[t[27]||(t[27]=n.createElementVNode("h3",null,"Keyboard Shortcuts",-1)),n.createElementVNode("button",{class:"close-btn",onClick:t[19]||(t[19]=e=>N.value=!1)},[n.createVNode(v,{name:"x",size:"20"})])]),n.createElementVNode("div",ge,[(n.openBlock(),n.createElementBlock(n.Fragment,null,n.renderList(T,e=>n.createElementVNode("div",{key:e.key,class:"shortcut-row"},[n.createElementVNode("span",pe,n.toDisplayString(e.key),1),n.createElementVNode("span",fe,n.toDisplayString(e.action),1)])),64))])])])):n.createCommentVNode("",!0)],2))}}),[["__scopeId","data-v-87730b5c"]]);e.GraphCanvas=Me,e.GraphEngine=l,e.createGraphData=(e,t)=>({nodes:e,edges:t}),Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "vortx-gl",
3
3
  "private": false,
4
- "version": "1.0.1",
5
- "description": "Secure High-performance WebGL Graph Rendering Library",
4
+ "version": "1.0.2",
5
+ "description": "Secure High-performance VortxGL Graph Rendering Library",
6
6
  "type": "module",
7
7
  "main": "./dist/vortx-gl.umd.js",
8
8
  "module": "./dist/vortx-gl.es.js",
@@ -19,26 +19,33 @@
19
19
  },
20
20
  "license": "Apache-2.0",
21
21
  "files": [
22
- "dist",
23
- "README.md",
24
- "LICENSE",
25
- "examples"
22
+ "dist"
26
23
  ],
24
+ "scripts": {
25
+ "dev": "vite",
26
+ "build": "vue-tsc -b && vite build",
27
+ "build:lib": "vue-tsc -b && cross-env BUILD_LIB=true vite build",
28
+ "preview": "vite preview"
29
+ },
27
30
  "peerDependencies": {
28
31
  "gl-matrix": "^3.0.0",
29
32
  "vue": "^3.0.0"
30
33
  },
31
- "keywords": [
32
- "webgl",
33
- "graph",
34
- "visualization",
35
- "performance",
36
- "vortx-gl",
37
- "network"
38
- ],
39
- "author": "VortxGL Contributors",
40
- "repository": {
41
- "type": "git",
42
- "url": "https://github.com/doryhokayem/vortx-gl.git"
34
+ "dependencies": {
35
+ "gl-matrix": "^3.0.0",
36
+ "vue": "^3.0.0"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^24.10.1",
40
+ "@vitejs/plugin-vue": "^6.0.1",
41
+ "@vue/tsconfig": "^0.8.1",
42
+ "cross-env": "^10.1.0",
43
+ "javascript-obfuscator": "^5.3.0",
44
+ "rollup-plugin-javascript-obfuscator": "^1.0.4",
45
+ "terser": "^5.46.0",
46
+ "typescript": "~5.9.3",
47
+ "vite": "^7.2.4",
48
+ "vite-plugin-dts": "^4.5.1",
49
+ "vue-tsc": "^3.1.4"
43
50
  }
44
51
  }
@@ -1,71 +0,0 @@
1
- <script setup>
2
- import { onMounted, ref } from 'vue';
3
- import { GraphCanvas, createGraphData } from 'webgl-graph-library';
4
- import 'webgl-graph-library/dist/webgl-graph-library.css';
5
-
6
- // 1. Prepare your data (can be loaded from an API)
7
- const graphData = ref({
8
- nodes: [
9
- { data: { id: '1', label: 'CEO', color: '#ff4757', width: 80, height: 80 }, position: { x: 2500, y: 2400 } },
10
- { data: { id: '2', label: 'CTO', color: '#2ed573', width: 60, height: 60 }, position: { x: 2300, y: 2600 } },
11
- { data: { id: '3', label: 'CFO', color: '#1e90ff', width: 60, height: 60 }, position: { x: 2700, y: 2600 } }
12
- ],
13
- edges: [
14
- { data: { id: 'e1-2', source: '1', target: '2', label: 'Reports to' } },
15
- { data: { id: 'e1-3', source: '1', target: '3', label: 'Reports to' } }
16
- ]
17
- });
18
-
19
- // 2. Event Handled
20
- const onNodeSelect = (nodeId) => {
21
- console.log('User selected node:', nodeId);
22
- };
23
-
24
- const onEdgeSelect = (edgeId) => {
25
- console.log('User selected edge:', edgeId);
26
- };
27
- </script>
28
-
29
- <template>
30
- <div class="app-container">
31
- <header>
32
- <h1>Org Chart Visualizer</h1>
33
- <p>Powered by WebGL Graph Engine</p>
34
- </header>
35
-
36
- <main class="viewport">
37
- <!-- 3. Use the Library Component -->
38
- <GraphCanvas
39
- :data="graphData"
40
- @node-selected="onNodeSelect"
41
- @edge-selected="onEdgeSelect"
42
- />
43
- </main>
44
- </div>
45
- </template>
46
-
47
- <style>
48
- /* Ensure the container has dimensions */
49
- .viewport {
50
- width: 100vw;
51
- height: calc(100vh - 80px);
52
- position: relative;
53
- }
54
-
55
- header {
56
- height: 80px;
57
- background: #1a1a2e;
58
- color: white;
59
- display: flex;
60
- flex-direction: column;
61
- justify-content: center;
62
- align-items: center;
63
- border-bottom: 1px solid #16213e;
64
- }
65
-
66
- body {
67
- margin: 0;
68
- overflow: hidden;
69
- font-family: 'Inter', sans-serif;
70
- }
71
- </style>