yaml-flow 5.4.2 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/board-live-cards-cli.js +2 -2
- package/board-livecards-server-runtime.js +486 -547
- package/browser/asset-integrity.json +10 -0
- package/browser/board-livegraph-engine.js +2 -1676
- package/browser/board-livegraph-engine.js.map +1 -1
- package/browser/live-cards.js +347 -26
- package/browser/live-cards.schema.json +418 -132
- package/card-store.js +37 -0
- package/dist/batch/index.cjs +1 -108
- package/dist/batch/index.cjs.map +1 -1
- package/dist/batch/index.js +1 -106
- package/dist/batch/index.js.map +1 -1
- package/dist/board-live-cards-lib-Bg6EvCo5.d.cts +136 -0
- package/dist/board-live-cards-lib-jM2uYG1v.d.ts +136 -0
- package/dist/board-live-cards-public-CltXYgaY.d.cts +314 -0
- package/dist/board-live-cards-public-f-E-FAyp.d.ts +314 -0
- package/dist/board-livegraph-runtime/index.cjs +2 -1671
- package/dist/board-livegraph-runtime/index.cjs.map +1 -1
- package/dist/board-livegraph-runtime/index.d.cts +1 -2
- package/dist/board-livegraph-runtime/index.d.ts +1 -2
- package/dist/board-livegraph-runtime/index.js +2 -1662
- package/dist/board-livegraph-runtime/index.js.map +1 -1
- package/dist/board-livegraph-runtime/jsonata-sync.cjs +7587 -0
- package/dist/card-compute/index.cjs +9 -7159
- package/dist/card-compute/index.cjs.map +1 -1
- package/dist/card-compute/index.d.cts +22 -0
- package/dist/card-compute/index.d.ts +22 -0
- package/dist/card-compute/index.js +9 -7145
- package/dist/card-compute/index.js.map +1 -1
- package/dist/card-compute/jsonata-sync.cjs +7587 -0
- package/dist/cli/browser-api/board-live-cards-browser-adapter.cjs +2 -0
- package/dist/cli/browser-api/board-live-cards-browser-adapter.cjs.map +1 -0
- package/dist/cli/browser-api/board-live-cards-browser-adapter.d.cts +24 -0
- package/dist/cli/browser-api/board-live-cards-browser-adapter.d.ts +24 -0
- package/dist/cli/browser-api/board-live-cards-browser-adapter.js +2 -0
- package/dist/cli/browser-api/board-live-cards-browser-adapter.js.map +1 -0
- package/dist/cli/browser-api/card-store-browser-api.cjs +2 -0
- package/dist/cli/browser-api/card-store-browser-api.cjs.map +1 -0
- package/dist/cli/browser-api/card-store-browser-api.d.cts +26 -0
- package/dist/cli/browser-api/card-store-browser-api.d.ts +26 -0
- package/dist/cli/browser-api/card-store-browser-api.js +2 -0
- package/dist/cli/browser-api/card-store-browser-api.js.map +1 -0
- package/dist/cli/browser-api/jsonata-sync.cjs +7587 -0
- package/dist/cli/node/artifacts-store-cli.cjs +11 -0
- package/dist/cli/node/artifacts-store-cli.cjs.map +1 -0
- package/dist/cli/node/artifacts-store-cli.d.cts +8 -0
- package/dist/cli/node/artifacts-store-cli.d.ts +8 -0
- package/dist/cli/node/artifacts-store-cli.js +11 -0
- package/dist/cli/node/artifacts-store-cli.js.map +1 -0
- package/dist/cli/node/board-live-cards-cli.cjs +15 -0
- package/dist/cli/node/board-live-cards-cli.cjs.map +1 -0
- package/dist/cli/node/board-live-cards-cli.d.cts +20 -0
- package/dist/cli/node/board-live-cards-cli.d.ts +20 -0
- package/dist/cli/node/board-live-cards-cli.js +15 -0
- package/dist/cli/node/board-live-cards-cli.js.map +1 -0
- package/dist/cli/node/card-store-cli.cjs +8 -0
- package/dist/cli/node/card-store-cli.cjs.map +1 -0
- package/dist/cli/node/card-store-cli.d.cts +15 -0
- package/dist/cli/node/card-store-cli.d.ts +15 -0
- package/dist/cli/node/card-store-cli.js +8 -0
- package/dist/cli/node/card-store-cli.js.map +1 -0
- package/dist/cli/node/fs-board-adapter.cjs +14 -0
- package/dist/cli/node/fs-board-adapter.cjs.map +1 -0
- package/dist/cli/node/fs-board-adapter.d.cts +204 -0
- package/dist/cli/node/fs-board-adapter.d.ts +204 -0
- package/dist/cli/node/fs-board-adapter.js +14 -0
- package/dist/cli/node/fs-board-adapter.js.map +1 -0
- package/dist/cli/node/jsonata-sync.cjs +7587 -0
- package/dist/cli/node/source-cli-task-executor.cjs +11 -0
- package/dist/cli/node/source-cli-task-executor.cjs.map +1 -0
- package/dist/cli/node/source-cli-task-executor.d.cts +1 -0
- package/dist/cli/node/source-cli-task-executor.d.ts +1 -0
- package/dist/cli/node/source-cli-task-executor.js +11 -0
- package/dist/cli/node/source-cli-task-executor.js.map +1 -0
- package/dist/config/index.cjs +1 -79
- package/dist/config/index.cjs.map +1 -1
- package/dist/config/index.js +1 -76
- package/dist/config/index.js.map +1 -1
- package/dist/continuous-event-graph/index.cjs +2 -2129
- package/dist/continuous-event-graph/index.cjs.map +1 -1
- package/dist/continuous-event-graph/index.d.cts +81 -5
- package/dist/continuous-event-graph/index.d.ts +81 -5
- package/dist/continuous-event-graph/index.js +2 -2088
- package/dist/continuous-event-graph/index.js.map +1 -1
- package/dist/continuous-event-graph/jsonata-sync.cjs +7587 -0
- package/dist/event-graph/index.cjs +22 -8292
- package/dist/event-graph/index.cjs.map +1 -1
- package/dist/event-graph/index.js +22 -8237
- package/dist/event-graph/index.js.map +1 -1
- package/dist/execution-refs.cjs +2 -0
- package/dist/execution-refs.cjs.map +1 -0
- package/dist/execution-refs.d.cts +222 -0
- package/dist/execution-refs.d.ts +222 -0
- package/dist/execution-refs.js +2 -0
- package/dist/execution-refs.js.map +1 -0
- package/dist/index.cjs +29 -13221
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -4
- package/dist/index.d.ts +2 -4
- package/dist/index.js +29 -13112
- package/dist/index.js.map +1 -1
- package/dist/inference/index.cjs +5 -617
- package/dist/inference/index.cjs.map +1 -1
- package/dist/inference/index.js +5 -610
- package/dist/inference/index.js.map +1 -1
- package/dist/jsonata-sync.cjs +7587 -0
- package/dist/{live-cards-bridge-x5XREkXm.d.cts → live-cards-bridge-BXbVTsna.d.cts} +27 -4
- package/dist/{live-cards-bridge-EQjytzI_.d.ts → live-cards-bridge-Ds28XR15.d.ts} +27 -4
- package/dist/pycli/quickjs-board-runtime.global.js +9 -0
- package/dist/pycli/quickjs-board-runtime.global.js.map +1 -0
- package/dist/pycli/quickjs-step-machine-runtime.global.js +5 -0
- package/dist/pycli/quickjs-step-machine-runtime.global.js.map +1 -0
- package/dist/step-machine/index.cjs +11 -7129
- package/dist/step-machine/index.cjs.map +1 -1
- package/dist/step-machine/index.js +11 -7113
- package/dist/step-machine/index.js.map +1 -1
- package/dist/storage-refs.cjs +10 -0
- package/dist/storage-refs.cjs.map +1 -0
- package/dist/storage-refs.d.cts +92 -0
- package/dist/storage-refs.d.ts +92 -0
- package/dist/storage-refs.js +10 -0
- package/dist/storage-refs.js.map +1 -0
- package/dist/stores/file.cjs +1 -114
- package/dist/stores/file.cjs.map +1 -1
- package/dist/stores/file.js +1 -112
- package/dist/stores/file.js.map +1 -1
- package/dist/stores/index.cjs +1 -231
- package/dist/stores/index.cjs.map +1 -1
- package/dist/stores/index.js +1 -227
- package/dist/stores/index.js.map +1 -1
- package/dist/stores/localStorage.cjs +1 -76
- package/dist/stores/localStorage.cjs.map +1 -1
- package/dist/stores/localStorage.js +1 -74
- package/dist/stores/localStorage.js.map +1 -1
- package/dist/stores/memory.cjs +1 -47
- package/dist/stores/memory.cjs.map +1 -1
- package/dist/stores/memory.js +1 -45
- package/dist/stores/memory.js.map +1 -1
- package/examples/browser/boards/portfolio-tracker/portfolio-t4.js +292 -0
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker-fetch-prices.js +218 -0
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker-fetch-prices.py +201 -0
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker-inference-adapter.js +25 -16
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker-public.js +553 -0
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker.py +365 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/--base-ref/.runtime-out +1 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/--base-ref/board-graph.json +32 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/_board-cli.js +53 -1
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/add-cards-cli.js +15 -6
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/init-board-cli.js +6 -1
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/poll-status-cli.js +57 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/retrigger-cli.js +1 -1
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/status-cli.js +1 -1
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/update-holdings-cli.js +7 -2
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/wait-completed-cli.js +6 -2
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/_board_pycli.py +97 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/add-cards.py +50 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/init-board.py +44 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/poll-status.py +70 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/reset-board-dir.py +36 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/inline-python-demo.flow.yaml +26 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/inline-python-handlers.py +39 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker-pycli.flow.yaml +80 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker.flow.yaml +25 -172
- package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker.input.json +40 -34
- package/examples/cli/step-machine-cli/portfolio-tracker/run-inline-python-demo-pycli.py +46 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/run-portfolio-tracker-pycli.py +77 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/run-portfolio-tracker.bat +1 -2
- package/examples/example-board/agent-instructions.md +11 -5
- package/examples/example-board/demo-chat-handler.js +14 -4
- package/examples/example-board/demo-server-config.json +1 -0
- package/examples/example-board/demo-server.js +14 -7
- package/examples/example-board/demo-shell-browser.html +5 -4
- package/examples/example-board/demo-shell-with-server.html +6 -5
- package/examples/example-board/demo-task-executor.js +81 -35
- package/examples/index.html +0 -14
- package/examples/step-machine-cli/portfolio-tracker/handlers/_board-cli.js +0 -1
- package/examples/step-machine-cli/portfolio-tracker/run-portfolio-tracker.bat +1 -2
- package/package.json +39 -3
- package/schema/live-cards.schema.json +418 -132
- package/dist/cli/board-live-cards-cli.cjs +0 -10650
- package/dist/cli/board-live-cards-cli.cjs.map +0 -1
- package/dist/cli/board-live-cards-cli.d.cts +0 -179
- package/dist/cli/board-live-cards-cli.d.ts +0 -179
- package/dist/cli/board-live-cards-cli.js +0 -10598
- package/dist/cli/board-live-cards-cli.js.map +0 -1
- package/dist/journal-9HEgs7dU.d.ts +0 -28
- package/dist/journal-B-JCfQnh.d.cts +0 -28
- package/dist/schedule-Cszq9LYY.d.ts +0 -21
- package/dist/schedule-qWNL0RQh.d.cts +0 -21
- package/examples/browser/boards/portfolio-tracker/cards/holdings-table.json +0 -22
- package/examples/browser/boards/portfolio-tracker/cards/portfolio-form.json +0 -16
- package/examples/browser/boards/portfolio-tracker/cards/portfolio-risk-assessment.json +0 -28
- package/examples/browser/boards/portfolio-tracker/cards/portfolio-value.json +0 -15
- package/examples/browser/boards/portfolio-tracker/cards/price-fetch.json +0 -15
- package/examples/browser/boards/portfolio-tracker/cards/rebalancing-strategy.json +0 -28
- package/examples/browser/boards/portfolio-tracker/fetch-prices.js +0 -43
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker-task-executor.cjs +0 -96
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker.bat +0 -7
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker.js +0 -351
package/browser/live-cards.js
CHANGED
|
@@ -98,6 +98,20 @@ var LiveCard = (function () {
|
|
|
98
98
|
.lc-gandalf-caret:hover { opacity:1; }
|
|
99
99
|
.lc-gandalf-card.lc-collapsed .lc-gandalf-caret { transform:rotate(-90deg); }
|
|
100
100
|
.lc-gandalf-card.lc-collapsed .card-body { display:none !important; }
|
|
101
|
+
.lc-token-row { display:flex; flex-wrap:wrap; gap:0.35rem; padding:0.2rem 0.5rem; background:transparent; align-items:center; justify-content:center; min-height:0; }
|
|
102
|
+
.lc-token-row-requires { border-bottom:none; padding-bottom:0.1rem; }
|
|
103
|
+
.lc-token-row-provides { border-top:none; padding-top:0.1rem; }
|
|
104
|
+
.lc-token-gem { display:inline-block; width:10px; height:10px; border-radius:50%; cursor:default; transition:transform .15s, box-shadow .15s; position:relative; }
|
|
105
|
+
.lc-token-gem:hover { transform:scale(1.5); box-shadow:0 0 4px rgba(0,0,0,0.3); z-index:5; }
|
|
106
|
+
.lc-token-gem-requires { background:var(--bs-secondary,#6c757d); border:1.5px solid var(--bs-secondary,#6c757d); }
|
|
107
|
+
.lc-token-gem-requires.lc-token-available { background:var(--bs-success,#198754); border-color:var(--bs-success,#198754); }
|
|
108
|
+
.lc-token-gem-provides { background:var(--bs-secondary,#6c757d); border:1.5px solid var(--bs-secondary,#6c757d); }
|
|
109
|
+
.lc-token-gem-provides.lc-token-available { background:var(--bs-success,#198754); border-color:var(--bs-success,#198754); }
|
|
110
|
+
.lc-running { animation:lc-running-pulse 2s ease-in-out infinite; position:relative; }
|
|
111
|
+
.lc-running::before { content:''; position:absolute; inset:-2px; border-radius:inherit; background:linear-gradient(90deg,transparent,rgba(13,110,253,.45),rgba(102,16,242,.4),rgba(13,110,253,.45),transparent); background-size:300% 100%; animation:lc-running-shimmer 2s linear infinite; z-index:-1; pointer-events:none; }
|
|
112
|
+
@keyframes lc-running-pulse { 0%,100%{ box-shadow:0 0 4px rgba(13,110,253,.15); } 50%{ box-shadow:0 0 14px 3px rgba(13,110,253,.35); } }
|
|
113
|
+
@keyframes lc-running-shimmer { 0%{ background-position:100% 0; } 100%{ background-position:-100% 0; } }
|
|
114
|
+
.lc-running .card-header { border-bottom-color:rgba(13,110,253,.35); }
|
|
101
115
|
@media (max-width:576px) {
|
|
102
116
|
.lc-metric-value { font-size:1.5rem; }
|
|
103
117
|
.lc-chart-wrap { min-height:150px; }
|
|
@@ -781,7 +795,29 @@ var LiveCard = (function () {
|
|
|
781
795
|
const requires = (node && node.card && Array.isArray(node.card.requires)) ? node.card.requires : [];
|
|
782
796
|
if (!requires.length) return;
|
|
783
797
|
const cleanup = _getCleanup(node.id);
|
|
784
|
-
|
|
798
|
+
|
|
799
|
+
// Resolve required tokens to upstream node IDs via provides declarations.
|
|
800
|
+
// Build a token→nodeId map from all nodes the engine knows about.
|
|
801
|
+
const tokenMap = {};
|
|
802
|
+
const allNodeIds = Object.keys(_subs).concat(Object.keys(_nodeEls));
|
|
803
|
+
allNodeIds.forEach(function(nid) {
|
|
804
|
+
const n = cfg.resolve(nid);
|
|
805
|
+
if (!n || !n.card) return;
|
|
806
|
+
var provides = (Array.isArray(n.card.provides) && n.card.provides.length)
|
|
807
|
+
? n.card.provides.map(function(p) { return typeof p === 'string' ? p : (p.bindTo || p); })
|
|
808
|
+
: [n.id];
|
|
809
|
+
provides.forEach(function(tok) { tokenMap[tok] = n.id; });
|
|
810
|
+
});
|
|
811
|
+
|
|
812
|
+
// Subscribe to each upstream provider node (deduplicated)
|
|
813
|
+
const seen = {};
|
|
814
|
+
const upIds = [];
|
|
815
|
+
requires.forEach(function(token) {
|
|
816
|
+
var srcId = tokenMap[token] || token; // fallback: treat token as nodeId
|
|
817
|
+
if (!seen[srcId]) { seen[srcId] = true; upIds.push(srcId); }
|
|
818
|
+
});
|
|
819
|
+
|
|
820
|
+
cleanup.unsubs = upIds.map(upId => subscribe(upId, () => {
|
|
785
821
|
const info = _nodeEls[node.id];
|
|
786
822
|
if (!info || !info.resultEl) return;
|
|
787
823
|
const updated = cfg.resolve(node.id);
|
|
@@ -2351,6 +2387,17 @@ var LiveCard = (function () {
|
|
|
2351
2387
|
};
|
|
2352
2388
|
const ac = new AbortController();
|
|
2353
2389
|
const signal = ac.signal;
|
|
2390
|
+
const _edges = []; // LeaderLine instances for canvas edges
|
|
2391
|
+
|
|
2392
|
+
// Edge style config (from canvas opts)
|
|
2393
|
+
const edgeOpts = co.edgeStyle || {};
|
|
2394
|
+
const edgeCfg = {
|
|
2395
|
+
color: edgeOpts.color || 'rgba(108, 117, 125, 0.6)',
|
|
2396
|
+
size: edgeOpts.size || 2,
|
|
2397
|
+
dash: edgeOpts.dash !== false,
|
|
2398
|
+
animation: edgeOpts.animation !== false,
|
|
2399
|
+
endPlug: edgeOpts.endPlug || 'arrow1',
|
|
2400
|
+
};
|
|
2354
2401
|
|
|
2355
2402
|
// DOM containers
|
|
2356
2403
|
const root = document.createElement('div');
|
|
@@ -2384,10 +2431,16 @@ var LiveCard = (function () {
|
|
|
2384
2431
|
const s = document.createElement('style');
|
|
2385
2432
|
s.id = 'lc-board-css';
|
|
2386
2433
|
s.textContent = `
|
|
2387
|
-
.lc-canvas-card { position:absolute; min-width:${cvs.minWidth}px;
|
|
2434
|
+
.lc-canvas-card { position:absolute; min-width:${cvs.minWidth}px; cursor:grab; user-select:none; z-index:1; }
|
|
2388
2435
|
.lc-canvas-card.lc-dragging { cursor:grabbing; z-index:10; box-shadow:0 8px 24px rgba(0,0,0,0.18)!important; }
|
|
2389
|
-
.lc-canvas-card .card-body {
|
|
2436
|
+
.lc-canvas-card .card-body { overflow:auto; }
|
|
2437
|
+
.lc-canvas-card.lc-resizing { cursor:nwse-resize; z-index:10; }
|
|
2438
|
+
.lc-resize-handle { position:absolute; bottom:0; right:0; width:14px; height:14px; cursor:nwse-resize; z-index:2; opacity:0.4; transition:opacity .15s; }
|
|
2439
|
+
.lc-resize-handle:hover { opacity:1; }
|
|
2440
|
+
.lc-resize-handle::after { content:''; position:absolute; bottom:3px; right:3px; width:8px; height:8px; border-right:2px solid var(--bs-secondary,#6c757d); border-bottom:2px solid var(--bs-secondary,#6c757d); }
|
|
2441
|
+
.lc-canvas-edges path.lc-edge-path { stroke:var(--bs-secondary,#6c757d); stroke-width:1.5; stroke-dasharray:6 4; animation:lc-edge-flow 0.6s linear infinite; }
|
|
2390
2442
|
.lc-canvas-edges line { stroke:var(--bs-secondary,#6c757d); stroke-width:1.5; }
|
|
2443
|
+
@keyframes lc-edge-flow { to { stroke-dashoffset:-10; } }
|
|
2391
2444
|
.lc-source-node { position:absolute; cursor:grab; user-select:none; z-index:1; }
|
|
2392
2445
|
.lc-source-node.lc-dragging { cursor:grabbing; z-index:10; }
|
|
2393
2446
|
`;
|
|
@@ -2422,6 +2475,51 @@ var LiveCard = (function () {
|
|
|
2422
2475
|
return (node && node.card && Array.isArray(node.card.requires)) ? node.card.requires : [];
|
|
2423
2476
|
}
|
|
2424
2477
|
|
|
2478
|
+
/**
|
|
2479
|
+
* Returns tokens this node provides.
|
|
2480
|
+
* Explicit: card.provides[].bindTo
|
|
2481
|
+
* Implicit default: the node's own id (if no provides declared)
|
|
2482
|
+
*/
|
|
2483
|
+
function _getProvides(node) {
|
|
2484
|
+
if (!node || !node.card) return [node ? node.id : ''];
|
|
2485
|
+
if (Array.isArray(node.card.provides) && node.card.provides.length > 0) {
|
|
2486
|
+
return node.card.provides.map(function(p) { return (typeof p === 'string') ? p : (p.bindTo || p); });
|
|
2487
|
+
}
|
|
2488
|
+
// Default: node provides a token equal to its own id
|
|
2489
|
+
return [node.id];
|
|
2490
|
+
}
|
|
2491
|
+
|
|
2492
|
+
/**
|
|
2493
|
+
* Build token → provider nodeId map from all nodes in the board.
|
|
2494
|
+
* Called before drawing edges so we can resolve requires tokens → source nodes.
|
|
2495
|
+
*/
|
|
2496
|
+
function _buildTokenMap() {
|
|
2497
|
+
var map = {};
|
|
2498
|
+
nodeList.forEach(function(node) {
|
|
2499
|
+
_getProvides(node).forEach(function(token) {
|
|
2500
|
+
map[token] = node.id;
|
|
2501
|
+
});
|
|
2502
|
+
});
|
|
2503
|
+
return map;
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2506
|
+
/**
|
|
2507
|
+
* Resolve required tokens to provider node IDs.
|
|
2508
|
+
* Returns deduplicated array of source node IDs for a given consumer node.
|
|
2509
|
+
*/
|
|
2510
|
+
function _resolveEdgeSources(node, tokenMap) {
|
|
2511
|
+
var sources = [];
|
|
2512
|
+
var seen = {};
|
|
2513
|
+
_getRequires(node).forEach(function(token) {
|
|
2514
|
+
var srcId = tokenMap[token];
|
|
2515
|
+
if (srcId && !seen[srcId]) {
|
|
2516
|
+
seen[srcId] = true;
|
|
2517
|
+
sources.push(srcId);
|
|
2518
|
+
}
|
|
2519
|
+
});
|
|
2520
|
+
return sources;
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2425
2523
|
function _showCardInspector(node) {
|
|
2426
2524
|
const modal = document.createElement('div');
|
|
2427
2525
|
modal.className = 'modal d-block';
|
|
@@ -2562,8 +2660,9 @@ var LiveCard = (function () {
|
|
|
2562
2660
|
const card = node && node.card ? node.card : {};
|
|
2563
2661
|
const isSimulation = card.meta && card.meta.simulation === true;
|
|
2564
2662
|
const isGandalfCard = card.meta && card.meta._gandalfCard === true;
|
|
2663
|
+
const isRunning = node && node.runtime_state && node.runtime_state.task_status === 'running';
|
|
2565
2664
|
const extraClass = isSimulation ? ' lc-simulation-card' : (isGandalfCard ? ' lc-gandalf-card' : '');
|
|
2566
|
-
wrap.className = 'card shadow-sm h-100' + extraClass;
|
|
2665
|
+
wrap.className = 'card shadow-sm h-100' + extraClass + (isRunning ? ' lc-running' : '');
|
|
2567
2666
|
const header = document.createElement('div');
|
|
2568
2667
|
header.className = 'card-header d-flex align-items-center gap-2 py-2';
|
|
2569
2668
|
const title = (card.meta && card.meta.title) || node.id;
|
|
@@ -2639,8 +2738,44 @@ var LiveCard = (function () {
|
|
|
2639
2738
|
|
|
2640
2739
|
const body = document.createElement('div');
|
|
2641
2740
|
body.className = 'card-body p-2';
|
|
2741
|
+
|
|
2742
|
+
// Token gem rows — requires gems above header, provides gems below body
|
|
2743
|
+
const requiresTokens = (card.requires && Array.isArray(card.requires)) ? card.requires : [];
|
|
2744
|
+
const providesTokens = (Array.isArray(card.provides) && card.provides.length)
|
|
2745
|
+
? card.provides.map(function(p) { return typeof p === 'string' ? p : (p.bindTo || p); })
|
|
2746
|
+
: [node.id];
|
|
2747
|
+
|
|
2748
|
+
// Requires gems — top of card (above header)
|
|
2749
|
+
if (requiresTokens.length) {
|
|
2750
|
+
const reqRow = document.createElement('div');
|
|
2751
|
+
reqRow.className = 'lc-token-row lc-token-row-requires';
|
|
2752
|
+
requiresTokens.forEach(function(token) {
|
|
2753
|
+
const gem = document.createElement('span');
|
|
2754
|
+
gem.className = 'lc-token-gem lc-token-gem-requires';
|
|
2755
|
+
gem.dataset.token = token;
|
|
2756
|
+
gem.title = token;
|
|
2757
|
+
reqRow.appendChild(gem);
|
|
2758
|
+
});
|
|
2759
|
+
wrap.appendChild(reqRow);
|
|
2760
|
+
}
|
|
2761
|
+
|
|
2642
2762
|
wrap.appendChild(header);
|
|
2643
2763
|
wrap.appendChild(body);
|
|
2764
|
+
|
|
2765
|
+
// Provides gems — bottom of card (below body)
|
|
2766
|
+
if (providesTokens.length) {
|
|
2767
|
+
const provRow = document.createElement('div');
|
|
2768
|
+
provRow.className = 'lc-token-row lc-token-row-provides';
|
|
2769
|
+
providesTokens.forEach(function(token) {
|
|
2770
|
+
const gem = document.createElement('span');
|
|
2771
|
+
gem.className = 'lc-token-gem lc-token-gem-provides';
|
|
2772
|
+
gem.dataset.token = token;
|
|
2773
|
+
gem.title = token;
|
|
2774
|
+
provRow.appendChild(gem);
|
|
2775
|
+
});
|
|
2776
|
+
wrap.appendChild(provRow);
|
|
2777
|
+
}
|
|
2778
|
+
|
|
2644
2779
|
return { wrap, header, body };
|
|
2645
2780
|
}
|
|
2646
2781
|
|
|
@@ -2662,6 +2797,7 @@ var LiveCard = (function () {
|
|
|
2662
2797
|
// ---- Board mode ----
|
|
2663
2798
|
|
|
2664
2799
|
function _renderBoard() {
|
|
2800
|
+
_destroyEdges();
|
|
2665
2801
|
root.innerHTML = '';
|
|
2666
2802
|
root.appendChild(gridEl);
|
|
2667
2803
|
gridEl.innerHTML = '';
|
|
@@ -2684,6 +2820,7 @@ var LiveCard = (function () {
|
|
|
2684
2820
|
nodeMap[node.id] = { node, colEl: col, bodyEl: body };
|
|
2685
2821
|
engine.render(node, body, { showChat });
|
|
2686
2822
|
});
|
|
2823
|
+
_updateTokenAvailability();
|
|
2687
2824
|
}
|
|
2688
2825
|
|
|
2689
2826
|
// ---- Canvas mode ----
|
|
@@ -2692,26 +2829,132 @@ var LiveCard = (function () {
|
|
|
2692
2829
|
canvasInner.style.transform = `translate(${cvs.panX}px,${cvs.panY}px) scale(${cvs.zoom})`;
|
|
2693
2830
|
}
|
|
2694
2831
|
|
|
2832
|
+
/**
|
|
2833
|
+
* Update token badge availability: a provides badge turns green when the
|
|
2834
|
+
* node has data; a requires badge turns green when the upstream provider
|
|
2835
|
+
* has data for that token.
|
|
2836
|
+
*/
|
|
2837
|
+
function _updateTokenAvailability() {
|
|
2838
|
+
var tokenMap = _buildTokenMap();
|
|
2839
|
+
// Determine which nodes "have data" (non-empty card_data or fetched_sources, or status=fresh/completed)
|
|
2840
|
+
var nodeHasData = {};
|
|
2841
|
+
nodeList.forEach(function(node) {
|
|
2842
|
+
var cd = node.card_data || (node.card && node.card.card_data);
|
|
2843
|
+
var fs = node.fetched_sources;
|
|
2844
|
+
var status = cd && cd.status;
|
|
2845
|
+
var hasOutput = (cd && Object.keys(cd).length > 0) || (fs && Object.keys(fs).length > 0);
|
|
2846
|
+
nodeHasData[node.id] = hasOutput || status === 'fresh' || status === 'completed';
|
|
2847
|
+
});
|
|
2848
|
+
|
|
2849
|
+
// Update all gem elements in root container
|
|
2850
|
+
var allGems = root.querySelectorAll('.lc-token-gem');
|
|
2851
|
+
allGems.forEach(function(gem) {
|
|
2852
|
+
var token = gem.dataset.token;
|
|
2853
|
+
if (!token) return;
|
|
2854
|
+
if (gem.classList.contains('lc-token-gem-provides')) {
|
|
2855
|
+
// The provides gem: green if this node has data
|
|
2856
|
+
var nodeEl = gem.closest('[data-node-id]');
|
|
2857
|
+
var nId = nodeEl && nodeEl.dataset.nodeId;
|
|
2858
|
+
gem.classList.toggle('lc-token-available', !!(nId && nodeHasData[nId]));
|
|
2859
|
+
} else if (gem.classList.contains('lc-token-gem-requires')) {
|
|
2860
|
+
// The requires gem: green if the upstream provider for this token has data
|
|
2861
|
+
var srcId = tokenMap[token];
|
|
2862
|
+
gem.classList.toggle('lc-token-available', !!(srcId && nodeHasData[srcId]));
|
|
2863
|
+
}
|
|
2864
|
+
});
|
|
2865
|
+
}
|
|
2866
|
+
|
|
2867
|
+
function _destroyEdges() {
|
|
2868
|
+
_edges.forEach(function(line) { try { line.remove(); } catch(e) { /* noop */ } });
|
|
2869
|
+
_edges.length = 0;
|
|
2870
|
+
}
|
|
2871
|
+
|
|
2872
|
+
function _repositionEdges() {
|
|
2873
|
+
_edges.forEach(function(line) { try { line.position(); } catch(e) { /* noop */ } });
|
|
2874
|
+
}
|
|
2875
|
+
|
|
2695
2876
|
function _drawEdges() {
|
|
2696
|
-
|
|
2877
|
+
_destroyEdges();
|
|
2878
|
+
svgEl.querySelectorAll('line,path').forEach(function(el) { el.remove(); });
|
|
2697
2879
|
if (!cvs.edges) return;
|
|
2698
2880
|
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2881
|
+
// Build token → provider nodeId map
|
|
2882
|
+
var tokenMap = _buildTokenMap();
|
|
2883
|
+
|
|
2884
|
+
// For each consumer node, for each required token, draw edge from
|
|
2885
|
+
// the provider's "provides" badge → the consumer's "requires" badge.
|
|
2886
|
+
if (typeof LeaderLine !== 'undefined') {
|
|
2887
|
+
nodeList.forEach(function(node) {
|
|
2888
|
+
var tgtInfo = nodeMap[node.id];
|
|
2889
|
+
if (!tgtInfo || !tgtInfo.colEl) return;
|
|
2890
|
+
_getRequires(node).forEach(function(token) {
|
|
2891
|
+
var srcId = tokenMap[token];
|
|
2892
|
+
if (!srcId) return;
|
|
2893
|
+
var srcInfo = nodeMap[srcId];
|
|
2894
|
+
if (!srcInfo || !srcInfo.colEl) return;
|
|
2895
|
+
// Find the specific gem elements for this token
|
|
2896
|
+
var srcGem = srcInfo.colEl.querySelector('.lc-token-gem-provides[data-token="' + token + '"]');
|
|
2897
|
+
var tgtGem = tgtInfo.colEl.querySelector('.lc-token-gem-requires[data-token="' + token + '"]');
|
|
2898
|
+
var startEl = srcGem || srcInfo.colEl;
|
|
2899
|
+
var endEl = tgtGem || tgtInfo.colEl;
|
|
2900
|
+
try {
|
|
2901
|
+
var lineOpts = {
|
|
2902
|
+
color: edgeCfg.color,
|
|
2903
|
+
size: edgeCfg.size,
|
|
2904
|
+
endPlug: edgeCfg.endPlug,
|
|
2905
|
+
startSocket: srcGem ? 'bottom' : 'right',
|
|
2906
|
+
endSocket: tgtGem ? 'top' : 'left',
|
|
2907
|
+
};
|
|
2908
|
+
if (edgeCfg.dash) {
|
|
2909
|
+
lineOpts.dash = edgeCfg.animation ? { animation: true } : true;
|
|
2910
|
+
}
|
|
2911
|
+
_edges.push(new LeaderLine(startEl, endEl, lineOpts));
|
|
2912
|
+
} catch(e) { /* skip edge on error */ }
|
|
2913
|
+
});
|
|
2914
|
+
});
|
|
2915
|
+
return;
|
|
2916
|
+
}
|
|
2917
|
+
|
|
2918
|
+
// SVG fallback — connect badge-to-badge with curved paths
|
|
2919
|
+
nodeList.forEach(function(node) {
|
|
2920
|
+
var tgtInfo = nodeMap[node.id];
|
|
2921
|
+
if (!tgtInfo || !tgtInfo.colEl) return;
|
|
2922
|
+
_getRequires(node).forEach(function(token) {
|
|
2923
|
+
var srcId = tokenMap[token];
|
|
2924
|
+
if (!srcId) return;
|
|
2925
|
+
var srcInfo = nodeMap[srcId];
|
|
2926
|
+
if (!srcInfo || !srcInfo.colEl) return;
|
|
2927
|
+
// Locate gems; fall back to card element if gem not found
|
|
2928
|
+
var srcGem = srcInfo.colEl.querySelector('.lc-token-gem-provides[data-token="' + token + '"]');
|
|
2929
|
+
var tgtGem = tgtInfo.colEl.querySelector('.lc-token-gem-requires[data-token="' + token + '"]');
|
|
2930
|
+
var sx, sy, tx, ty;
|
|
2931
|
+
var innerRect = canvasInner.getBoundingClientRect();
|
|
2932
|
+
if (srcGem) {
|
|
2933
|
+
var srcRect = srcGem.getBoundingClientRect();
|
|
2934
|
+
sx = (srcRect.left + srcRect.width / 2 - innerRect.left) / cvs.zoom;
|
|
2935
|
+
sy = (srcRect.bottom - innerRect.top) / cvs.zoom;
|
|
2936
|
+
} else {
|
|
2937
|
+
var sEl = srcInfo.colEl;
|
|
2938
|
+
sx = sEl.offsetLeft + sEl.offsetWidth / 2;
|
|
2939
|
+
sy = sEl.offsetTop + sEl.offsetHeight;
|
|
2940
|
+
}
|
|
2941
|
+
if (tgtGem) {
|
|
2942
|
+
var tgtRect = tgtGem.getBoundingClientRect();
|
|
2943
|
+
tx = (tgtRect.left + tgtRect.width / 2 - innerRect.left) / cvs.zoom;
|
|
2944
|
+
ty = (tgtRect.top - innerRect.top) / cvs.zoom;
|
|
2945
|
+
} else {
|
|
2946
|
+
var tEl = tgtInfo.colEl;
|
|
2947
|
+
tx = tEl.offsetLeft + tEl.offsetWidth / 2;
|
|
2948
|
+
ty = tEl.offsetTop;
|
|
2949
|
+
}
|
|
2950
|
+
var cpOffset = Math.min(Math.abs(ty - sy) * 0.5, 80);
|
|
2951
|
+
var d = 'M ' + sx + ' ' + sy + ' C ' + sx + ' ' + (sy + cpOffset) + ', ' + tx + ' ' + (ty - cpOffset) + ', ' + tx + ' ' + ty;
|
|
2952
|
+
var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
2953
|
+
path.setAttribute('d', d);
|
|
2954
|
+
path.setAttribute('fill', 'none');
|
|
2955
|
+
path.setAttribute('marker-end', 'url(#lc-arrow)');
|
|
2956
|
+
path.classList.add('lc-edge-path');
|
|
2957
|
+
svgEl.appendChild(path);
|
|
2715
2958
|
});
|
|
2716
2959
|
});
|
|
2717
2960
|
}
|
|
@@ -2736,7 +2979,8 @@ var LiveCard = (function () {
|
|
|
2736
2979
|
const dy = (e.clientY - startY) / cvs.zoom;
|
|
2737
2980
|
el.style.left = (origX + dx) + 'px';
|
|
2738
2981
|
el.style.top = (origY + dy) + 'px';
|
|
2739
|
-
|
|
2982
|
+
if (_edges.length) _repositionEdges();
|
|
2983
|
+
else _drawEdges();
|
|
2740
2984
|
}, { signal });
|
|
2741
2985
|
|
|
2742
2986
|
el.addEventListener('pointerup', () => {
|
|
@@ -2755,15 +2999,75 @@ var LiveCard = (function () {
|
|
|
2755
2999
|
node.card.view.layout.canvas.y = y;
|
|
2756
3000
|
}
|
|
2757
3001
|
engine.notify(node.id);
|
|
2758
|
-
|
|
3002
|
+
if (_edges.length) _repositionEdges();
|
|
3003
|
+
else _drawEdges();
|
|
3004
|
+
}, { signal });
|
|
3005
|
+
}
|
|
3006
|
+
|
|
3007
|
+
function _makeResizable(el, node) {
|
|
3008
|
+
const handle = document.createElement('div');
|
|
3009
|
+
handle.className = 'lc-resize-handle';
|
|
3010
|
+
el.appendChild(handle);
|
|
3011
|
+
el.style.overflow = 'visible';
|
|
3012
|
+
|
|
3013
|
+
let resizing = false, startX, startY, origW, origH;
|
|
3014
|
+
|
|
3015
|
+
handle.addEventListener('pointerdown', function(e) {
|
|
3016
|
+
if (e.button !== 0) return;
|
|
3017
|
+
e.stopPropagation();
|
|
3018
|
+
e.preventDefault();
|
|
3019
|
+
resizing = true;
|
|
3020
|
+
el.classList.add('lc-resizing');
|
|
3021
|
+
handle.setPointerCapture(e.pointerId);
|
|
3022
|
+
startX = e.clientX;
|
|
3023
|
+
startY = e.clientY;
|
|
3024
|
+
origW = el.offsetWidth;
|
|
3025
|
+
origH = el.offsetHeight;
|
|
3026
|
+
}, { signal });
|
|
3027
|
+
|
|
3028
|
+
handle.addEventListener('pointermove', function(e) {
|
|
3029
|
+
if (!resizing) return;
|
|
3030
|
+
const dw = (e.clientX - startX) / cvs.zoom;
|
|
3031
|
+
const dh = (e.clientY - startY) / cvs.zoom;
|
|
3032
|
+
const newW = Math.max(cvs.minWidth, origW + dw);
|
|
3033
|
+
const newH = Math.max(80, origH + dh);
|
|
3034
|
+
el.style.width = newW + 'px';
|
|
3035
|
+
el.style.height = newH + 'px';
|
|
3036
|
+
if (_edges.length) _repositionEdges();
|
|
3037
|
+
else _drawEdges();
|
|
3038
|
+
}, { signal });
|
|
3039
|
+
|
|
3040
|
+
handle.addEventListener('pointerup', function() {
|
|
3041
|
+
if (!resizing) return;
|
|
3042
|
+
resizing = false;
|
|
3043
|
+
el.classList.remove('lc-resizing');
|
|
3044
|
+
const w = el.offsetWidth;
|
|
3045
|
+
const h = el.offsetHeight;
|
|
3046
|
+
// Snap to grid
|
|
3047
|
+
const sw = cvs.snap > 1 ? Math.round(w / cvs.snap) * cvs.snap : w;
|
|
3048
|
+
const sh = cvs.snap > 1 ? Math.round(h / cvs.snap) * cvs.snap : h;
|
|
3049
|
+
el.style.width = sw + 'px';
|
|
3050
|
+
el.style.height = sh + 'px';
|
|
3051
|
+
// Persist dimensions
|
|
3052
|
+
_positions[node.id] = Object.assign(_positions[node.id] || {}, { w: sw, h: sh });
|
|
3053
|
+
if (node.card && node.card.view) {
|
|
3054
|
+
if (!node.card.view.layout) node.card.view.layout = {};
|
|
3055
|
+
if (!node.card.view.layout.canvas) node.card.view.layout.canvas = {};
|
|
3056
|
+
node.card.view.layout.canvas.w = sw;
|
|
3057
|
+
node.card.view.layout.canvas.h = sh;
|
|
3058
|
+
}
|
|
3059
|
+
engine.notify(node.id);
|
|
3060
|
+
if (_edges.length) _repositionEdges();
|
|
3061
|
+
else _drawEdges();
|
|
2759
3062
|
}, { signal });
|
|
2760
3063
|
}
|
|
2761
3064
|
|
|
2762
3065
|
function _renderCanvas() {
|
|
3066
|
+
_destroyEdges();
|
|
2763
3067
|
root.innerHTML = '';
|
|
2764
3068
|
root.appendChild(canvasEl);
|
|
2765
3069
|
canvasInner.querySelectorAll('.lc-canvas-card,.lc-source-node').forEach(el => el.remove());
|
|
2766
|
-
svgEl.querySelectorAll('line').forEach(
|
|
3070
|
+
svgEl.querySelectorAll('line,path').forEach(function(el) { el.remove(); });
|
|
2767
3071
|
_initPositions();
|
|
2768
3072
|
_applyTransform();
|
|
2769
3073
|
|
|
@@ -2788,6 +3092,7 @@ var LiveCard = (function () {
|
|
|
2788
3092
|
el.style.left = pos.x + 'px';
|
|
2789
3093
|
el.style.top = pos.y + 'px';
|
|
2790
3094
|
if (pos.w) el.style.width = pos.w + 'px';
|
|
3095
|
+
if (pos.h) el.style.height = pos.h + 'px';
|
|
2791
3096
|
|
|
2792
3097
|
const { wrap, body } = _buildCardWrapper(node);
|
|
2793
3098
|
while (wrap.firstChild) el.appendChild(wrap.firstChild);
|
|
@@ -2798,10 +3103,21 @@ var LiveCard = (function () {
|
|
|
2798
3103
|
nodeMap[node.id] = { node, colEl: el, bodyEl: body };
|
|
2799
3104
|
engine.render(node, body, { showChat: false });
|
|
2800
3105
|
_makeDraggable(el, node);
|
|
3106
|
+
_makeResizable(el, node);
|
|
2801
3107
|
}
|
|
2802
3108
|
});
|
|
2803
3109
|
|
|
2804
|
-
|
|
3110
|
+
_updateTokenAvailability();
|
|
3111
|
+
|
|
3112
|
+
// Draw edges — use rAF for LeaderLine so elements are laid out first
|
|
3113
|
+
if (typeof LeaderLine !== 'undefined') {
|
|
3114
|
+
requestAnimationFrame(function() { _drawEdges(); });
|
|
3115
|
+
} else {
|
|
3116
|
+
_drawEdges();
|
|
3117
|
+
}
|
|
3118
|
+
|
|
3119
|
+
// Reposition LeaderLine edges on scroll
|
|
3120
|
+
canvasEl.addEventListener('scroll', function() { _repositionEdges(); }, { signal, passive: true });
|
|
2805
3121
|
|
|
2806
3122
|
// Pan: middle-click or Ctrl+drag on background
|
|
2807
3123
|
let panning = false, panStartX, panStartY, panOrigX, panOrigY;
|
|
@@ -2819,6 +3135,7 @@ var LiveCard = (function () {
|
|
|
2819
3135
|
cvs.panX = panOrigX + (e.clientX - panStartX);
|
|
2820
3136
|
cvs.panY = panOrigY + (e.clientY - panStartY);
|
|
2821
3137
|
_applyTransform();
|
|
3138
|
+
_repositionEdges();
|
|
2822
3139
|
}, { signal });
|
|
2823
3140
|
canvasEl.addEventListener('pointerup', () => { panning = false; }, { signal });
|
|
2824
3141
|
|
|
@@ -2829,6 +3146,7 @@ var LiveCard = (function () {
|
|
|
2829
3146
|
const delta = e.deltaY > 0 ? 0.9 : 1.1;
|
|
2830
3147
|
cvs.zoom = Math.min(cvs.zoomMax, Math.max(cvs.zoomMin, cvs.zoom * delta));
|
|
2831
3148
|
_applyTransform();
|
|
3149
|
+
_repositionEdges();
|
|
2832
3150
|
}, { signal, passive: false });
|
|
2833
3151
|
}
|
|
2834
3152
|
|
|
@@ -2840,11 +3158,12 @@ var LiveCard = (function () {
|
|
|
2840
3158
|
// ---- Auto-layout (topological L → R) ----
|
|
2841
3159
|
|
|
2842
3160
|
function autoLayout() {
|
|
3161
|
+
const tokenMap = _buildTokenMap();
|
|
2843
3162
|
const incoming = {};
|
|
2844
3163
|
const levels = {};
|
|
2845
3164
|
nodeList.forEach(n => { incoming[n.id] = []; levels[n.id] = 0; });
|
|
2846
3165
|
nodeList.forEach(n => {
|
|
2847
|
-
|
|
3166
|
+
_resolveEdgeSources(n, tokenMap).forEach(srcId => {
|
|
2848
3167
|
if (incoming[n.id]) incoming[n.id].push(srcId);
|
|
2849
3168
|
});
|
|
2850
3169
|
});
|
|
@@ -2910,6 +3229,7 @@ var LiveCard = (function () {
|
|
|
2910
3229
|
function refresh() { _render(); }
|
|
2911
3230
|
|
|
2912
3231
|
function clear() {
|
|
3232
|
+
_destroyEdges();
|
|
2913
3233
|
engine.destroyAll();
|
|
2914
3234
|
nodeList.length = 0;
|
|
2915
3235
|
Object.keys(nodeMap).forEach(k => delete nodeMap[k]);
|
|
@@ -2929,6 +3249,7 @@ var LiveCard = (function () {
|
|
|
2929
3249
|
}
|
|
2930
3250
|
|
|
2931
3251
|
function destroy() {
|
|
3252
|
+
_destroyEdges();
|
|
2932
3253
|
ac.abort();
|
|
2933
3254
|
engine.destroyAll();
|
|
2934
3255
|
nodeList.length = 0;
|